diff --git a/Android.mk b/Android.mk
index 362a329..9d7906e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -473,7 +473,8 @@
 		-nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
-LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=assets-sdk
+
+LOCAL_UNINSTALLABLE_MODULE := true
 
 include $(BUILD_DROIDDOC)
 
@@ -482,6 +483,34 @@
 $(INTERNAL_PLATFORM_API_FILE): $(full_target)
 $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_API_FILE))
 
+# ====  check javadoc comments but don't generate docs ========
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
+LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES)
+LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
+LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
+LOCAL_DROIDDOC_HTML_DIR:=$(framework_docs_LOCAL_DROIDDOC_HTML_DIR)
+LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_ADDITIONAL_JAVA_DIR)
+
+LOCAL_MODULE := doc-comment-check
+
+LOCAL_DROIDDOC_OPTIONS:=\
+		$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
+		-parsecomments
+
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
+
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_DROIDDOC)
+
+# $(gen), i.e. framework.aidl, is also needed while building against the current stub.
+$(full_target): $(framework_built) $(gen)
+
+droidcore: doc-comment-check-docs
+
 # ====  static html in the sdk ==================================
 include $(CLEAR_VARS)
 
@@ -503,14 +532,13 @@
 		-proofread $(OUT_DOCS)/$(LOCAL_MODULE)-proofread.txt \
 		-todo $(OUT_DOCS)/$(LOCAL_MODULE)-docs-todo.html \
 		-sdkvalues $(OUT_DOCS) \
-		-hdf android.whichdoc offline 
+		-hdf android.whichdoc offline
 
 ifeq ($(framework_docs_SDK_PREVIEW),true)
   LOCAL_DROIDDOC_OPTIONS += -hdf sdk.current preview 
 endif
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
-LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=assets-sdk
 
 include $(BUILD_DROIDDOC)
 
@@ -545,7 +573,6 @@
 		-hdf template.showLanguageMenu true
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
-LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=assets-sdk
 
 include $(BUILD_DROIDDOC)
 
@@ -566,11 +593,10 @@
 LOCAL_MODULE := hidden
 LOCAL_DROIDDOC_OPTIONS:=\
 		$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
-        -title "Android SDK - Including hidden APIs."
-#        -hidden
+		-title "Android SDK - Including hidden APIs."
+#		-hidden
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
-LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=assets-sdk
 
 include $(BUILD_DROIDDOC)
 
diff --git a/CleanSpec.mk b/CleanSpec.mk
index e961a5a..50bee9c 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -78,6 +78,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libhwui.so)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/storage/*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/IClipboard.P)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java/com/android/internal/telephony/ITelephonyRegistry.P)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/api/9.xml b/api/9.xml
index 08f86e1..6e059c5 100644
--- a/api/9.xml
+++ b/api/9.xml
@@ -793,17 +793,6 @@
  visibility="public"
 >
 </field>
-<field name="READ_OWNER_DATA"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.READ_OWNER_DATA&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="READ_PHONE_STATE"
  type="java.lang.String"
  transient="false"
@@ -1233,17 +1222,6 @@
  visibility="public"
 >
 </field>
-<field name="WRITE_OWNER_DATA"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.WRITE_OWNER_DATA&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="WRITE_SECURE_SETTINGS"
  type="java.lang.String"
  transient="false"
diff --git a/api/current.xml b/api/current.xml
index 52a0b51..8476d96 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -712,7 +712,7 @@
  value="&quot;android.permission.PERSISTENT_ACTIVITY&quot;"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -793,17 +793,6 @@
  visibility="public"
 >
 </field>
-<field name="READ_OWNER_DATA"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.READ_OWNER_DATA&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="READ_PHONE_STATE"
  type="java.lang.String"
  transient="false"
@@ -1233,17 +1222,6 @@
  visibility="public"
 >
 </field>
-<field name="WRITE_OWNER_DATA"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.WRITE_OWNER_DATA&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="WRITE_SECURE_SETTINGS"
  type="java.lang.String"
  transient="false"
@@ -8919,6 +8897,17 @@
  visibility="public"
 >
 </field>
+<field name="spinnerMode"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843569"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="spinnerStyle"
  type="int"
  transient="false"
@@ -15782,6 +15771,23 @@
 >
 </field>
 </class>
+<class name="R.menu"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="R.menu"
+ type="android.R.menu"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+</class>
 <class name="R.plurals"
  extends="java.lang.Object"
  abstract="false"
@@ -19845,8 +19851,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<exception name="CloneNotSupportedException" type="java.lang.CloneNotSupportedException">
-</exception>
 </method>
 <method name="end"
  return="void"
@@ -19859,6 +19863,17 @@
  visibility="public"
 >
 </method>
+<method name="getDuration"
+ return="long"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getListeners"
  return="java.util.ArrayList&lt;android.animation.Animatable.AnimatableListener&gt;"
  abstract="false"
@@ -19870,6 +19885,17 @@
  visibility="public"
 >
 </method>
+<method name="getStartDelay"
+ return="long"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isRunning"
  return="boolean"
  abstract="true"
@@ -19905,6 +19931,80 @@
 <parameter name="listener" type="android.animation.Animatable.AnimatableListener">
 </parameter>
 </method>
+<method name="setDuration"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="duration" type="long">
+</parameter>
+</method>
+<method name="setInterpolator"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="android.view.animation.Interpolator">
+</parameter>
+</method>
+<method name="setStartDelay"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startDelay" type="long">
+</parameter>
+</method>
+<method name="setTarget"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="target" type="java.lang.Object">
+</parameter>
+</method>
+<method name="setupEndValues"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setupStartValues"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="start"
  return="void"
  abstract="false"
@@ -20224,6 +20324,17 @@
  visibility="public"
 >
 </method>
+<method name="getValues"
+ return="android.animation.PropertyValuesHolder[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isRunning"
  return="boolean"
  abstract="false"
@@ -20560,6 +20671,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<implements name="java.lang.Cloneable">
+</implements>
 <constructor name="Keyframe"
  type="android.animation.Keyframe"
  static="false"
@@ -20581,6 +20694,42 @@
 >
 <parameter name="fraction" type="float">
 </parameter>
+<parameter name="value" type="java.lang.Float">
+</parameter>
+</constructor>
+<constructor name="Keyframe"
+ type="android.animation.Keyframe"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fraction" type="float">
+</parameter>
+<parameter name="value" type="java.lang.Integer">
+</parameter>
+</constructor>
+<constructor name="Keyframe"
+ type="android.animation.Keyframe"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fraction" type="float">
+</parameter>
+<parameter name="value" type="java.lang.Double">
+</parameter>
+</constructor>
+<constructor name="Keyframe"
+ type="android.animation.Keyframe"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fraction" type="float">
+</parameter>
 <parameter name="value" type="int">
 </parameter>
 </constructor>
@@ -20608,6 +20757,17 @@
 <parameter name="value" type="double">
 </parameter>
 </constructor>
+<method name="clone"
+ return="android.animation.Keyframe"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getFraction"
  return="float"
  abstract="false"
@@ -20692,6 +20852,333 @@
 </parameter>
 </method>
 </class>
+<class name="LayoutTransition"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="LayoutTransition"
+ type="android.animation.LayoutTransition"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="addTransitionListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.animation.LayoutTransition.TransitionListener">
+</parameter>
+</method>
+<method name="childAdd"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="parent" type="android.view.ViewGroup">
+</parameter>
+<parameter name="child" type="android.view.View">
+</parameter>
+</method>
+<method name="childRemove"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="parent" type="android.view.ViewGroup">
+</parameter>
+<parameter name="child" type="android.view.View">
+</parameter>
+</method>
+<method name="getAnimatable"
+ return="android.animation.Animatable"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transitionType" type="int">
+</parameter>
+</method>
+<method name="getDuration"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transitionType" type="int">
+</parameter>
+</method>
+<method name="getInterpolator"
+ return="android.view.animation.Interpolator"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transitionType" type="int">
+</parameter>
+</method>
+<method name="getStagger"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transitionType" type="int">
+</parameter>
+</method>
+<method name="getStartDelay"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transitionType" type="int">
+</parameter>
+</method>
+<method name="getTransitionListeners"
+ return="java.util.List&lt;android.animation.LayoutTransition.TransitionListener&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="removeTransitionListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.animation.LayoutTransition.TransitionListener">
+</parameter>
+</method>
+<method name="setAnimatable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transitionType" type="int">
+</parameter>
+<parameter name="animatable" type="android.animation.Animatable">
+</parameter>
+</method>
+<method name="setDuration"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="duration" type="long">
+</parameter>
+</method>
+<method name="setDuration"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transitionType" type="int">
+</parameter>
+<parameter name="duration" type="long">
+</parameter>
+</method>
+<method name="setInterpolator"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transitionType" type="int">
+</parameter>
+<parameter name="interpolator" type="android.view.animation.Interpolator">
+</parameter>
+</method>
+<method name="setStagger"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transitionType" type="int">
+</parameter>
+<parameter name="duration" type="long">
+</parameter>
+</method>
+<method name="setStartDelay"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transitionType" type="int">
+</parameter>
+<parameter name="delay" type="long">
+</parameter>
+</method>
+<field name="APPEARING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CHANGE_APPEARING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CHANGE_DISAPPEARING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DISAPPEARING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<interface name="LayoutTransition.TransitionListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="endTransition"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transition" type="android.animation.LayoutTransition">
+</parameter>
+<parameter name="container" type="android.view.ViewGroup">
+</parameter>
+<parameter name="view" type="android.view.View">
+</parameter>
+<parameter name="transitionType" type="int">
+</parameter>
+</method>
+<method name="startTransition"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transition" type="android.animation.LayoutTransition">
+</parameter>
+<parameter name="container" type="android.view.ViewGroup">
+</parameter>
+<parameter name="view" type="android.view.View">
+</parameter>
+<parameter name="transitionType" type="int">
+</parameter>
+</method>
+</interface>
 <class name="PropertyAnimator"
  extends="android.animation.Animator"
  abstract="false"
@@ -20773,19 +21260,6 @@
 <parameter name="propertyName" type="java.lang.String">
 </parameter>
 </method>
-<method name="setTarget"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="target" type="java.lang.Object">
-</parameter>
-</method>
 </class>
 <class name="PropertyValuesHolder"
  extends="java.lang.Object"
@@ -20795,6 +21269,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<implements name="java.lang.Cloneable">
+</implements>
 <constructor name="PropertyValuesHolder"
  type="android.animation.PropertyValuesHolder"
  static="false"
@@ -20817,6 +21293,17 @@
 <parameter name="values" type="T...">
 </parameter>
 </constructor>
+<method name="clone"
+ return="android.animation.PropertyValuesHolder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getGetter"
  return="java.lang.reflect.Method"
  abstract="false"
@@ -20979,6 +21466,28 @@
  visibility="public"
 >
 </method>
+<method name="getDuration"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStartDelay"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isRunning"
  return="boolean"
  abstract="false"
@@ -21029,7 +21538,7 @@
 <parameter name="sequenceItems" type="android.animation.Animatable...">
 </parameter>
 </method>
-<method name="setTarget"
+<method name="setDuration"
  return="void"
  abstract="false"
  native="false"
@@ -21039,7 +21548,33 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="target" type="java.lang.Object">
+<parameter name="duration" type="long">
+</parameter>
+</method>
+<method name="setInterpolator"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="interpolator" type="android.view.animation.Interpolator">
+</parameter>
+</method>
+<method name="setStartDelay"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startDelay" type="long">
 </parameter>
 </method>
 </class>
@@ -23398,7 +23933,7 @@
  synchronized="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="isPersistent" type="boolean">
@@ -24649,17 +25184,6 @@
  visibility="public"
 >
 </field>
-<field name="FLAG_HEAVY_WEIGHT"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="IMPORTANCE_BACKGROUND"
  type="int"
  transient="false"
@@ -24770,16 +25294,6 @@
  visibility="public"
 >
 </field>
-<field name="flags"
- type="int"
- transient="false"
- volatile="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="importance"
  type="int"
  transient="false"
@@ -51299,6 +51813,17 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<method name="apply"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="clear"
  return="android.content.SharedPreferences.Editor"
  abstract="true"
@@ -51424,17 +51949,6 @@
 <parameter name="key" type="java.lang.String">
 </parameter>
 </method>
-<method name="startCommit"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 </interface>
 <interface name="SharedPreferences.OnSharedPreferenceChangeListener"
  abstract="true"
@@ -54625,7 +55139,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="className" type="android.content.ComponentName">
+<parameter name="component" type="android.content.ComponentName">
 </parameter>
 <parameter name="flags" type="int">
 </parameter>
@@ -55021,6 +55535,23 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
+<method name="getProviderInfo"
+ return="android.content.pm.ProviderInfo"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="component" type="android.content.ComponentName">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+<exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
+</exception>
+</method>
 <method name="getReceiverInfo"
  return="android.content.pm.ActivityInfo"
  abstract="true"
@@ -55031,7 +55562,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="className" type="android.content.ComponentName">
+<parameter name="component" type="android.content.ComponentName">
 </parameter>
 <parameter name="flags" type="int">
 </parameter>
@@ -55093,7 +55624,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="className" type="android.content.ComponentName">
+<parameter name="component" type="android.content.ComponentName">
 </parameter>
 <parameter name="flags" type="int">
 </parameter>
@@ -55552,6 +56083,17 @@
  visibility="public"
 >
 </field>
+<field name="FEATURE_NFC"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.hardware.nfc&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="FEATURE_SENSOR_ACCELEROMETER"
  type="java.lang.String"
  transient="false"
@@ -55563,6 +56105,17 @@
  visibility="public"
 >
 </field>
+<field name="FEATURE_SENSOR_BAROMETER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.hardware.sensor.barometer&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="FEATURE_SENSOR_COMPASS"
  type="java.lang.String"
  transient="false"
@@ -55574,6 +56127,17 @@
  visibility="public"
 >
 </field>
+<field name="FEATURE_SENSOR_GYROSCOPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.hardware.sensor.gyroscope&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="FEATURE_SENSOR_LIGHT"
  type="java.lang.String"
  transient="false"
@@ -55596,6 +56160,28 @@
  visibility="public"
 >
 </field>
+<field name="FEATURE_SIP"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.software.sip&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FEATURE_SIP_VOIP"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.software.sip.voip&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="FEATURE_TELEPHONY"
  type="java.lang.String"
  transient="false"
@@ -55662,6 +56248,17 @@
  visibility="public"
 >
 </field>
+<field name="FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.hardware.touchscreen.multitouch.jazzhand&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="FEATURE_WIFI"
  type="java.lang.String"
  transient="false"
@@ -83330,17 +83927,6 @@
  visibility="public"
 >
 </method>
-<method name="getMeteringMode"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="getMinExposureCompensation"
  return="int"
  abstract="false"
@@ -83486,17 +84072,6 @@
  visibility="public"
 >
 </method>
-<method name="getSupportedMeteringModes"
- return="java.util.List&lt;java.lang.String&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="getSupportedPictureFormats"
  return="java.util.List&lt;java.lang.Integer&gt;"
  abstract="false"
@@ -83876,19 +84451,6 @@
 <parameter name="height" type="int">
 </parameter>
 </method>
-<method name="setMeteringMode"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="value" type="java.lang.String">
-</parameter>
-</method>
 <method name="setPictureFormat"
  return="void"
  abstract="false"
@@ -84335,39 +84897,6 @@
  visibility="public"
 >
 </field>
-<field name="METERING_MODE_CENTER_WEIGHTED"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;center-weighted&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="METERING_MODE_FRAME_AVERAGE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;frame-average&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="METERING_MODE_SPOT"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;spot&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="PREVIEW_FPS_MAX_INDEX"
  type="int"
  transient="false"
@@ -139587,6 +140116,21 @@
 <parameter name="preferenceScreen" type="android.preference.PreferenceScreen">
 </parameter>
 </method>
+<method name="startPreferenceFragment"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fragment" type="android.app.Fragment">
+</parameter>
+<parameter name="push" type="boolean">
+</parameter>
+</method>
 <method name="startWithFragment"
  return="void"
  abstract="false"
@@ -144267,6 +144811,17 @@
  visibility="public"
 >
 </field>
+<field name="LIMIT_PARAM_KEY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;limit&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="ContactsContract.AggregationExceptions"
  extends="java.lang.Object"
@@ -146751,6 +147306,10 @@
 >
 <implements name="android.provider.BaseColumns">
 </implements>
+<implements name="android.provider.ContactsContract.ContactOptionsColumns">
+</implements>
+<implements name="android.provider.ContactsContract.ContactStatusColumns">
+</implements>
 <implements name="android.provider.ContactsContract.ContactsColumns">
 </implements>
 <field name="CONTENT_DIRECTORY"
@@ -146861,7 +147420,7 @@
 >
 <implements name="android.provider.BaseColumns">
 </implements>
-<implements name="android.provider.ContactsContract.DataColumns">
+<implements name="android.provider.ContactsContract.DataColumnsWithJoins">
 </implements>
 <field name="CONTENT_DIRECTORY"
  type="java.lang.String"
@@ -148646,7 +149205,7 @@
  value="1"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -167180,6 +167739,23 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
+<method name="getProviderInfo"
+ return="android.content.pm.ProviderInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="className" type="android.content.ComponentName">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+<exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
+</exception>
+</method>
 <method name="getReceiverInfo"
  return="android.content.pm.ActivityInfo"
  abstract="false"
@@ -186797,14 +187373,19 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="InputDevice"
- type="android.view.InputDevice"
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-</constructor>
+</method>
 <method name="getDevice"
  return="android.view.InputDevice"
  abstract="false"
@@ -186818,6 +187399,28 @@
 <parameter name="id" type="int">
 </parameter>
 </method>
+<method name="getDeviceIds"
+ return="int[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getKeyCharacterMap"
  return="android.view.KeyCharacterMap"
  abstract="false"
@@ -186850,7 +187453,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="range" type="int">
+<parameter name="rangeType" type="int">
 </parameter>
 </method>
 <method name="getName"
@@ -186875,8 +187478,8 @@
  visibility="public"
 >
 </method>
-<method name="hasKey"
- return="boolean"
+<method name="writeToParcel"
+ return="void"
  abstract="false"
  native="false"
  synchronized="false"
@@ -186885,9 +187488,21 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="keyCode" type="int">
+<parameter name="out" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
 </parameter>
 </method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="KEYBOARD_TYPE_ALPHABETIC"
  type="int"
  transient="false"
@@ -187216,14 +187831,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="InputDevice.MotionRange"
- type="android.view.InputDevice.MotionRange"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
 <method name="getFlat"
  return="float"
  abstract="false"
@@ -192740,6 +193347,28 @@
  visibility="public"
 >
 </method>
+<method name="getCurrentSpanX"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getCurrentSpanY"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getEventTime"
  return="long"
  abstract="false"
@@ -192784,6 +193413,28 @@
  visibility="public"
 >
 </method>
+<method name="getPreviousSpanX"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getPreviousSpanY"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getScaleFactor"
  return="float"
  abstract="false"
@@ -194363,6 +195014,19 @@
 <parameter name="focusableMode" type="int">
 </parameter>
 </method>
+<method name="addOnLayoutChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.view.View.OnLayoutChangeListener">
+</parameter>
+</method>
 <method name="addTouchables"
  return="void"
  abstract="false"
@@ -195452,6 +196116,17 @@
  visibility="public"
 >
 </method>
+<method name="getOnLayoutChangeListeners"
+ return="java.util.List&lt;android.view.View.OnLayoutChangeListener&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getPaddingBottom"
  return="int"
  abstract="false"
@@ -197056,6 +197731,19 @@
 <parameter name="action" type="java.lang.Runnable">
 </parameter>
 </method>
+<method name="removeOnLayoutChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.view.View.OnLayoutChangeListener">
+</parameter>
+</method>
 <method name="requestFocus"
  return="boolean"
  abstract="false"
@@ -197324,6 +198012,19 @@
 <parameter name="resid" type="int">
 </parameter>
 </method>
+<method name="setBottom"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="bottom" type="int">
+</parameter>
+</method>
 <method name="setClickable"
  return="void"
  abstract="false"
@@ -197532,6 +198233,19 @@
 <parameter name="params" type="android.view.ViewGroup.LayoutParams">
 </parameter>
 </method>
+<method name="setLeft"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="left" type="int">
+</parameter>
+</method>
 <method name="setLongClickable"
  return="void"
  abstract="false"
@@ -197774,6 +198488,19 @@
 <parameter name="pressed" type="boolean">
 </parameter>
 </method>
+<method name="setRight"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="right" type="int">
+</parameter>
+</method>
 <method name="setRotation"
  return="void"
  abstract="false"
@@ -197958,6 +198685,19 @@
 <parameter name="tag" type="java.lang.Object">
 </parameter>
 </method>
+<method name="setTop"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="top" type="int">
+</parameter>
+</method>
 <method name="setTouchDelegate"
  return="void"
  abstract="false"
@@ -199020,6 +199760,43 @@
 </parameter>
 </method>
 </interface>
+<interface name="View.OnLayoutChangeListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onLayoutChange"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="v" type="android.view.View">
+</parameter>
+<parameter name="left" type="int">
+</parameter>
+<parameter name="top" type="int">
+</parameter>
+<parameter name="right" type="int">
+</parameter>
+<parameter name="bottom" type="int">
+</parameter>
+<parameter name="oldLeft" type="int">
+</parameter>
+<parameter name="oldTop" type="int">
+</parameter>
+<parameter name="oldRight" type="int">
+</parameter>
+<parameter name="oldBottom" type="int">
+</parameter>
+</method>
+</interface>
 <interface name="View.OnLongClickListener"
  abstract="true"
  static="true"
@@ -200848,6 +201625,19 @@
 <parameter name="animationListener" type="android.view.animation.Animation.AnimationListener">
 </parameter>
 </method>
+<method name="setLayoutTransition"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="transition" type="android.animation.LayoutTransition">
+</parameter>
+</method>
 <method name="setMotionEventSplittingEnabled"
  return="void"
  abstract="false"
@@ -213699,7 +214489,7 @@
  synchronized="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </method>
@@ -214249,7 +215039,7 @@
  synchronized="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="pluginsPath" type="java.lang.String">
@@ -215990,6 +216780,19 @@
 <parameter name="client" type="android.webkit.WebViewClient">
 </parameter>
 </method>
+<method name="showFindDialog"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="text" type="java.lang.String">
+</parameter>
+</method>
 <method name="stopLoading"
  return="void"
  abstract="false"
@@ -232273,6 +233076,18 @@
 >
 <parameter name="context" type="android.content.Context">
 </parameter>
+<parameter name="mode" type="int">
+</parameter>
+</constructor>
+<constructor name="Spinner"
+ type="android.widget.Spinner"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
 <parameter name="attrs" type="android.util.AttributeSet">
 </parameter>
 </constructor>
@@ -232290,6 +233105,22 @@
 <parameter name="defStyle" type="int">
 </parameter>
 </constructor>
+<constructor name="Spinner"
+ type="android.widget.Spinner"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+<parameter name="defStyle" type="int">
+</parameter>
+<parameter name="mode" type="int">
+</parameter>
+</constructor>
 <method name="getPrompt"
  return="java.lang.CharSequence"
  abstract="false"
@@ -264457,7 +265288,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="lng" type="long">
+<parameter name="l" type="long">
 </parameter>
 </method>
 <method name="append"
@@ -264535,7 +265366,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="ch" type="char[]">
+<parameter name="chars" type="char[]">
 </parameter>
 </method>
 <method name="append"
@@ -319106,9 +319937,9 @@
 >
 <parameter name="number" type="java.lang.Object">
 </parameter>
-<parameter name="toAppendTo" type="java.lang.StringBuffer">
+<parameter name="buffer" type="java.lang.StringBuffer">
 </parameter>
-<parameter name="pos" type="java.text.FieldPosition">
+<parameter name="position" type="java.text.FieldPosition">
 </parameter>
 </method>
 <method name="getDecimalFormatSymbols"
diff --git a/awt/Android.mk b/awt/Android.mk
deleted file mode 100644
index 213c6ce..0000000
--- a/awt/Android.mk
+++ /dev/null
@@ -1,31 +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-subdir-java-files)
-
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_JAVA_LIBRARIES := core framework
-
-LOCAL_MODULE:= android.awt
-
-LOCAL_DX_FLAGS := --core-library
-
-#include $(BUILD_JAVA_LIBRARY)
diff --git a/awt/com/android/internal/awt/AndroidGraphics2D.java b/awt/com/android/internal/awt/AndroidGraphics2D.java
deleted file mode 100644
index 9a8ae02..0000000
--- a/awt/com/android/internal/awt/AndroidGraphics2D.java
+++ /dev/null
@@ -1,1354 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package com.android.internal.awt;
-
-import com.android.internal.awt.AndroidGraphicsConfiguration;
-import com.android.internal.graphics.NativeUtils;
-
-import java.awt.AlphaComposite;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.GraphicsConfiguration;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphVector;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.PathIterator;
-import java.awt.image.AffineTransformOp;
-import java.awt.image.BufferedImage;
-import java.awt.image.BufferedImageOp;
-import java.awt.image.DataBuffer;
-import java.awt.image.DirectColorModel;
-import java.awt.image.ImageObserver;
-import java.awt.image.Raster;
-import java.awt.image.RenderedImage;
-import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.WritableRaster;
-import java.awt.image.renderable.RenderableImage;
-import java.text.AttributedCharacterIterator;
-import java.util.Map;
-
-import org.apache.harmony.awt.gl.ImageSurface;
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.gl.Surface;
-import org.apache.harmony.awt.gl.font.AndroidGlyphVector;
-import org.apache.harmony.awt.gl.font.FontMetricsImpl;
-import org.apache.harmony.awt.gl.image.OffscreenImage;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Path;
-
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.Typeface;
-import android.graphics.PixelXorXfermode;
-import android.view.Display;
-import android.view.WindowManager;
-import android.content.Context;
-
-public class AndroidGraphics2D extends Graphics2D {
-    
-    private int displayWidth, displayHeight;
-
-    protected Surface dstSurf = null;
-    protected MultiRectArea clip = null;
-
-    protected Composite composite = AlphaComposite.SrcOver;
-    protected AffineTransform transform = new AffineTransform();
-
-    private static AndroidGraphics2D mAg;
-    private static Canvas mC;
-
-    // Android Paint
-    public static Paint mP;
-
-    private static java.awt.Font mFnt;
-
-    // Cached Matrix
-    public static Matrix mM;
-    private static FontMetrics mFm;
-    private static RenderingHints mRh;
-    private static Color mBc;
-
-    private Area mCurrClip;
-    
-    public final static double RAD_360 = Math.PI / 180 * 360;
-    
-    // Image drawing
-    private AndroidJavaBlitter blitter;
-    private DirectColorModel cm;
-    private SinglePixelPackedSampleModel sm;
-    private WritableRaster wr;
-
-
-    public static AndroidGraphics2D getInstance() {
-        if (mAg == null) {
-            throw new RuntimeException("AndroidGraphics2D not instantiated!");
-        }
-        return mAg;
-    }
-
-    public static AndroidGraphics2D getInstance(Context ctx, Canvas c, Paint p) {
-        if (c == null || ctx == null) {
-            throw new RuntimeException(
-                    "Illegal argument, Canvas cannot be null!");
-        }
-        mAg = new AndroidGraphics2D(ctx, c, p);
-        return mAg;
-    }
-
-    private AndroidGraphics2D(Context ctx, Canvas c, Paint p) {
-        super();
-        mC = c;
-        mP = p;
-        mM = new Matrix();
-        mM.reset();
-        mM = mC.getMatrix();
-        Rect r = mC.getClipBounds();
-        int cl[] = {-1, r.top, r.left, -2, r.top, r.right, -2, r.bottom, r.right, -2, r.bottom, r.left};
-        mCurrClip = new Area(createShape(cl));
-        if(ctx != null) {
-            WindowManager wm = (WindowManager)ctx.getSystemService(Context.WINDOW_SERVICE);
-            Display d = wm.getDefaultDisplay();
-            displayWidth = d.getWidth();
-            displayHeight = d.getHeight();
-        }
-        blitter = new AndroidJavaBlitter(c);
-        cm = new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
-        sm = new SinglePixelPackedSampleModel(
-                DataBuffer.TYPE_INT, displayWidth, displayHeight, cm.getMasks());
-        wr = Raster.createWritableRaster(sm, null);
-        dstSurf = new ImageSurface(cm, wr);       
-    }
-
-    @Override
-    public void addRenderingHints(Map<?, ?> hints) {
-        if (mRh == null) {
-            mRh = (RenderingHints) hints;
-        }
-        mRh.add((RenderingHints) hints);
-    }
-
-    public float[] getMatrix() {
-        float[] f = new float[9];
-        mC.getMatrix().getValues(f);
-        return f;
-    }
-
-    /**
-     * 
-     * @return a Matrix in Android format
-     */
-    public float[] getInverseMatrix() {
-        AffineTransform af = new AffineTransform(createAWTMatrix(getMatrix()));
-        try {
-            af = af.createInverse();
-        } catch (NoninvertibleTransformException e) {
-        }
-        return createMatrix(af);
-    }
-
-    private Path getPath(Shape s) {
-        Path path = new Path();
-        PathIterator pi = s.getPathIterator(null);
-        while (pi.isDone() == false) {
-            getCurrentSegment(pi, path);
-            pi.next();
-        }
-        return path;
-    }
-
-    private void getCurrentSegment(PathIterator pi, Path path) {
-        float[] coordinates = new float[6];
-        int type = pi.currentSegment(coordinates);
-        switch (type) {
-        case PathIterator.SEG_MOVETO:
-            path.moveTo(coordinates[0], coordinates[1]);
-            break;
-        case PathIterator.SEG_LINETO:
-            path.lineTo(coordinates[0], coordinates[1]);
-            break;
-        case PathIterator.SEG_QUADTO:
-            path.quadTo(coordinates[0], coordinates[1], coordinates[2],
-                    coordinates[3]);
-            break;
-        case PathIterator.SEG_CUBICTO:
-            path.cubicTo(coordinates[0], coordinates[1], coordinates[2],
-                    coordinates[3], coordinates[4], coordinates[5]);
-            break;
-        case PathIterator.SEG_CLOSE:
-            path.close();
-            break;
-        default:
-            break;
-        }
-    }
-    
-    private Shape createShape(int[] arr) {
-        Shape s = new GeneralPath();
-        for(int i = 0; i < arr.length; i++) {
-            int type = arr[i];    
-            switch (type) {
-            case -1:
-                //MOVETO
-                ((GeneralPath)s).moveTo(arr[++i], arr[++i]);
-                break;
-            case -2:
-                //LINETO
-                ((GeneralPath)s).lineTo(arr[++i], arr[++i]);
-                break;
-            case -3:
-                //QUADTO
-                ((GeneralPath)s).quadTo(arr[++i], arr[++i], arr[++i],
-                        arr[++i]);
-                break;
-            case -4:
-                //CUBICTO
-                ((GeneralPath)s).curveTo(arr[++i], arr[++i], arr[++i],
-                        arr[++i], arr[++i], arr[++i]);
-                break;
-            case -5:
-                //CLOSE
-                return s;
-            default:
-                break;
-            }
-        }
-        return s;
-    }
-    /*
-    public int[] getPixels() {
-        return mC.getPixels();
-    }*/
-
-    public static float getRadian(float degree) {
-        return (float) ((Math.PI / 180) * degree);
-    }
-    
-    private Shape getShape() {
-        return null;
-    }
-
-    public static float getDegree(float radian) {
-        return (float) ((180 / Math.PI) * radian);
-    }
-
-    /*
-     * Degree in radian
-     */
-    public static float getEllipsisX(float degree, float princAxis) {
-        return (float) Math.cos(degree) * princAxis;
-    }
-
-    public static float getEllipsisY(float degree, float conAxis) {
-        return (float) Math.sin(degree) * conAxis;
-    }
-
-    @Override
-    public void clip(Shape s) {
-        mC.clipPath(getPath(s));
-    }
-
-    public void setCanvas(Canvas c) {
-        mC = c;
-    }
-
-    @Override
-    public void draw(Shape s) {
-        if (mP == null) {
-            mP = new Paint();
-        }
-        Paint.Style tmp = mP.getStyle();
-        mP.setStyle(Paint.Style.STROKE);
-        mC.drawPath(getPath(s), mP);
-        mP.setStyle(tmp);
-    }
-/*
-    private ArrayList getSegments(Shape s) {
-        ArrayList arr = new ArrayList();
-        PathIterator pi = s.getPathIterator(null);
-        while (pi.isDone() == false) {
-            getCurrentSegment(pi, arr);
-            pi.next();
-        }
-        return arr;
-    }
-
-    private void getCurrentSegment(PathIterator pi, ArrayList arr) {
-        float[] coordinates = new float[6];
-        int type = pi.currentSegment(coordinates);
-        switch (type) {
-        case PathIterator.SEG_MOVETO:
-            arr.add(new Integer(-1));
-            break;
-        case PathIterator.SEG_LINETO:
-            arr.add(new Integer(-2));
-            break;
-        case PathIterator.SEG_QUADTO:
-            arr.add(new Integer(-3));
-            break;
-        case PathIterator.SEG_CUBICTO:
-            arr.add(new Integer(-4));
-            break;
-        case PathIterator.SEG_CLOSE:
-            arr.add(new Integer(-5));
-            break;
-        default:
-            break;
-        }
-    }
-*/
-    /*
-     * Convenience method, not standard AWT
-     */
-    public void draw(Path s) {
-        if (mP == null) {
-            mP = new Paint();
-        }
-        Paint.Style tmp = mP.getStyle();
-        mP.setStyle(Paint.Style.STROKE);
-        s.transform(mM);
-        mC.drawPath(s, mP);
-        mP.setStyle(tmp);
-    }
-
-    @Override
-    public void drawGlyphVector(GlyphVector g, float x, float y) {
-        // TODO draw at x, y
-        // draw(g.getOutline());
-        /*
-        Matrix matrix = new Matrix();
-        matrix.setTranslate(x, y);
-        Path pth = getPath(g.getOutline());
-        pth.transform(matrix);
-        draw(pth);
-        */
-        Path path = new Path();
-        char[] c = ((AndroidGlyphVector)g).getGlyphs();
-        mP.getTextPath(c, 0, c.length, x, y, path);
-        mC.drawPath(path, mP);
-    }
-
-    @Override
-    public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
-        throw new RuntimeException("Not implemented!");
-    }
-
-    @Override
-    public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
-        throw new RuntimeException("Not implemented!");
-    }
-
-    @Override
-    public void drawString(AttributedCharacterIterator iterator, float x,
-            float y) {
-        throw new RuntimeException("AttributedCharacterIterator not supported!");
-
-    }
-
-    @Override
-    public void drawString(AttributedCharacterIterator iterator, int x, int y) {
-        throw new RuntimeException("AttributedCharacterIterator not supported!");
-
-    }
-
-    @Override
-    public void drawString(String s, float x, float y) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            Paint.Style tmp = mP.getStyle();
-
-            mP.setStyle(Paint.Style.FILL);
-            Path pth = new Path();
-            mP.getTextPath(s, 0, s.length(), x, y, pth);
-            mC.drawPath(pth, mP);
-            mP.setStyle(tmp);
-    }
-
-    @Override
-    public void drawString(String str, int x, int y) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            Paint.Style tmp = mP.getStyle();
-            mP.setStrokeWidth(0);
-
-            mC.drawText(str.toCharArray(), 0, str.toCharArray().length, x, y,
-                    mP);
-            mP.setStyle(tmp);
-    }
-
-    @Override
-    public void fill(Shape s) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            Paint.Style tmp = mP.getStyle();
-            mP.setStyle(Paint.Style.FILL);
-            mC.drawPath(getPath(s), mP);
-            mP.setStyle(tmp);
-    }
-
-    @Override
-    public Color getBackground() {
-        return mBc;
-    }
-
-    @Override
-    public Composite getComposite() {
-        throw new RuntimeException("Composite not implemented!");
-    }
-
-    @Override
-    public GraphicsConfiguration getDeviceConfiguration() {
-        return new AndroidGraphicsConfiguration();
-    }
-
-    @Override
-    public FontRenderContext getFontRenderContext() {
-        return new FontRenderContext(getTransform(), mP.isAntiAlias(), true);
-    }
-
-    @Override
-    public java.awt.Paint getPaint() {
-        throw new RuntimeException("AWT Paint not implemented in Android!");
-    }
-
-    public static Canvas getAndroidCanvas() {
-        return mC;
-    }
-    
-    public static Paint getAndroidPaint() {
-        return mP;
-    }
-
-    @Override
-    public RenderingHints getRenderingHints() {
-        return mRh;
-    }
-
-    @Override
-    public Stroke getStroke() {
-        if (mP != null) {
-            return new BasicStroke(mP.getStrokeWidth(), mP.getStrokeCap()
-                    .ordinal(), mP.getStrokeJoin().ordinal());
-        }
-        return null;
-    }
-
-    @Override
-    public AffineTransform getTransform() {
-        return new AffineTransform(createAWTMatrix(getMatrix()));
-    }
-
-    @Override
-    public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
-        // ???AWT TODO check if on stroke
-        return s.intersects(rect.getX(), rect.getY(), rect.getWidth(), rect
-                .getHeight());
-    }
-
-    @Override
-    public void rotate(double theta) {
-        mM.preRotate((float) AndroidGraphics2D
-                .getDegree((float) (RAD_360 - theta)));
-        mC.concat(mM);
-    }
-
-    @Override
-    public void rotate(double theta, double x, double y) {
-        mM.preRotate((float) AndroidGraphics2D.getDegree((float) theta),
-                (float) x, (float) y);
-        mC.concat(mM);
-    }
-
-    @Override
-    public void scale(double sx, double sy) {
-        mM.setScale((float) sx, (float) sy);
-        mC.concat(mM);
-    }
-
-    @Override
-    public void setBackground(Color color) {
-        mBc = color;
-        mC.clipRect(new Rect(0, 0, mC.getWidth(), mC.getHeight()));
-        // TODO don't limit to current clip
-        mC.drawARGB(color.getAlpha(), color.getRed(), color.getGreen(), color
-                .getBlue());
-    }
-
-    @Override
-    public void setComposite(Composite comp) {
-        throw new RuntimeException("Composite not implemented!");
-    }
-
-    public void setSpaint(Paint paint) {
-        mP = paint;
-    }
-
-    @Override
-    public void setPaint(java.awt.Paint paint) {
-        setColor((Color)paint);
-    }
-
-    @Override
-    public Object getRenderingHint(RenderingHints.Key key) {
-        if (mRh == null) {
-            return null;
-        }
-        return mRh.get(key);
-    }
-
-    @Override
-    public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) {
-        if (mRh == null) {
-            mRh = new RenderingHints(hintKey, hintValue);
-        } else {
-            mRh.put(hintKey, hintValue);
-        }
-        applyHints();
-    }
-
-    @Override
-    public void setRenderingHints(Map<?, ?> hints) {
-        mRh = (RenderingHints) hints;
-        applyHints();
-    }
-
-    private void applyHints() {
-        Object o;
-
-        // TODO do something like this:
-        /*
-         * Set s = mRh.keySet(); Iterator it = s.iterator(); while(it.hasNext()) {
-         * o = it.next(); }
-         */
-
-        // /////////////////////////////////////////////////////////////////////
-        // not supported in skia
-        /*
-         * o = mRh.get(RenderingHints.KEY_ALPHA_INTERPOLATION); if
-         * (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) { } else
-         * if (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) { }
-         * else if (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) { }
-         * 
-         * o = mRh.get(RenderingHints.KEY_COLOR_RENDERING); if
-         * (o.equals(RenderingHints.VALUE_COLOR_RENDER_DEFAULT)) { } else if
-         * (o.equals(RenderingHints.VALUE_COLOR_RENDER_QUALITY)) { } else if
-         * (o.equals(RenderingHints.VALUE_COLOR_RENDER_SPEED)) { }
-         * 
-         * o = mRh.get(RenderingHints.KEY_DITHERING); if
-         * (o.equals(RenderingHints.VALUE_DITHER_DEFAULT)) { } else if
-         * (o.equals(RenderingHints.VALUE_DITHER_DISABLE)) { } else if
-         * (o.equals(RenderingHints.VALUE_DITHER_ENABLE)) { }
-         * 
-         * o = mRh.get(RenderingHints.KEY_FRACTIONALMETRICS); if
-         * (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT)) { } else
-         * if (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_OFF)) { } else if
-         * (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_ON)) { }
-         * 
-         * o = mRh.get(RenderingHints.KEY_INTERPOLATION); if
-         * (o.equals(RenderingHints.VALUE_INTERPOLATION_BICUBIC)) { } else if
-         * (o.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) { } else if
-         * (o .equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) { }
-         * 
-         * o = mRh.get(RenderingHints.KEY_RENDERING); if
-         * (o.equals(RenderingHints.VALUE_RENDER_DEFAULT)) { } else if
-         * (o.equals(RenderingHints.VALUE_RENDER_QUALITY)) { } else if
-         * (o.equals(RenderingHints.VALUE_RENDER_SPEED)) { }
-         * 
-         * o = mRh.get(RenderingHints.KEY_STROKE_CONTROL); if
-         * (o.equals(RenderingHints.VALUE_STROKE_DEFAULT)) { } else if
-         * (o.equals(RenderingHints.VALUE_STROKE_NORMALIZE)) { } else if
-         * (o.equals(RenderingHints.VALUE_STROKE_PURE)) { }
-         */
-
-        o = mRh.get(RenderingHints.KEY_ANTIALIASING);
-        if (o != null) {
-            if (o.equals(RenderingHints.VALUE_ANTIALIAS_DEFAULT)) {
-                mP.setAntiAlias(false);
-            } else if (o.equals(RenderingHints.VALUE_ANTIALIAS_OFF)) {
-                mP.setAntiAlias(false);
-            } else if (o.equals(RenderingHints.VALUE_ANTIALIAS_ON)) {
-                mP.setAntiAlias(true);
-            }
-        }
-
-        o = mRh.get(RenderingHints.KEY_TEXT_ANTIALIASING);
-        if (o != null) {
-            if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT)) {
-                mP.setAntiAlias(false);
-            } else if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)) {
-                mP.setAntiAlias(false);
-            } else if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_ON)) {
-                mP.setAntiAlias(true);
-            }
-        }
-    }
-
-    @Override
-    public void setStroke(Stroke s) {
-        if (mP == null) {
-            mP = new Paint();
-        }
-        BasicStroke bs = (BasicStroke) s;
-        mP.setStyle(Paint.Style.STROKE);
-        mP.setStrokeWidth(bs.getLineWidth());
-
-        int cap = bs.getEndCap();
-        if (cap == 0) {
-            mP.setStrokeCap(Paint.Cap.BUTT);
-        } else if (cap == 1) {
-            mP.setStrokeCap(Paint.Cap.ROUND);
-        } else if (cap == 2) {
-            mP.setStrokeCap(Paint.Cap.SQUARE);
-        }
-
-        int join = bs.getLineJoin();
-        if (join == 0) {
-            mP.setStrokeJoin(Paint.Join.MITER);
-        } else if (join == 1) {
-            mP.setStrokeJoin(Paint.Join.ROUND);
-        } else if (join == 2) {
-            mP.setStrokeJoin(Paint.Join.BEVEL);
-        }
-    }
-
-    public static float[] createMatrix(AffineTransform Tx) {
-        double[] at = new double[9];
-        Tx.getMatrix(at);
-        float[] f = new float[at.length];
-        f[0] = (float) at[0];
-        f[1] = (float) at[2];
-        f[2] = (float) at[4];
-        f[3] = (float) at[1];
-        f[4] = (float) at[3];
-        f[5] = (float) at[5];
-        f[6] = 0;
-        f[7] = 0;
-        f[8] = 1;
-        return f;
-    }
-
-    private float[] createAWTMatrix(float[] matrix) {
-        float[] at = new float[9];
-        at[0] = matrix[0];
-        at[1] = matrix[3];
-        at[2] = matrix[1];
-        at[3] = matrix[4];
-        at[4] = matrix[2];
-        at[5] = matrix[5];
-        at[6] = 0;
-        at[7] = 0;
-        at[8] = 1;
-        return at;
-    }
-
-    public static Matrix createMatrixObj(AffineTransform Tx) {
-        Matrix m = new Matrix();
-        m.reset();
-        m.setValues(createMatrix(Tx));
-        return m;
-    }
-
-    @Override
-    public void setTransform(AffineTransform Tx) {
-        mM.reset();
-        /*
-         * if(Tx.isIdentity()) { mM = new Matrix(); }
-         */
-        mM.setValues(createMatrix(Tx));
-        Matrix m = new Matrix();
-        m.setValues(getInverseMatrix());
-        mC.concat(m);
-        mC.concat(mM);
-    }
-
-    @Override
-    public void shear(double shx, double shy) {
-        mM.setSkew((float) shx, (float) shy);
-        mC.concat(mM);
-    }
-
-    @Override
-    public void transform(AffineTransform Tx) {
-        Matrix m = new Matrix();
-        m.setValues(createMatrix(Tx));
-        mC.concat(m);
-    }
-
-    @Override
-    public void translate(double tx, double ty) {
-        mM.setTranslate((float) tx, (float) ty);
-        mC.concat(mM);
-    }
-
-    @Override
-    public void translate(int x, int y) {
-        mM.setTranslate((float) x, (float) y);
-        mC.concat(mM);
-    }
-
-    @Override
-    public void clearRect(int x, int y, int width, int height) {
-        mC.clipRect(x, y, x + width, y + height);
-        if (mBc != null) {
-            mC.drawARGB(mBc.getAlpha(), mBc.getBlue(), mBc.getGreen(), mBc
-                    .getRed());
-        } else {
-            mC.drawARGB(0xff, 0xff, 0xff, 0xff);
-        }
-    }
-
-    @Override
-    public void clipRect(int x, int y, int width, int height) {
-        int cl[] = {-1, x, y, -2, x, y + width, -2, x + height, y + width, -2, x + height, y};
-        Shape shp = createShape(cl);
-        mCurrClip.intersect(new Area(shp));
-        mC.clipRect(new Rect(x, y, x + width, y + height), Region.Op.INTERSECT);
-    }
-
-    @Override
-    public void copyArea(int sx, int sy, int width, int height, int dx, int dy) {
-        copyArea(mC, sx, sy, width + dx, height + dy, dx, dy);
-    }
-
-    @Override
-    public Graphics create() {
-        return this;
-    }
-
-    @Override
-    public void dispose() {
-            mC = null;
-            mP = null;
-    }
-
-    @Override
-    public void drawArc(int x, int y, int width, int height, int sa, int ea) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            mP.setStrokeWidth(0);
-            mC.drawArc(new RectF(x, y, x + width, y + height), 360 - (ea + sa),
-                       ea, true, mP);
-    }
-
-    
-    // ???AWT: only used for debuging, delete in final version
-    public void drawBitmap(Bitmap bm, float x, float y, Paint p) {
-        mC.drawBitmap(bm, x, y, null);
-    }
-    
-    @Override
-    public boolean drawImage(Image image, int x, int y, Color bgcolor,
-            ImageObserver imageObserver) {
-
-        if(image == null) {
-            return true;
-        }
-
-        boolean done = false;
-        boolean somebits = false;
-        Surface srcSurf = null;
-        if(image instanceof OffscreenImage){
-            OffscreenImage oi = (OffscreenImage) image;
-            if((oi.getState() & ImageObserver.ERROR) != 0) {
-                return false;
-            }
-            done = oi.prepareImage(imageObserver);
-            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
-            srcSurf = oi.getImageSurface();
-        }else{
-            done = true;
-            srcSurf = Surface.getImageSurface(image);
-        }
-
-        if(done || somebits) {
-            int w = srcSurf.getWidth();
-            int h = srcSurf.getHeight();
-            
-            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, (AffineTransform) transform.clone(),
-                    composite, bgcolor, clip);
-        }
-        return done;
-    }
-
-    @Override
-    public boolean drawImage(Image image, int x, int y, ImageObserver imageObserver) {
-        return drawImage(image, x, y, null, imageObserver);
-    }
-
-    @Override
-    public boolean drawImage(Image image, int x, int y, int width, int height,
-            Color bgcolor, ImageObserver imageObserver) {
-
-        if(image == null) {
-            return true;
-        }
-        if(width == 0 || height == 0) {
-            return true;
-        }
-
-        boolean done = false;
-        boolean somebits = false;
-        Surface srcSurf = null;
-
-        if(image instanceof OffscreenImage){
-            OffscreenImage oi = (OffscreenImage) image;
-            if((oi.getState() & ImageObserver.ERROR) != 0) {
-                return false;
-            }
-            done = oi.prepareImage(imageObserver);
-            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
-            srcSurf = oi.getImageSurface();
-        }else{
-            done = true;
-            srcSurf = Surface.getImageSurface(image);
-        }
-
-        if(done || somebits) {
-            int w = srcSurf.getWidth();
-            int h = srcSurf.getHeight();
-            if(w == width && h == height){
-                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
-                        (AffineTransform) transform.clone(),
-                        composite, bgcolor, clip);
-            }else{
-                AffineTransform xform = new AffineTransform();
-                xform.setToScale((float)width / w, (float)height / h);
-                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
-                        (AffineTransform) transform.clone(),
-                        xform, composite, bgcolor, clip);
-            }
-        }
-        return done;
-    }
-
-    @Override
-    public boolean drawImage(Image image, int x, int y, int width, int height,
-            ImageObserver imageObserver) {
-        return drawImage(image, x, y, width, height, null, imageObserver);
-    }
-
-    @Override
-    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
-            int sx1, int sy1, int sx2, int sy2, Color bgcolor,
-            ImageObserver imageObserver) {
-
-        if(image == null) {
-            return true;
-        }
-        if(dx1 == dx2 || dy1 == dy2 || sx1 == sx2 || sy1 == sy2) {
-            return true;
-        }
-
-        boolean done = false;
-        boolean somebits = false;
-        Surface srcSurf = null;
-        if(image instanceof OffscreenImage){
-            OffscreenImage oi = (OffscreenImage) image;
-            if((oi.getState() & ImageObserver.ERROR) != 0) {
-                return false;
-            }
-            done = oi.prepareImage(imageObserver);
-            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
-            srcSurf = oi.getImageSurface();
-        }else{
-            done = true;
-            srcSurf = Surface.getImageSurface(image);
-        }
-
-        if(done || somebits) {
-
-            int dstX = dx1;
-            int dstY = dy1;
-            int srcX = sx1;
-            int srcY = sy1;
-
-            int dstW = dx2 - dx1;
-            int dstH = dy2 - dy1;
-            int srcW = sx2 - sx1;
-            int srcH = sy2 - sy1;
-
-            if(srcW == dstW && srcH == dstH){
-                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
-                        (AffineTransform) transform.clone(),
-                        composite, bgcolor, clip);
-            }else{
-                AffineTransform xform = new AffineTransform();
-                xform.setToScale((float)dstW / srcW, (float)dstH / srcH);
-                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
-                        (AffineTransform) transform.clone(),
-                        xform, composite, bgcolor, clip);
-            }
-        }
-        return done;
-    }
-
-    @Override
-    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
-            int sx1, int sy1, int sx2, int sy2, ImageObserver imageObserver) {
-
-        return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
-                imageObserver);
-     }
-
-    @Override
-    public void drawImage(BufferedImage bufImage, BufferedImageOp op,
-            int x, int y) {
-
-        if(bufImage == null) {
-            return;
-        }
-
-        if(op == null) {
-            drawImage(bufImage, x, y, null);
-        } else if(op instanceof AffineTransformOp){
-            AffineTransformOp atop = (AffineTransformOp) op;
-            AffineTransform xform = atop.getTransform();
-            Surface srcSurf = Surface.getImageSurface(bufImage);
-            int w = srcSurf.getWidth();
-            int h = srcSurf.getHeight();
-            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
-                    (AffineTransform) transform.clone(), xform,
-                    composite, null, clip);
-        } else {
-            bufImage = op.filter(bufImage, null);
-            Surface srcSurf = Surface.getImageSurface(bufImage);
-            int w = srcSurf.getWidth();
-            int h = srcSurf.getHeight();
-            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
-                    (AffineTransform) transform.clone(),
-                    composite, null, clip);
-        }
-    }
-
-    @Override
-    public boolean drawImage(Image image, AffineTransform trans,
-            ImageObserver imageObserver) {
-
-        if(image == null) {
-            return true;
-        }
-        if(trans == null || trans.isIdentity()) {
-            return drawImage(image, 0, 0, imageObserver);
-        }
-
-        boolean done = false;
-        boolean somebits = false;
-        Surface srcSurf = null;
-        if(image instanceof OffscreenImage){
-            OffscreenImage oi = (OffscreenImage) image;
-            if((oi.getState() & ImageObserver.ERROR) != 0) {
-                return false;
-            }
-            done = oi.prepareImage(imageObserver);
-            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
-            srcSurf = oi.getImageSurface();
-        }else{
-            done = true;
-            srcSurf = Surface.getImageSurface(image);
-        }
-
-        if(done || somebits) {
-            int w = srcSurf.getWidth();
-            int h = srcSurf.getHeight();
-            AffineTransform xform = (AffineTransform) transform.clone();
-            xform.concatenate(trans);
-            blitter.blit(0, 0, srcSurf, 0, 0, dstSurf, w, h, xform, composite,
-                    null, clip);
-        }
-        return done;
-    }
-        
-    @Override
-    public void drawLine(int x1, int y1, int x2, int y2) {
-        if (mP == null) {
-            mP = new Paint();
-        }
-            mC.drawLine(x1, y1, x2, y2, mP);
-    }
-
-    @Override
-    public void drawOval(int x, int y, int width, int height) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            mP.setStyle(Paint.Style.STROKE);
-            mC.drawOval(new RectF(x, y, x + width, y + height), mP);
-    }
-
-    @Override
-    public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            mC.drawLine(xpoints[npoints - 1], ypoints[npoints - 1], xpoints[0],
-                    ypoints[0], mP);
-            for (int i = 0; i < npoints - 1; i++) {
-                mC.drawLine(xpoints[i], ypoints[i], xpoints[i + 1],
-                        ypoints[i + 1], mP);
-            }
-    }
-
-    @Override
-    public void drawPolyline(int[] xpoints, int[] ypoints, int npoints) {
-        for (int i = 0; i < npoints - 1; i++) {
-            drawLine(xpoints[i], ypoints[i], xpoints[i + 1], ypoints[i + 1]);
-        }
-
-    }
-
-    @Override
-    public void drawRoundRect(int x, int y, int width, int height,
-            int arcWidth, int arcHeight) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            mC.drawRoundRect(new RectF(x, y, width, height), arcWidth,
-                    arcHeight, mP);
-    }
-
-    @Override
-    public void fillArc(int x, int y, int width, int height, int sa, int ea) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            
-            Paint.Style tmp = mP.getStyle();
-            mP.setStyle(Paint.Style.FILL_AND_STROKE);
-            mC.drawArc(new RectF(x, y, x + width, y + height), 360 - (sa + ea),
-                    ea, true, mP);
-            
-            mP.setStyle(tmp);
-    }
-
-    @Override
-    public void fillOval(int x, int y, int width, int height) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            Paint.Style tmp = mP.getStyle();
-            mP.setStyle(Paint.Style.FILL);
-            mC.drawOval(new RectF(x, y, x + width, y + height), mP);
-            mP.setStyle(tmp);
-    }
-
-    @Override
-    public void fillPolygon(int[] xpoints, int[] ypoints, int npoints) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            Paint.Style tmp = mP.getStyle();
-            mC.save(Canvas.CLIP_SAVE_FLAG);
-
-            mP.setStyle(Paint.Style.FILL);
-
-            GeneralPath filledPolygon = new GeneralPath(
-                    GeneralPath.WIND_EVEN_ODD, npoints);
-            filledPolygon.moveTo(xpoints[0], ypoints[0]);
-            for (int index = 1; index < xpoints.length; index++) {
-                filledPolygon.lineTo(xpoints[index], ypoints[index]);
-            }
-            filledPolygon.closePath();
-            Path path = getPath(filledPolygon);
-            mC.clipPath(path);
-            mC.drawPath(path, mP);
-
-            mP.setStyle(tmp);
-            mC.restore();
-    }
-
-    @Override
-    public void fillRect(int x, int y, int width, int height) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            Paint.Style tmp = mP.getStyle();
-            mP.setStyle(Paint.Style.FILL);
-            mC.drawRect(new Rect(x, y, x + width, y + height), mP);
-            mP.setStyle(tmp);
-    }
-
-    @Override
-    public void drawRect(int x, int y, int width, int height) {
-        int[] xpoints = { x, x, x + width, x + width };
-        int[] ypoints = { y, y + height, y + height, y };
-        drawPolygon(xpoints, ypoints, 4);
-    }
-
-    @Override
-    public void fillRoundRect(int x, int y, int width, int height,
-            int arcWidth, int arcHeight) {
-            if (mP == null) {
-                mP = new Paint();
-            }
-            mP.setStyle(Paint.Style.FILL);
-            mC.drawRoundRect(new RectF(x, y, x + width, y + height), arcWidth,
-                    arcHeight, mP);
-    }
-
-    @Override
-    public Shape getClip() {
-        return mCurrClip;
-    }
-
-    @Override
-    public Rectangle getClipBounds() {
-            Rect r = mC.getClipBounds();
-            return new Rectangle(r.left, r.top, r.width(), r.height());
-    }
-
-    @Override
-    public Color getColor() {
-        if (mP != null) {
-            return new Color(mP.getColor());
-        }
-        return null;
-    }
-
-    @Override
-    public Font getFont() {
-        return mFnt;
-    }
-
-    @Override
-    public FontMetrics getFontMetrics(Font font) {
-        mFm = new FontMetricsImpl(font);
-        return mFm;
-    }
-
-    @Override
-    public void setClip(int x, int y, int width, int height) {
-        int cl[] = {-1, x, y, -2, x, y + width, -2, x + height, y + width, -2, x + height, y};
-        mCurrClip = new Area(createShape(cl));
-        mC.clipRect(x, y, x + width, y + height, Region.Op.REPLACE);
-
-    }
-
-    @Override
-    public void setClip(Shape clip) {
-        mCurrClip = new Area(clip);
-        mC.clipPath(getPath(clip), Region.Op.REPLACE);
-    }
-
-    @Override
-    public void setColor(Color c) {
-        if (mP == null) {
-            mP = new Paint();
-        }
-        mP.setColor(c.getRGB());
-    }
-
-    /**
-     * Font mapping:
-     * 
-     * Family:
-     * 
-     * Android         AWT
-     * -------------------------------------
-     * serif           Serif / TimesRoman
-     * sans-serif      SansSerif / Helvetica
-     * monospace       Monospaced / Courier
-     * 
-     * Style:
-     * 
-     * Android            AWT
-     * -------------------------------------
-     * normal          Plain
-     * bold            bold
-     * italic          italic
-     * 
-     */
-    @Override
-    public void setFont(Font font) {
-        if (font == null) {
-            return;
-        }
-        if (mP == null) {
-            mP = new Paint();
-        }
-
-        mFnt = font;
-        Typeface tf = null;
-        int sty = font.getStyle();
-        String nam = font.getName();
-        String aF = "";
-        if (nam != null) {
-            if (nam.equalsIgnoreCase("Serif")
-                    || nam.equalsIgnoreCase("TimesRoman")) {
-                aF = "serif";
-            } else if (nam.equalsIgnoreCase("SansSerif")
-                    || nam.equalsIgnoreCase("Helvetica")) {
-                aF = "sans-serif";
-            } else if (nam.equalsIgnoreCase("Monospaced")
-                    || nam.equalsIgnoreCase("Courier")) {
-                aF = "monospace";
-            }
-        }
-
-        switch (sty) {
-        case Font.PLAIN:
-            tf = Typeface.create(aF, Typeface.NORMAL);
-            break;
-        case Font.BOLD:
-            tf = Typeface.create(aF, Typeface.BOLD);
-            break;
-        case Font.ITALIC:
-            tf = Typeface.create(aF, Typeface.ITALIC);
-            break;
-        case Font.BOLD | Font.ITALIC:
-            tf = Typeface.create(aF, Typeface.BOLD_ITALIC);
-            break;
-        default:
-            tf = Typeface.DEFAULT;
-        }
-
-        mP.setTextSize(font.getSize());
-        mP.setTypeface(tf);
-    }
-
-    @Override
-    public void drawBytes(byte[] data, int offset, int length, int x, int y) {
-        drawString(new String(data, offset, length), x, y);
-    }
-    
-    @Override
-    public void drawPolygon(Polygon p) {
-        drawPolygon(p.xpoints, p.ypoints, p.npoints);
-    }
-
-    @Override
-    public void fillPolygon(Polygon p) {
-        fillPolygon(p.xpoints, p.ypoints, p.npoints);
-    }
-    
-    @Override
-    public Rectangle getClipBounds(Rectangle r) {
-        Shape clip = getClip();
-        if (clip != null) {
-            Rectangle b = clip.getBounds();
-            r.x = b.x;
-            r.y = b.y;
-            r.width = b.width;
-            r.height = b.height;
-        }
-        return r;
-    }
-    
-    @Override
-    public boolean hitClip(int x, int y, int width, int height) {
-        return getClipBounds().intersects(new Rectangle(x, y, width, height));
-    }
-    
-    @Override
-    public void drawChars(char[] data, int offset, int length, int x, int y) {
-        mC.drawText(data, offset, length, x, y, mP);
-    }
-    
-    @Override
-    public void setPaintMode() {
-        if (mP == null) {
-            mP = new Paint();
-        }
-        mP.setXfermode(null);
-    }
-
-    @Override
-    public void setXORMode(Color color) {
-        if (mP == null) {
-            mP = new Paint();
-        }
-        mP.setXfermode(new PixelXorXfermode(color.getRGB()));
-    }
-    
-    @Override
-    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
-        Color color = getColor();
-        Color colorUp, colorDown;
-        if (raised) {
-            colorUp = color.brighter();
-            colorDown = color.darker();
-            setColor(color);
-        } else {
-            colorUp = color.darker();
-            colorDown = color.brighter();
-            setColor(colorUp);
-        }
-
-        width--;
-        height--;
-        fillRect(x+1, y+1, width-1, height-1);
-
-        setColor(colorUp);
-        fillRect(x, y, width, 1);
-        fillRect(x, y+1, 1, height);
-
-        setColor(colorDown);
-        fillRect(x+width, y, 1, height);
-        fillRect(x+1, y+height, width, 1);
-    }
-    
-    @Override
-    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
-        Color color = getColor();
-        Color colorUp, colorDown;
-        if (raised) {
-            colorUp = color.brighter();
-            colorDown = color.darker();
-        } else {
-            colorUp = color.darker();
-            colorDown = color.brighter();
-        }
-
-        setColor(colorUp);
-        fillRect(x, y, width, 1);
-        fillRect(x, y+1, 1, height);
-
-        setColor(colorDown);
-        fillRect(x+width, y, 1, height);
-        fillRect(x+1, y+height, width, 1);
-    }
-
-    public void copyArea(Canvas canvas, int sx, int sy, int width, int height, int dx, int dy) {
-        sx += getTransform().getTranslateX();
-        sy += getTransform().getTranslateY();
-
-        NativeUtils.nativeScrollRect(canvas,
-                new Rect(sx, sy, sx + width, sy + height),
-                dx, dy);
-    }
-}
diff --git a/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java b/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java
deleted file mode 100644
index 0c888cd..0000000
--- a/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package com.android.internal.awt;
-
-import com.android.internal.awt.AndroidGraphics2D;
-
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsDevice;
-import java.awt.Rectangle;
-import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.VolatileImage;
-
-import android.graphics.Canvas;
-
-public class AndroidGraphicsConfiguration extends GraphicsConfiguration {
-
-    @Override
-    public BufferedImage createCompatibleImage(int width, int height) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public BufferedImage createCompatibleImage(int width, int height,
-            int transparency) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public VolatileImage createCompatibleVolatileImage(int width, int height) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public VolatileImage createCompatibleVolatileImage(int width, int height,
-            int transparency) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Rectangle getBounds() {
-        Canvas c = AndroidGraphics2D.getAndroidCanvas();
-        if(c != null)
-            return new Rectangle(0, 0, c.getWidth(), c.getHeight());
-        return null;
-    }
-
-    @Override
-    public ColorModel getColorModel() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ColorModel getColorModel(int transparency) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AffineTransform getDefaultTransform() {
-        return new AffineTransform();
-    }
-
-    @Override
-    public GraphicsDevice getDevice() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AffineTransform getNormalizingTransform() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-}
diff --git a/awt/com/android/internal/awt/AndroidGraphicsFactory.java b/awt/com/android/internal/awt/AndroidGraphicsFactory.java
deleted file mode 100644
index ca255b5..0000000
--- a/awt/com/android/internal/awt/AndroidGraphicsFactory.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package com.android.internal.awt;
-
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.GraphicsEnvironment;
-import java.awt.peer.FontPeer;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.gl.font.AndroidFont;
-import org.apache.harmony.awt.gl.font.FontManager;
-import org.apache.harmony.awt.gl.font.FontMetricsImpl;
-import org.apache.harmony.awt.gl.font.AndroidFontManager;
-import org.apache.harmony.awt.wtk.NativeWindow;
-import org.apache.harmony.awt.wtk.WindowFactory;
-import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.content.Context;
-
-public class AndroidGraphicsFactory extends CommonGraphics2DFactory {
-    
-    public GraphicsEnvironment createGraphicsEnvironment(WindowFactory wf) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    public Font embedFont(String fontFilePath) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    public FontManager getFontManager() {
-        return AndroidFontManager.inst;
-    }
-
-    public FontMetrics getFontMetrics(Font font) {
-        return new FontMetricsImpl(font);
-    }
-
-    public FontPeer getFontPeer(Font font) {
-        //return getFontManager().getFontPeer(font.getName(), font.getStyle(), font.getSize());
-        return new AndroidFont(font.getName(), font.getStyle(), font.getSize());
-    }
-
-    public Graphics2D getGraphics2D(NativeWindow win, int translateX,
-            int translateY, MultiRectArea clip) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    public Graphics2D getGraphics2D(NativeWindow win, int translateX,
-            int translateY, int width, int height) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    public Graphics2D getGraphics2D(Context ctx, Canvas c, Paint p) {
-        return AndroidGraphics2D.getInstance(ctx, c, p);
-    }
-
-    public Graphics2D getGraphics2D(Canvas c, Paint p) {
-        throw new RuntimeException("Not supported!");
-    }
-
-    public Graphics2D getGraphics2D() {
-        return AndroidGraphics2D.getInstance();
-    }
-
-}
diff --git a/awt/com/android/internal/awt/AndroidImageDecoder.java b/awt/com/android/internal/awt/AndroidImageDecoder.java
deleted file mode 100644
index 81b2e1a..0000000
--- a/awt/com/android/internal/awt/AndroidImageDecoder.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-package com.android.internal.awt;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
-//import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DirectColorModel;
-import java.awt.image.ImageConsumer;
-import java.awt.image.IndexColorModel;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Hashtable;
-
-import org.apache.harmony.awt.gl.image.DecodingImageSource;
-import org.apache.harmony.awt.gl.image.ImageDecoder;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-public class AndroidImageDecoder extends ImageDecoder {
-    
-    private static final int hintflags =
-        ImageConsumer.SINGLEFRAME | // PNG is a static image
-        ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
-        ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
-    
-    // Each pixel is a grayscale sample.
-    private static final int PNG_COLOR_TYPE_GRAY = 0;
-    // Each pixel is an R,G,B triple.
-    private static final int PNG_COLOR_TYPE_RGB = 2;
-    // Each pixel is a palette index, a PLTE chunk must appear.
-    private static final int PNG_COLOR_TYPE_PLTE = 3;
-    // Each pixel is a grayscale sample, followed by an alpha sample.
-    private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
-    // Each pixel is an R,G,B triple, followed by an alpha sample.
-    private static final int PNG_COLOR_TYPE_RGBA = 6;
-    
-    private static final int NB_OF_LINES_PER_CHUNK = 1;  // 0 = full image
-    
-    Bitmap bm;  // The image as decoded by Android
-    
-    // Header information
-    int imageWidth; // Image size
-    int imageHeight;  
-    int colorType;  // One of the PNG_ constants from above
-    int bitDepth;   // Number of bits per color
-    byte cmap[];    // The color palette for index color models
-    ColorModel model;  // The corresponding AWT color model
-    
-    boolean transferInts; // Is transfer of type int or byte?
-    int dataElementsPerPixel;
-
-    // Buffers for decoded image data
-    byte byteOut[];
-    int intOut[];
-
-    
-    public AndroidImageDecoder(DecodingImageSource src, InputStream is) {
-        super(src, is);
-        dataElementsPerPixel = 1;
-    }
-
-    @Override
-    /**
-     * All the decoding is done in Android
-     * 
-     * AWT???: Method returns only once the image is completly 
-     * decoded; decoding is not done asynchronously
-     */
-    public void decodeImage() throws IOException {
-        try {
-            bm = BitmapFactory.decodeStream(inputStream);
-            if (bm == null) {
-                throw new IOException("Input stream empty and no image cached");
-            }
-
-            // Check size
-            imageWidth = bm.getWidth();
-            imageHeight = bm.getHeight();
-            if (imageWidth < 0 || imageHeight < 0 ) {
-                throw new RuntimeException("Illegal image size: " 
-                        + imageWidth + ", " + imageHeight);
-            }
-            
-            // We got the image fully decoded; now send all image data to AWT
-            setDimensions(imageWidth, imageHeight);
-            model = createColorModel();
-            setColorModel(model);
-            setHints(hintflags);
-            setProperties(new Hashtable<Object, Object>()); // Empty
-            sendPixels(NB_OF_LINES_PER_CHUNK != 0 ? NB_OF_LINES_PER_CHUNK : imageHeight);
-            imageComplete(ImageConsumer.STATICIMAGEDONE);        
-        } catch (IOException e) {
-            throw e;
-        } catch (RuntimeException e) {
-            imageComplete(ImageConsumer.IMAGEERROR);
-            throw e;
-        } finally {
-            closeStream();
-        }
-    }
-    
-    /**
-     * Create the AWT color model
-     *
-     * ???AWT: Android Bitmaps are always of type: ARGB-8888-Direct color model
-     * 
-     * However, we leave the code here for a more powerfull decoder 
-     * that returns a native model, and the conversion is then handled
-     * in AWT. With such a decoder, we would need to get the colorType, 
-     * the bitDepth, (and the color palette for an index color model)
-     * from the image and construct the correct color model here.
-     */
-    private ColorModel createColorModel() {
-        ColorModel cm = null;
-        int bmModel = 5; // TODO This doesn't exist: bm.getColorModel();
-        cmap = null;
-           
-        switch (bmModel) {
-        // A1_MODEL
-        case 1: 
-            colorType = PNG_COLOR_TYPE_GRAY;
-            bitDepth = 1;
-            break;
-            
-        // A8_MODEL
-        case 2:
-            colorType = PNG_COLOR_TYPE_GRAY_ALPHA;
-            bitDepth = 8;
-            break;
-            
-        // INDEX8_MODEL
-        // RGB_565_MODEL
-        // ARGB_8888_MODEL
-        case 3:
-        case 4: 
-        case 5: 
-            colorType = bm.hasAlpha() ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB;
-            bitDepth = 8;
-            break;
-
-        default:
-            // awt.3C=Unknown PNG color type
-            throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-        }
-        
-        switch (colorType) {
-        
-            case PNG_COLOR_TYPE_GRAY: {
-                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 &&  bitDepth != 1) {
-                    // awt.3C=Unknown PNG color type
-                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-                }
-
-                // Create gray color model
-                int numEntries = 1 << bitDepth;
-                int scaleFactor = 255 / (numEntries-1);
-                byte comps[] = new byte[numEntries];
-                for (int i = 0; i < numEntries; i++) {
-                    comps[i] = (byte) (i * scaleFactor);
-                }
-                cm = new IndexColorModel(bitDepth, numEntries, comps, comps, comps);
-
-                transferInts = false;
-                break;
-            }
-
-            case PNG_COLOR_TYPE_RGB: {
-                if (bitDepth != 8) {
-                    // awt.3C=Unknown PNG color type
-                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-                }
-                
-                cm = new DirectColorModel(24, 0xff0000, 0xFF00, 0xFF);
-                
-                transferInts = true;
-                break;
-            }
-
-            case PNG_COLOR_TYPE_PLTE: {
-                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
-                    // awt.3C=Unknown PNG color type
-                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-                }
-
-                if (cmap == null) {
-                    throw new IllegalStateException("Palette color type is not supported");
-                }
-
-                cm = new IndexColorModel(bitDepth, cmap.length / 3, cmap, 0, false);
-
-                transferInts = false;
-                break;
-            }
-
-            case PNG_COLOR_TYPE_GRAY_ALPHA: {
-                if (bitDepth != 8) {
-                    // awt.3C=Unknown PNG color type
-                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-                }
-
-                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
-                        true, false,
-                        Transparency.TRANSLUCENT,
-                        DataBuffer.TYPE_BYTE);
-
-                transferInts = false;
-                dataElementsPerPixel = 2;
-                break;
-            }
-
-            case PNG_COLOR_TYPE_RGBA: {
-                if (bitDepth != 8) {
-                    // awt.3C=Unknown PNG color type
-                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-                }
-
-                cm = ColorModel.getRGBdefault();
-
-                transferInts = true;
-                break;
-            }
-            default:
-                // awt.3C=Unknown PNG color type
-                throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-        }
-        
-        return cm;
-    }
-    
-    private void sendPixels(int nbOfLinesPerChunk) {
-        int w = imageWidth;
-        int h = imageHeight;
-        int n = 1;
-        if (nbOfLinesPerChunk > 0 && nbOfLinesPerChunk <= h) {
-            n = nbOfLinesPerChunk;
-        }
-        
-        if (transferInts) {
-            // Create output buffer
-            intOut = new int[w * n];
-            for (int yi = 0; yi < h; yi += n) {
-                // Last chunk might contain less liness
-                if (n > 1 && h - yi < n ) {
-                    n = h - yi;
-                }
-                bm.getPixels(intOut, 0, w, 0, yi, w, n);
-                setPixels(0, yi, w, n, model, intOut, 0, w);
-            }
-        } else {
-            // Android bitmaps always store ints (ARGB-8888 direct model)
-            throw new RuntimeException("Byte transfer not supported");
-        }
-    }
-    
-}
diff --git a/awt/com/android/internal/awt/AndroidJavaBlitter.java b/awt/com/android/internal/awt/AndroidJavaBlitter.java
deleted file mode 100644
index 423b534..0000000
--- a/awt/com/android/internal/awt/AndroidJavaBlitter.java
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package com.android.internal.awt;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.gl.Surface;
-import org.apache.harmony.awt.gl.XORComposite;
-import org.apache.harmony.awt.gl.render.Blitter;
-
-import java.awt.*;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferInt;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-
-public class AndroidJavaBlitter implements Blitter {
-
-    private Canvas canvas;
-    private Paint paint;
-    private int colorCache;
-        
-    public AndroidJavaBlitter(Canvas c) {
-        this.canvas = c;
-        this.paint = new Paint();
-        this.paint.setStrokeWidth(1);
-    }
-    
-    /**
-     * Instead of multiplication and division we are using values from
-     * Lookup tables.
-     */
-    static byte mulLUT[][]; // Lookup table for multiplication
-    static byte divLUT[][]; // Lookup table for division
-
-    static{
-        mulLUT = new byte[256][256];
-        for(int i = 0; i < 256; i++){
-            for(int j = 0; j < 256; j++){
-                mulLUT[i][j] = (byte)((float)(i * j)/255 + 0.5f);
-            }
-        }
-        divLUT = new byte[256][256];
-        for(int i = 1; i < 256; i++){
-            for(int j = 0; j < i; j++){
-                divLUT[i][j] = (byte)(((float)j / 255) / ((float)i/ 255) * 255 + 0.5f);
-            }
-            for(int j = i; j < 256; j++){
-                divLUT[i][j] = (byte)255;
-            }
-        }
-    }
-
-    final static int AlphaCompositeMode = 1;
-    final static int XORMode = 2;
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, AffineTransform sysxform,
-            AffineTransform xform, Composite comp, Color bgcolor,
-            MultiRectArea clip) {
-        
-        if(xform == null){
-            blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
-                    sysxform, comp, bgcolor, clip);
-        }else{
-            double scaleX = xform.getScaleX();
-            double scaleY = xform.getScaleY();
-            double scaledX = dstX / scaleX;
-            double scaledY = dstY / scaleY;
-            AffineTransform at = new AffineTransform();
-            at.setToTranslation(scaledX, scaledY);
-            xform.concatenate(at);
-            sysxform.concatenate(xform);
-            blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
-                    sysxform, comp, bgcolor, clip);
-        }
-
-    }
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, AffineTransform sysxform,
-            Composite comp, Color bgcolor, MultiRectArea clip) {
-        
-        if(sysxform == null) {
-            sysxform = new AffineTransform();
-        }
-        int type = sysxform.getType();
-        switch(type){
-            case AffineTransform.TYPE_TRANSLATION:
-                dstX += sysxform.getTranslateX();
-                dstY += sysxform.getTranslateY();
-            case AffineTransform.TYPE_IDENTITY:
-                simpleBlit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
-                        width, height, comp, bgcolor, clip);
-                break;
-            default:
-                int srcW = srcSurf.getWidth();
-                int srcH = srcSurf.getHeight();
-
-                int w = srcX + width < srcW ? width : srcW - srcX;
-                int h = srcY + height < srcH ? height : srcH - srcY;
-
-                ColorModel srcCM = srcSurf.getColorModel();
-                Raster srcR = srcSurf.getRaster().createChild(srcX, srcY,
-                        w, h, 0, 0, null);
-
-                ColorModel dstCM = dstSurf.getColorModel();
-                WritableRaster dstR = dstSurf.getRaster();
-
-                transformedBlit(srcCM, srcR, 0, 0, dstCM, dstR, dstX, dstY, w, h,
-                        sysxform, comp, bgcolor, clip);
-
-        }
-    }
-
-    public void simpleBlit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, Composite comp,
-            Color bgcolor, MultiRectArea clip) {
-
-        // TODO It's possible, though unlikely that we might encounter non-int[]
-        // data buffers. In this case the following code needs to have several
-        // branches that take this into account.
-        data = (DataBufferInt)srcSurf.getRaster().getDataBuffer();
-        int[] pixels = data.getData();
-        if (!srcSurf.getColorModel().hasAlpha()) {
-            // This wouldn't be necessary if Android supported RGB_888.
-            for (int i = 0; i < pixels.length; i++) {
-                pixels[i] = pixels[i] | 0xff000000;
-            }
-        }
-        bmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
-        canvas.drawBitmap(bmap, dstX, dstY, paint);
-    }
-    
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, Composite comp,
-            Color bgcolor, MultiRectArea clip) {
-
-        javaBlt(srcX, srcY, srcSurf.getWidth(), srcSurf.getHeight(),
-                srcSurf.getColorModel(), srcSurf.getRaster(), dstX, dstY,
-                dstSurf.getWidth(), dstSurf.getHeight(),
-                dstSurf.getColorModel(), dstSurf.getRaster(),
-                width, height, comp, bgcolor, clip);
-
-    }
-    
-    public void javaBlt(int srcX, int srcY, int srcW, int srcH,
-            ColorModel srcCM, Raster srcRast, int dstX, int dstY,
-            int dstW, int dstH, ColorModel dstCM, WritableRaster dstRast,
-            int width, int height, Composite comp, Color bgcolor,
-            MultiRectArea clip){
-        
-        int srcX2 = srcW - 1;
-        int srcY2 = srcH - 1;
-        int dstX2 = dstW - 1;
-        int dstY2 = dstH - 1;
-
-        if(srcX < 0){
-            width += srcX;
-            srcX = 0;
-        }
-        if(srcY < 0){
-            height += srcY;
-            srcY = 0;
-        }
-
-        if(dstX < 0){
-            width += dstX;
-            srcX -= dstX;
-            dstX = 0;
-        }
-        if(dstY < 0){
-            height += dstY;
-            srcY -= dstY;
-            dstY = 0;
-        }
-
-        if(srcX > srcX2 || srcY > srcY2) {
-            return;
-        }
-        if(dstX > dstX2 || dstY > dstY2) {
-            return;
-        }
-
-        if(srcX + width > srcX2) {
-            width = srcX2 - srcX + 1;
-        }
-        if(srcY + height > srcY2) {
-            height = srcY2 - srcY + 1;
-        }
-        if(dstX + width > dstX2) {
-            width = dstX2 - dstX + 1;
-        }
-        if(dstY + height > dstY2) {
-            height = dstY2 - dstY + 1;
-        }
-
-        if(width <= 0 || height <= 0) {
-            return;
-        }
-
-        int clipRects[];
-        if(clip != null) {
-            clipRects = clip.rect;
-        } else {
-            clipRects = new int[]{5, 0, 0, dstW - 1, dstH - 1};
-        }
-
-        boolean isAlphaComp = false;
-        int rule = 0;
-        float alpha = 0;
-        boolean isXORComp = false;
-        Color xorcolor = null;
-        CompositeContext cont = null;
-
-        if(comp instanceof AlphaComposite){
-            isAlphaComp = true;
-            AlphaComposite ac = (AlphaComposite) comp;
-            rule = ac.getRule();
-            alpha = ac.getAlpha();
-        }else if(comp instanceof XORComposite){
-            isXORComp = true;
-            XORComposite xcomp = (XORComposite) comp;
-            xorcolor = xcomp.getXORColor();
-        }else{
-            cont = comp.createContext(srcCM, dstCM, null);
-        }
-
-        for(int i = 1; i < clipRects[0]; i += 4){
-            int _sx = srcX;
-            int _sy = srcY;
-
-            int _dx = dstX;
-            int _dy = dstY;
-
-            int _w = width;
-            int _h = height;
-
-            int cx = clipRects[i];          // Clipping left top X
-            int cy = clipRects[i + 1];      // Clipping left top Y
-            int cx2 = clipRects[i + 2];     // Clipping right bottom X
-            int cy2 = clipRects[i + 3];     // Clipping right bottom Y
-
-            if(_dx > cx2 || _dy > cy2 || dstX2 < cx || dstY2 < cy) {
-                continue;
-            }
-
-            if(cx > _dx){
-                int shx = cx - _dx;
-                _w -= shx;
-                _dx = cx;
-                _sx += shx;
-            }
-
-            if(cy > _dy){
-                int shy = cy - _dy;
-                _h -= shy;
-                _dy = cy;
-                _sy += shy;
-            }
-
-            if(_dx + _w > cx2 + 1){
-                _w = cx2 - _dx + 1;
-            }
-
-            if(_dy + _h > cy2 + 1){
-                _h = cy2 - _dy + 1;
-            }
-
-            if(_sx > srcX2 || _sy > srcY2) {
-                continue;
-            }
-
-            if(isAlphaComp){
-                alphaCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
-                        dstCM, dstRast, _w, _h, rule, alpha, bgcolor);
-            }else if(isXORComp){
-                xorCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
-                        dstCM, dstRast, _w, _h, xorcolor);
-            }else{
-                Raster sr = srcRast.createChild(_sx, _sy, _w, _h, 0, 0, null);
-                WritableRaster dr = dstRast.createWritableChild(_dx, _dy,
-                        _w, _h, 0, 0, null);
-                cont.compose(sr, dr, dr);
-            }
-        }
-        
-    }
-
-    DataBufferInt data;
-    Bitmap bmap, bmp;
-    
-    void alphaCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
-            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
-            int width, int height, int rule, float alpha, Color bgcolor){
-        
-        Object srcPixel = getTransferArray(srcRast, 1);
-        data = (DataBufferInt)srcRast.getDataBuffer();
-        int pix[] = data.getData();
-        bmap = Bitmap.createBitmap(pix, width, height, Bitmap.Config.RGB_565);
-        canvas.drawBitmap(bmap, dstX, dstY, paint);
-    }
-    
-    void render(int[] img, int x, int y, int width, int height) {
-        canvas.drawBitmap(Bitmap.createBitmap(img, width, height, Bitmap.Config.ARGB_8888), x, y, paint);
-    }
-
-    void xorCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
-            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
-            int width, int height, Color xorcolor){
-
-        data = (DataBufferInt)srcRast.getDataBuffer();
-        int pix[] = data.getData();
-        bmap = Bitmap.createBitmap(pix, width, height, Bitmap.Config.RGB_565);
-        canvas.drawBitmap(bmap, dstX, dstY, paint);
-    }
-    
-    private void transformedBlit(ColorModel srcCM, Raster srcR, int srcX, int srcY,
-            ColorModel dstCM, WritableRaster dstR, int dstX, int dstY,
-            int width, int height, AffineTransform at, Composite comp,
-            Color bgcolor, MultiRectArea clip) {
-        
-        data = (DataBufferInt)srcR.getDataBuffer();
-        int[] pixels = data.getData();
-        if (!srcCM.hasAlpha()) {
-            // This wouldn't be necessary if Android supported RGB_888.
-            for (int i = 0; i < pixels.length; i++) {
-                pixels[i] = pixels[i] | 0xff000000;
-            }
-        }
-        bmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
-        
-        Matrix tm = new Matrix();
-        tm.setConcat(canvas.getMatrix(), AndroidGraphics2D.createMatrixObj(at));
-        if(at.getType() > 1) {
-            bmp = Bitmap.createBitmap(bmap, 0, 0, width, height, tm, true);
-        } else {
-            bmp = Bitmap.createBitmap(bmap, 0, 0, width, height, tm, false);
-        }
-        canvas.drawBitmap(bmp, dstX + (float)at.getTranslateX(), dstY + (float)at.getTranslateY(), paint);
-    }
-
-    private Rectangle2D getBounds2D(AffineTransform at, Rectangle r) {
-        int x = r.x;
-        int y = r.y;
-        int width = r.width;
-        int height = r.height;
-
-        float[] corners = {
-            x, y,
-            x + width, y,
-            x + width, y + height,
-            x, y + height
-        };
-
-        at.transform(corners, 0, corners, 0, 4);
-
-        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0);
-        bounds.add(corners[2], corners[3]);
-        bounds.add(corners[4], corners[5]);
-        bounds.add(corners[6], corners[7]);
-
-        return bounds;
-    }
-
-    private int compose(int srcRGB, boolean isSrcAlphaPre,
-            int dstRGB, boolean dstHasAlpha, boolean isDstAlphaPre,
-            int rule, int srcConstAlpha){
-
-        int sa, sr, sg, sb, da, dr, dg, db;
-
-        sa = (srcRGB >> 24) & 0xff;
-        sr = (srcRGB >> 16) & 0xff;
-        sg = (srcRGB >> 8) & 0xff;
-        sb = srcRGB & 0xff;
-
-        if(isSrcAlphaPre){
-            sa = mulLUT[srcConstAlpha][sa] & 0xff;
-            sr = mulLUT[srcConstAlpha][sr] & 0xff;
-            sg = mulLUT[srcConstAlpha][sg] & 0xff;
-            sb = mulLUT[srcConstAlpha][sb] & 0xff;
-        }else{
-            sa = mulLUT[srcConstAlpha][sa] & 0xff;
-            sr = mulLUT[sa][sr] & 0xff;
-            sg = mulLUT[sa][sg] & 0xff;
-            sb = mulLUT[sa][sb] & 0xff;
-        }
-
-        da = (dstRGB >> 24) & 0xff;
-        dr = (dstRGB >> 16) & 0xff;
-        dg = (dstRGB >> 8) & 0xff;
-        db = dstRGB & 0xff;
-
-        if(!isDstAlphaPre){
-            dr = mulLUT[da][dr] & 0xff;
-            dg = mulLUT[da][dg] & 0xff;
-            db = mulLUT[da][db] & 0xff;
-        }
-
-        int Fs = 0;
-        int Fd = 0;
-        switch(rule){
-        case AlphaComposite.CLEAR:
-            break;
-
-        case AlphaComposite.DST:
-            Fd = 255;
-            break;
-
-        case AlphaComposite.DST_ATOP:
-            Fs = 255 - da;
-            Fd = sa;
-            break;
-
-        case AlphaComposite.DST_IN:
-            Fd = sa;
-            break;
-
-        case AlphaComposite.DST_OUT:
-            Fd = 255 - sa;
-            break;
-
-        case AlphaComposite.DST_OVER:
-            Fs = 255 - da;
-            Fd = 255;
-            break;
-
-        case AlphaComposite.SRC:
-            Fs = 255;
-            break;
-
-        case AlphaComposite.SRC_ATOP:
-            Fs = da;
-            Fd = 255 - sa;
-            break;
-
-        case AlphaComposite.SRC_IN:
-            Fs = da;
-            break;
-
-        case AlphaComposite.SRC_OUT:
-            Fs = 255 - da;
-            break;
-
-        case AlphaComposite.SRC_OVER:
-            Fs = 255;
-            Fd = 255 - sa;
-            break;
-
-        case AlphaComposite.XOR:
-            Fs = 255 - da;
-            Fd = 255 - sa;
-            break;
-        }
-        dr = (mulLUT[sr][Fs] & 0xff) + (mulLUT[dr][Fd] & 0xff);
-        dg = (mulLUT[sg][Fs] & 0xff) + (mulLUT[dg][Fd] & 0xff);
-        db = (mulLUT[sb][Fs] & 0xff) + (mulLUT[db][Fd] & 0xff);
-
-        da = (mulLUT[sa][Fs] & 0xff) + (mulLUT[da][Fd] & 0xff);
-
-        if(!isDstAlphaPre){
-            if(da != 255){
-                dr = divLUT[da][dr] & 0xff;
-                dg = divLUT[da][dg] & 0xff;
-                db = divLUT[da][db] & 0xff;
-            }
-        }
-        if(!dstHasAlpha) {
-            da = 0xff;
-        }
-        dstRGB = (da << 24) | (dr << 16) | (dg << 8) | db;
-
-        return dstRGB;
-
-    }
-    
-    /**
-     * Allocate an array that can be use to store the result for a 
-     * Raster.getDataElements call.
-     * @param raster  Raster (type) where the getDataElements call will be made. 
-     * @param nbPixels  How many pixels to store in the array at most
-     * @return the result array or null
-     */
-    private Object getTransferArray(Raster raster, int nbPixels) {
-        int transferType = raster.getTransferType();
-        int nbDataElements = raster.getSampleModel().getNumDataElements();
-        int n = nbDataElements * nbPixels;
-        switch (transferType) {
-        case DataBuffer.TYPE_BYTE:
-            return new byte[n];
-        case DataBuffer.TYPE_SHORT:
-        case DataBuffer.TYPE_USHORT:
-            return new short[n];
-        case DataBuffer.TYPE_INT:
-            return new int[n];
-        case DataBuffer.TYPE_FLOAT:
-            return new float[n];
-        case DataBuffer.TYPE_DOUBLE:
-            return new double[n];
-        case DataBuffer.TYPE_UNDEFINED:
-        default:
-            return null;
-        }
-    }
-    
-    /**
-     * Draw a pixel
-     */
-    private void dot(int x, int y, int clr) {
-        if (colorCache != clr) {
-            paint.setColor(clr);  
-            colorCache = clr;
-        }
-        canvas.drawLine(x, y, x + 1, y + 1, paint);
-    }
-}
diff --git a/awt/com/android/internal/awt/AndroidNativeEventQueue.java b/awt/com/android/internal/awt/AndroidNativeEventQueue.java
deleted file mode 100644
index fc30614..0000000
--- a/awt/com/android/internal/awt/AndroidNativeEventQueue.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package com.android.internal.awt;
-
-import org.apache.harmony.awt.wtk.NativeEventQueue;
-
-public class AndroidNativeEventQueue extends NativeEventQueue {
-    
-    private Object eventMonitor;
-    
-    public AndroidNativeEventQueue() {
-        super();
-        eventMonitor = getEventMonitor();
-    }
-
-    @Override
-    public void awake() {
-        synchronized (eventMonitor) {
-            eventMonitor.notify();
-        }
-    }
-
-    @Override
-    public void dispatchEvent() {
-        //???AWT
-        System.out.println(getClass()+": empty method called");
-    }
-
-    @Override
-    public long getJavaWindow() {
-        //???AWT
-        System.out.println(getClass()+": empty method called");
-        return 0;
-    }
-
-    @Override
-    public void performLater(Task task) {
-        //???AWT
-        System.out.println(getClass()+": empty method called");
-    }
-
-    @Override
-    public void performTask(Task task) {
-        //???AWT
-        System.out.println(getClass()+": empty method called");
-    }
-
-    @Override
-    public boolean waitEvent() {
-        while (isEmpty() ) {
-            synchronized (eventMonitor) {
-                try {
-                    eventMonitor.wait(1000);
-                } catch (InterruptedException ignore) {
-                }
-            }
-        }
-        return false;
-    }
-
-}
diff --git a/awt/com/android/internal/awt/AndroidWTK.java b/awt/com/android/internal/awt/AndroidWTK.java
deleted file mode 100644
index 1609d11..0000000
--- a/awt/com/android/internal/awt/AndroidWTK.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package com.android.internal.awt;
-
-import java.awt.GraphicsDevice;
-
-import org.apache.harmony.awt.wtk.CursorFactory;
-import org.apache.harmony.awt.wtk.GraphicsFactory;
-import org.apache.harmony.awt.wtk.NativeEventQueue;
-import org.apache.harmony.awt.wtk.NativeIM;
-import org.apache.harmony.awt.wtk.NativeMouseInfo;
-import org.apache.harmony.awt.wtk.NativeRobot;
-import org.apache.harmony.awt.wtk.SystemProperties;
-import org.apache.harmony.awt.wtk.WTK;
-import org.apache.harmony.awt.wtk.WindowFactory;
-
-public class AndroidWTK extends WTK {
-
-    private AndroidGraphicsFactory mAgf;
-    private AndroidNativeEventQueue mAneq;
-    
-    @Override
-    public CursorFactory getCursorFactory() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public GraphicsFactory getGraphicsFactory() {
-        if(mAgf == null) {
-            mAgf = new AndroidGraphicsFactory();
-        }
-        return mAgf;
-    }
-
-    @Override
-    public NativeEventQueue getNativeEventQueue() {
-        if(mAneq == null) {
-            mAneq = new AndroidNativeEventQueue();
-        }
-        return mAneq;
-    }
-
-    @Override
-    public NativeIM getNativeIM() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public NativeMouseInfo getNativeMouseInfo() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public NativeRobot getNativeRobot(GraphicsDevice screen) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public SystemProperties getSystemProperties() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public WindowFactory getWindowFactory() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-}
diff --git a/awt/com/android/internal/awt/AwtFactory.java b/awt/com/android/internal/awt/AwtFactory.java
deleted file mode 100644
index 6e667b2..0000000
--- a/awt/com/android/internal/awt/AwtFactory.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package com.android.internal.awt;
-
-import java.awt.Graphics2D;
-import java.awt.Toolkit;
-
-import org.apache.harmony.awt.wtk.GraphicsFactory;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-
-public class AwtFactory {
-    
-    private static GraphicsFactory gf;
-    
-    /**
-     * Use this method to get acces to AWT drawing primitives and to
-     * render into the surface area of a Android widget. Origin and 
-     * clip of the returned graphics object are the same as in the
-     * corresponding Android widget. 
-     * 
-     * @param c Canvas of the android widget to draw into
-     * @param p The default drawing parameters such as font, 
-     * stroke, foreground and background colors, etc.
-     * @return The AWT Graphics object that makes all AWT 
-     * drawing primitives available in the androind world.
-     */
-    public static Graphics2D getAwtGraphics(Canvas c, Paint p) {
-        // AWT?? TODO: test it!
-        if (null == gf) {
-            Toolkit tk = Toolkit.getDefaultToolkit();
-            gf = tk.getGraphicsFactory();
-        }
-        return gf.getGraphics2D(c, p);
-    }
-
-}
diff --git a/awt/com/android/internal/awt/ImageOutputStreamWrapper.java b/awt/com/android/internal/awt/ImageOutputStreamWrapper.java
deleted file mode 100644
index 92185fd..0000000
--- a/awt/com/android/internal/awt/ImageOutputStreamWrapper.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-package com.android.internal.awt;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-import javax.imageio.stream.ImageOutputStream;
-
-public class ImageOutputStreamWrapper extends OutputStream {
-	
-	protected ImageOutputStream mIos;
-	
-	private byte[] mBuff;
-	
-	public ImageOutputStreamWrapper(ImageOutputStream ios) {
-		if (null == ios) {
-			throw new IllegalArgumentException("ImageOutputStream must not be null");
-		}
-		this.mIos = ios;
-		this.mBuff = new byte[1];
-	}
-
-	public ImageOutputStream getImageOutputStream() {
-		return mIos;
-	}
-	
-	@Override
-	public void write(int oneByte) throws IOException {
-		mBuff[0] = (byte)oneByte;
-		mIos.write(mBuff, 0, 1);
-	}
-
-	public void write(byte[] b) throws IOException {
-		mIos.write(b, 0, b.length);
-	}
-	
-	public void write(byte[] b, int off, int len) throws IOException {
-		mIos.write(b, off, len);
-	}
-	
-	public void flush() throws IOException {
-		mIos.flush();
-	}
-	
-    public void close() throws IOException {
-    	if (mIos == null) {
-    		throw new IOException("Stream already closed");
-    	}
-        mIos = null;
-    }
-}
diff --git a/awt/java/awt/AWTEvent.java b/awt/java/awt/AWTEvent.java
deleted file mode 100644
index a8dc83a..0000000
--- a/awt/java/awt/AWTEvent.java
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev, Michael Danilov
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.util.EventObject;
-import java.util.Hashtable;
-import java.util.EventListener;
-
-import java.awt.event.*;
-
-/**
- * The abstract class AWTEvent is the base class for all AWT events. This class
- * and its subclasses supersede the original java.awt.Event class.
- * 
- * @since Android 1.0
- */
-public abstract class AWTEvent extends EventObject {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -1825314779160409405L;
-
-    /**
-     * The Constant COMPONENT_EVENT_MASK indicates the event relates to a
-     * component.
-     */
-    public static final long COMPONENT_EVENT_MASK = 1;
-
-    /**
-     * The Constant CONTAINER_EVENT_MASK indicates the event relates to a
-     * container.
-     */
-    public static final long CONTAINER_EVENT_MASK = 2;
-
-    /**
-     * The Constant FOCUS_EVENT_MASK indicates the event relates to the focus.
-     */
-    public static final long FOCUS_EVENT_MASK = 4;
-
-    /**
-     * The Constant KEY_EVENT_MASK indicates the event relates to a key.
-     */
-    public static final long KEY_EVENT_MASK = 8;
-
-    /**
-     * The Constant MOUSE_EVENT_MASK indicates the event relates to the mouse.
-     */
-    public static final long MOUSE_EVENT_MASK = 16;
-
-    /**
-     * The Constant MOUSE_MOTION_EVENT_MASK indicates the event relates to a
-     * mouse motion.
-     */
-    public static final long MOUSE_MOTION_EVENT_MASK = 32;
-
-    /**
-     * The Constant WINDOW_EVENT_MASK indicates the event relates to a window.
-     */
-    public static final long WINDOW_EVENT_MASK = 64;
-
-    /**
-     * The Constant ACTION_EVENT_MASK indicates the event relates to an action.
-     */
-    public static final long ACTION_EVENT_MASK = 128;
-
-    /**
-     * The Constant ADJUSTMENT_EVENT_MASK indicates the event relates to an
-     * adjustment.
-     */
-    public static final long ADJUSTMENT_EVENT_MASK = 256;
-
-    /**
-     * The Constant ITEM_EVENT_MASK indicates the event relates to an item.
-     */
-    public static final long ITEM_EVENT_MASK = 512;
-
-    /**
-     * The Constant TEXT_EVENT_MASK indicates the event relates to text.
-     */
-    public static final long TEXT_EVENT_MASK = 1024;
-
-    /**
-     * The Constant INPUT_METHOD_EVENT_MASK indicates the event relates to an
-     * input method.
-     */
-    public static final long INPUT_METHOD_EVENT_MASK = 2048;
-
-    /**
-     * The Constant PAINT_EVENT_MASK indicates the event relates to a paint
-     * method.
-     */
-    public static final long PAINT_EVENT_MASK = 8192;
-
-    /**
-     * The Constant INVOCATION_EVENT_MASK indicates the event relates to a
-     * method invocation.
-     */
-    public static final long INVOCATION_EVENT_MASK = 16384;
-
-    /**
-     * The Constant HIERARCHY_EVENT_MASK indicates the event relates to a
-     * hierarchy.
-     */
-    public static final long HIERARCHY_EVENT_MASK = 32768;
-
-    /**
-     * The Constant HIERARCHY_BOUNDS_EVENT_MASK indicates the event relates to
-     * hierarchy bounds.
-     */
-    public static final long HIERARCHY_BOUNDS_EVENT_MASK = 65536;
-
-    /**
-     * The Constant MOUSE_WHEEL_EVENT_MASK indicates the event relates to the
-     * mouse wheel.
-     */
-    public static final long MOUSE_WHEEL_EVENT_MASK = 131072;
-
-    /**
-     * The Constant WINDOW_STATE_EVENT_MASK indicates the event relates to a
-     * window state.
-     */
-    public static final long WINDOW_STATE_EVENT_MASK = 262144;
-
-    /**
-     * The Constant WINDOW_FOCUS_EVENT_MASK indicates the event relates to a
-     * window focus.
-     */
-    public static final long WINDOW_FOCUS_EVENT_MASK = 524288;
-
-    /**
-     * The Constant RESERVED_ID_MAX indicates the maximum value for reserved AWT
-     * event IDs.
-     */
-    public static final int RESERVED_ID_MAX = 1999;
-
-    /**
-     * The Constant eventsMap.
-     */
-    private static final Hashtable<Integer, EventDescriptor> eventsMap = new Hashtable<Integer, EventDescriptor>();
-
-    /**
-     * The converter.
-     */
-    private static EventConverter converter;
-
-    /**
-     * The ID of the event.
-     */
-    protected int id;
-
-    /**
-     * The consumed indicates whether or not the event is sent back down to the
-     * peer once the source has processed it (false means it's sent to the peer,
-     * true means it's not).
-     */
-    protected boolean consumed;
-
-    /**
-     * The dispatched by kfm.
-     */
-    boolean dispatchedByKFM;
-
-    /**
-     * The is posted.
-     */
-    transient boolean isPosted;
-
-    static {
-        eventsMap.put(new Integer(KeyEvent.KEY_TYPED), new EventDescriptor(KEY_EVENT_MASK,
-                KeyListener.class));
-        eventsMap.put(new Integer(KeyEvent.KEY_PRESSED), new EventDescriptor(KEY_EVENT_MASK,
-                KeyListener.class));
-        eventsMap.put(new Integer(KeyEvent.KEY_RELEASED), new EventDescriptor(KEY_EVENT_MASK,
-                KeyListener.class));
-        eventsMap.put(new Integer(MouseEvent.MOUSE_CLICKED), new EventDescriptor(MOUSE_EVENT_MASK,
-                MouseListener.class));
-        eventsMap.put(new Integer(MouseEvent.MOUSE_PRESSED), new EventDescriptor(MOUSE_EVENT_MASK,
-                MouseListener.class));
-        eventsMap.put(new Integer(MouseEvent.MOUSE_RELEASED), new EventDescriptor(MOUSE_EVENT_MASK,
-                MouseListener.class));
-        eventsMap.put(new Integer(MouseEvent.MOUSE_MOVED), new EventDescriptor(
-                MOUSE_MOTION_EVENT_MASK, MouseMotionListener.class));
-        eventsMap.put(new Integer(MouseEvent.MOUSE_ENTERED), new EventDescriptor(MOUSE_EVENT_MASK,
-                MouseListener.class));
-        eventsMap.put(new Integer(MouseEvent.MOUSE_EXITED), new EventDescriptor(MOUSE_EVENT_MASK,
-                MouseListener.class));
-        eventsMap.put(new Integer(MouseEvent.MOUSE_DRAGGED), new EventDescriptor(
-                MOUSE_MOTION_EVENT_MASK, MouseMotionListener.class));
-        eventsMap.put(new Integer(MouseEvent.MOUSE_WHEEL), new EventDescriptor(
-                MOUSE_WHEEL_EVENT_MASK, MouseWheelListener.class));
-        eventsMap.put(new Integer(ComponentEvent.COMPONENT_MOVED), new EventDescriptor(
-                COMPONENT_EVENT_MASK, ComponentListener.class));
-        eventsMap.put(new Integer(ComponentEvent.COMPONENT_RESIZED), new EventDescriptor(
-                COMPONENT_EVENT_MASK, ComponentListener.class));
-        eventsMap.put(new Integer(ComponentEvent.COMPONENT_SHOWN), new EventDescriptor(
-                COMPONENT_EVENT_MASK, ComponentListener.class));
-        eventsMap.put(new Integer(ComponentEvent.COMPONENT_HIDDEN), new EventDescriptor(
-                COMPONENT_EVENT_MASK, ComponentListener.class));
-        eventsMap.put(new Integer(FocusEvent.FOCUS_GAINED), new EventDescriptor(FOCUS_EVENT_MASK,
-                FocusListener.class));
-        eventsMap.put(new Integer(FocusEvent.FOCUS_LOST), new EventDescriptor(FOCUS_EVENT_MASK,
-                FocusListener.class));
-        eventsMap.put(new Integer(PaintEvent.PAINT), new EventDescriptor(PAINT_EVENT_MASK, null));
-        eventsMap.put(new Integer(PaintEvent.UPDATE), new EventDescriptor(PAINT_EVENT_MASK, null));
-        eventsMap.put(new Integer(WindowEvent.WINDOW_OPENED), new EventDescriptor(
-                WINDOW_EVENT_MASK, WindowListener.class));
-        eventsMap.put(new Integer(WindowEvent.WINDOW_CLOSING), new EventDescriptor(
-                WINDOW_EVENT_MASK, WindowListener.class));
-        eventsMap.put(new Integer(WindowEvent.WINDOW_CLOSED), new EventDescriptor(
-                WINDOW_EVENT_MASK, WindowListener.class));
-        eventsMap.put(new Integer(WindowEvent.WINDOW_DEICONIFIED), new EventDescriptor(
-                WINDOW_EVENT_MASK, WindowListener.class));
-        eventsMap.put(new Integer(WindowEvent.WINDOW_ICONIFIED), new EventDescriptor(
-                WINDOW_EVENT_MASK, WindowListener.class));
-        eventsMap.put(new Integer(WindowEvent.WINDOW_STATE_CHANGED), new EventDescriptor(
-                WINDOW_STATE_EVENT_MASK, WindowStateListener.class));
-        eventsMap.put(new Integer(WindowEvent.WINDOW_LOST_FOCUS), new EventDescriptor(
-                WINDOW_FOCUS_EVENT_MASK, WindowFocusListener.class));
-        eventsMap.put(new Integer(WindowEvent.WINDOW_GAINED_FOCUS), new EventDescriptor(
-                WINDOW_FOCUS_EVENT_MASK, WindowFocusListener.class));
-        eventsMap.put(new Integer(WindowEvent.WINDOW_DEACTIVATED), new EventDescriptor(
-                WINDOW_EVENT_MASK, WindowListener.class));
-        eventsMap.put(new Integer(WindowEvent.WINDOW_ACTIVATED), new EventDescriptor(
-                WINDOW_EVENT_MASK, WindowListener.class));
-        eventsMap.put(new Integer(HierarchyEvent.HIERARCHY_CHANGED), new EventDescriptor(
-                HIERARCHY_EVENT_MASK, HierarchyListener.class));
-        eventsMap.put(new Integer(HierarchyEvent.ANCESTOR_MOVED), new EventDescriptor(
-                HIERARCHY_BOUNDS_EVENT_MASK, HierarchyBoundsListener.class));
-        eventsMap.put(new Integer(HierarchyEvent.ANCESTOR_RESIZED), new EventDescriptor(
-                HIERARCHY_BOUNDS_EVENT_MASK, HierarchyBoundsListener.class));
-        eventsMap.put(new Integer(ContainerEvent.COMPONENT_ADDED), new EventDescriptor(
-                CONTAINER_EVENT_MASK, ContainerListener.class));
-        eventsMap.put(new Integer(ContainerEvent.COMPONENT_REMOVED), new EventDescriptor(
-                CONTAINER_EVENT_MASK, ContainerListener.class));
-        eventsMap.put(new Integer(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED), new EventDescriptor(
-                INPUT_METHOD_EVENT_MASK, InputMethodListener.class));
-        eventsMap.put(new Integer(InputMethodEvent.CARET_POSITION_CHANGED), new EventDescriptor(
-                INPUT_METHOD_EVENT_MASK, InputMethodListener.class));
-        eventsMap.put(new Integer(InvocationEvent.INVOCATION_DEFAULT), new EventDescriptor(
-                INVOCATION_EVENT_MASK, null));
-        eventsMap.put(new Integer(ItemEvent.ITEM_STATE_CHANGED), new EventDescriptor(
-                ITEM_EVENT_MASK, ItemListener.class));
-        eventsMap.put(new Integer(TextEvent.TEXT_VALUE_CHANGED), new EventDescriptor(
-                TEXT_EVENT_MASK, TextListener.class));
-        eventsMap.put(new Integer(ActionEvent.ACTION_PERFORMED), new EventDescriptor(
-                ACTION_EVENT_MASK, ActionListener.class));
-        eventsMap.put(new Integer(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED), new EventDescriptor(
-                ADJUSTMENT_EVENT_MASK, AdjustmentListener.class));
-        converter = new EventConverter();
-    }
-
-    /**
-     * Instantiates a new AWT event from the specified Event object.
-     * 
-     * @param event
-     *            the Event object.
-     */
-    public AWTEvent(Event event) {
-        this(event.target, event.id);
-    }
-
-    /**
-     * Instantiates a new AWT event with the specified object and type.
-     * 
-     * @param source
-     *            the source Object.
-     * @param id
-     *            the event's type.
-     */
-    public AWTEvent(Object source, int id) {
-        super(source);
-        this.id = id;
-        consumed = false;
-    }
-
-    /**
-     * Gets the event's type.
-     * 
-     * @return the event type ID.
-     */
-    public int getID() {
-        return id;
-    }
-
-    /**
-     * Sets a new source for the AWTEvent.
-     * 
-     * @param newSource
-     *            the new source Object for the AWTEvent.
-     */
-    public void setSource(Object newSource) {
-        source = newSource;
-    }
-
-    /**
-     * Returns a String representation of the AWTEvent.
-     * 
-     * @return the String representation of the AWTEvent.
-     */
-    @Override
-    public String toString() {
-        /*
-         * The format is based on 1.5 release behavior which can be revealed by
-         * the following code: AWTEvent event = new AWTEvent(new Component(){},
-         * 1){}; System.out.println(event);
-         */
-        String name = ""; //$NON-NLS-1$
-
-        if (source instanceof Component && (source != null)) {
-            Component comp = (Component)getSource();
-            name = comp.getName();
-            if (name == null) {
-                name = ""; //$NON-NLS-1$
-            }
-        }
-
-        return (getClass().getName() + "[" + paramString() + "]" //$NON-NLS-1$ //$NON-NLS-2$
-                + " on " + (name.length() > 0 ? name : source)); //$NON-NLS-1$
-    }
-
-    /**
-     * Returns a string representation of the AWTEvent state.
-     * 
-     * @return a string representation of the AWTEvent state.
-     */
-    public String paramString() {
-        // nothing to implement: all event types must override this method
-        return ""; //$NON-NLS-1$
-    }
-
-    /**
-     * Checks whether or not this AWTEvent has been consumed.
-     * 
-     * @return true, if this AWTEvent has been consumed, false otherwise.
-     */
-    protected boolean isConsumed() {
-        return consumed;
-    }
-
-    /**
-     * Consumes the AWTEvent.
-     */
-    protected void consume() {
-        consumed = true;
-    }
-
-    /**
-     * Convert AWTEvent object to a corresponding (deprecated) Event object.
-     * 
-     * @return new Event object which is a converted AWTEvent object or null if
-     *         the conversion is not possible
-     */
-    Event getEvent() {
-
-        if (id == ActionEvent.ACTION_PERFORMED) {
-            ActionEvent ae = (ActionEvent)this;
-            return converter.convertActionEvent(ae);
-
-        } else if (id == AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED) {
-            AdjustmentEvent ae = (AdjustmentEvent)this;
-            return converter.convertAdjustmentEvent(ae);
-
-            // ???AWT
-            // } else if (id == ComponentEvent.COMPONENT_MOVED
-            // && source instanceof Window) {
-            // //the only type of Component events is COMPONENT_MOVED on window
-            // ComponentEvent ce = (ComponentEvent) this;
-            // return converter.convertComponentEvent(ce);
-
-        } else if (id >= FocusEvent.FOCUS_FIRST && id <= FocusEvent.FOCUS_LAST) {
-            // nothing to convert
-
-            // ???AWT
-            // } else if (id == ItemEvent.ITEM_STATE_CHANGED) {
-            // ItemEvent ie = (ItemEvent) this;
-            // return converter.convertItemEvent(ie);
-
-        } else if (id == KeyEvent.KEY_PRESSED || id == KeyEvent.KEY_RELEASED) {
-            KeyEvent ke = (KeyEvent)this;
-            return converter.convertKeyEvent(ke);
-        } else if (id >= MouseEvent.MOUSE_FIRST && id <= MouseEvent.MOUSE_LAST) {
-            MouseEvent me = (MouseEvent)this;
-            return converter.convertMouseEvent(me);
-        } else if (id == WindowEvent.WINDOW_CLOSING || id == WindowEvent.WINDOW_ICONIFIED
-                || id == WindowEvent.WINDOW_DEICONIFIED) {
-            // nothing to convert
-        } else {
-            return null;
-        }
-        return new Event(source, id, null);
-    }
-
-    /**
-     * The class EventDescriptor.
-     */
-    static final class EventDescriptor {
-
-        /**
-         * The event mask.
-         */
-        final long eventMask;
-
-        /**
-         * The listener type.
-         */
-        final Class<? extends EventListener> listenerType;
-
-        /**
-         * Instantiates a new event descriptor.
-         * 
-         * @param eventMask
-         *            the event mask.
-         * @param listenerType
-         *            the listener type.
-         */
-        EventDescriptor(long eventMask, Class<? extends EventListener> listenerType) {
-            this.eventMask = eventMask;
-            this.listenerType = listenerType;
-        }
-
-    }
-
-    /**
-     * The class EventTypeLookup.
-     */
-    static final class EventTypeLookup {
-
-        /**
-         * The last event.
-         */
-        private AWTEvent lastEvent = null;
-
-        /**
-         * The last event descriptor.
-         */
-        private EventDescriptor lastEventDescriptor = null;
-
-        /**
-         * Gets the event descriptor.
-         * 
-         * @param event
-         *            the event.
-         * @return the event descriptor.
-         */
-        EventDescriptor getEventDescriptor(AWTEvent event) {
-            synchronized (this) {
-                if (event != lastEvent) {
-                    lastEvent = event;
-                    lastEventDescriptor = eventsMap.get(new Integer(event.id));
-                }
-
-                return lastEventDescriptor;
-            }
-        }
-
-        /**
-         * Gets the event mask.
-         * 
-         * @param event
-         *            the event.
-         * @return the event mask.
-         */
-        long getEventMask(AWTEvent event) {
-            final EventDescriptor ed = getEventDescriptor(event);
-            return ed == null ? -1 : ed.eventMask;
-        }
-    }
-
-    /**
-     * The class EventConverter.
-     */
-    static final class EventConverter {
-
-        /**
-         * The constant OLD_MOD_MASK.
-         */
-        static final int OLD_MOD_MASK = Event.ALT_MASK | Event.CTRL_MASK | Event.META_MASK
-                | Event.SHIFT_MASK;
-
-        /**
-         * Convert action event.
-         * 
-         * @param ae
-         *            the ae.
-         * @return the event.
-         */
-        Event convertActionEvent(ActionEvent ae) {
-            Event evt = new Event(ae.getSource(), ae.getID(), ae.getActionCommand());
-            evt.when = ae.getWhen();
-            evt.modifiers = ae.getModifiers() & OLD_MOD_MASK;
-
-            /*
-             * if (source instanceof Button) { arg = ((Button)
-             * source).getLabel(); } else if (source instanceof Checkbox) { arg
-             * = new Boolean(((Checkbox) source).getState()); } else if (source
-             * instanceof CheckboxMenuItem) { arg = ((CheckboxMenuItem)
-             * source).getLabel(); } else if (source instanceof Choice) { arg =
-             * ((Choice) source).getSelectedItem(); } else if (source instanceof
-             * List) { arg = ((List) source).getSelectedItem(); } else if
-             * (source instanceof MenuItem) { arg = ((MenuItem)
-             * source).getLabel(); } else if (source instanceof TextField) { arg
-             * = ((TextField) source).getText(); }
-             */
-            return evt;
-        }
-
-        /**
-         * Convert adjustment event.
-         * 
-         * @param ae
-         *            the ae.
-         * @return the event.
-         */
-        Event convertAdjustmentEvent(AdjustmentEvent ae) {
-            // TODO: Event.SCROLL_BEGIN/SCROLL_END
-            return new Event(ae.source, ae.id + ae.getAdjustmentType() - 1, new Integer(ae
-                    .getValue()));
-        }
-
-        /**
-         * Convert component event.
-         * 
-         * @param ce
-         *            the ce.
-         * @return the event.
-         */
-        Event convertComponentEvent(ComponentEvent ce) {
-            Component comp = ce.getComponent();
-            Event evt = new Event(comp, Event.WINDOW_MOVED, null);
-            evt.x = comp.getX();
-            evt.y = comp.getY();
-            return evt;
-        }
-
-        // ???AWT
-        /*
-         * Event convertItemEvent(ItemEvent ie) { int oldId = ie.id +
-         * ie.getStateChange() - 1; Object source = ie.source; int idx = -1; if
-         * (source instanceof List) { List list = (List) source; idx =
-         * list.getSelectedIndex(); } else if (source instanceof Choice) {
-         * Choice choice = (Choice) source; idx = choice.getSelectedIndex(); }
-         * Object arg = idx >= 0 ? new Integer(idx) : null; return new
-         * Event(source, oldId, arg); }
-         */
-
-        /**
-         * Convert key event.
-         * 
-         * @param ke
-         *            the ke.
-         * @return the event.
-         */
-        Event convertKeyEvent(KeyEvent ke) {
-            int oldId = ke.id;
-            // leave only old Event's modifiers
-
-            int mod = ke.getModifiers() & OLD_MOD_MASK;
-            Component comp = ke.getComponent();
-            char keyChar = ke.getKeyChar();
-            int keyCode = ke.getKeyCode();
-            int key = convertKey(keyChar, keyCode);
-            if (key >= Event.HOME && key <= Event.INSERT) {
-                oldId += 2; // non-ASCII key -> action key
-            }
-            return new Event(comp, ke.getWhen(), oldId, 0, 0, key, mod);
-        }
-
-        /**
-         * Convert mouse event.
-         * 
-         * @param me
-         *            the me.
-         * @return the event.
-         */
-        Event convertMouseEvent(MouseEvent me) {
-            int id = me.id;
-            if (id != MouseEvent.MOUSE_CLICKED) {
-                Event evt = new Event(me.source, id, null);
-                evt.x = me.getX();
-                evt.y = me.getY();
-                int mod = me.getModifiers();
-                // in Event modifiers mean button number for mouse events:
-                evt.modifiers = mod & (Event.ALT_MASK | Event.META_MASK);
-                if (id == MouseEvent.MOUSE_PRESSED) {
-                    evt.clickCount = me.getClickCount();
-                }
-                return evt;
-            }
-            return null;
-        }
-
-        /**
-         * Convert key.
-         * 
-         * @param keyChar
-         *            the key char.
-         * @param keyCode
-         *            the key code.
-         * @return the int.
-         */
-        int convertKey(char keyChar, int keyCode) {
-            int key;
-            // F1 - F12
-            if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) {
-                key = Event.F1 + keyCode - KeyEvent.VK_F1;
-            } else {
-                switch (keyCode) {
-                    default: // non-action key
-                        key = keyChar;
-                        break;
-                    // action keys:
-                    case KeyEvent.VK_HOME:
-                        key = Event.HOME;
-                        break;
-                    case KeyEvent.VK_END:
-                        key = Event.END;
-                        break;
-                    case KeyEvent.VK_PAGE_UP:
-                        key = Event.PGUP;
-                        break;
-                    case KeyEvent.VK_PAGE_DOWN:
-                        key = Event.PGDN;
-                        break;
-                    case KeyEvent.VK_UP:
-                        key = Event.UP;
-                        break;
-                    case KeyEvent.VK_DOWN:
-                        key = Event.DOWN;
-                        break;
-                    case KeyEvent.VK_LEFT:
-                        key = Event.LEFT;
-                        break;
-                    case KeyEvent.VK_RIGHT:
-                        key = Event.RIGHT;
-                        break;
-                    case KeyEvent.VK_PRINTSCREEN:
-                        key = Event.PRINT_SCREEN;
-                        break;
-                    case KeyEvent.VK_SCROLL_LOCK:
-                        key = Event.SCROLL_LOCK;
-                        break;
-                    case KeyEvent.VK_CAPS_LOCK:
-                        key = Event.CAPS_LOCK;
-                        break;
-                    case KeyEvent.VK_NUM_LOCK:
-                        key = Event.NUM_LOCK;
-                        break;
-                    case KeyEvent.VK_PAUSE:
-                        key = Event.PAUSE;
-                        break;
-                    case KeyEvent.VK_INSERT:
-                        key = Event.INSERT;
-                        break;
-                }
-            }
-            return key;
-        }
-
-    }
-
-}
diff --git a/awt/java/awt/AWTException.java b/awt/java/awt/AWTException.java
deleted file mode 100644
index 6590b73..0000000
--- a/awt/java/awt/AWTException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * The AWTException class is used to provide notification and information about
- * AWT errors.
- * 
- * @since Android 1.0
- */
-public class AWTException extends Exception {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -1900414231151323879L;
-
-    /**
-     * Instantiates a new AWT exception with the specified message.
-     * 
-     * @param msg
-     *            the specific message for current exception.
-     */
-    public AWTException(String msg) {
-        super(msg);
-    }
-
-}
diff --git a/awt/java/awt/AWTKeyStroke.java b/awt/java/awt/AWTKeyStroke.java
deleted file mode 100644
index f01f6f0..0000000
--- a/awt/java/awt/AWTKeyStroke.java
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The AWTKeyStroke holds all of the information for the complete act of 
- * typing a character. This includes the events that are generated when 
- * the key is pressed, released, or typed (pressed and released generating
- * a Unicode character result) which are associated with the event
- * objects KeyEvent.KEY_PRESSED, KeyEvent.KEY_RELEASED, or KeyEvent.KEY_TYPED.
- * It also holds information about which modifiers (such as control or 
- * shift) were used in conjunction with the keystroke. The following masks 
- * are available to identify the modifiers:
- * <ul>
- * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
- * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
- * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
- * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
- * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
- * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
- * <li>java.awt.event.InputEvent.ALT_MASK</li>
- * <li>java.awt.event.InputEvent.CTRL_MASK</li>
- * <li>java.awt.event.InputEvent.META_MASK</li>  
- * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
- * </ul>  
- * <br>
- *  The AWTKeyStroke is unique, and applications should not create their own 
- *  instances of AWTKeyStroke. All applications should use getAWTKeyStroke 
- *  methods for obtaining instances of AWTKeyStroke.
- *  
- *  @since Android 1.0
- */
-public class AWTKeyStroke implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -6430539691155161871L;
-
-    /**
-     * The Constant cache.
-     */
-    private static final Map<AWTKeyStroke, AWTKeyStroke> cache = new HashMap<AWTKeyStroke, AWTKeyStroke>(); // Map
-
-    // <
-    // AWTKeyStroke
-    // ,
-    // ?
-    // extends
-    // AWTKeyStroke
-    // >
-
-    /**
-     * The Constant keyEventTypesMap.
-     */
-    private static final Map<Integer, String> keyEventTypesMap = new HashMap<Integer, String>(); // Map
-
-    // <
-    // int
-    // ,
-    // String
-    // >
-
-    private static Constructor<?> subConstructor;
-
-    static {
-        keyEventTypesMap.put(new Integer(KeyEvent.KEY_PRESSED), "pressed"); //$NON-NLS-1$
-        keyEventTypesMap.put(new Integer(KeyEvent.KEY_RELEASED), "released"); //$NON-NLS-1$
-        keyEventTypesMap.put(new Integer(KeyEvent.KEY_TYPED), "typed"); //$NON-NLS-1$
-    }
-
-    /**
-     * The key char.
-     */
-    private char keyChar;
-
-    /**
-     * The key code.
-     */
-    private int keyCode;
-
-    /**
-     * The modifiers.
-     */
-    private int modifiers;
-
-    /**
-     * The on key release.
-     */
-    private boolean onKeyRelease;
-
-    /**
-     * Instantiates a new AWTKeyStroke. getAWTKeyStroke method should be used by
-     * applications code.
-     * 
-     * @param keyChar
-     *            the key char.
-     * @param keyCode
-     *            the key code.
-     * @param modifiers
-     *            the modifiers.
-     * @param onKeyRelease
-     *            true if AWTKeyStroke is for a key release, false otherwise.
-     */
-    protected AWTKeyStroke(char keyChar, int keyCode, int modifiers, boolean onKeyRelease) {
-        setAWTKeyStroke(keyChar, keyCode, modifiers, onKeyRelease);
-    }
-
-    /**
-     * Sets the AWT key stroke.
-     * 
-     * @param keyChar
-     *            the key char.
-     * @param keyCode
-     *            the key code.
-     * @param modifiers
-     *            the modifiers.
-     * @param onKeyRelease
-     *            the on key release.
-     */
-    private void setAWTKeyStroke(char keyChar, int keyCode, int modifiers, boolean onKeyRelease) {
-        this.keyChar = keyChar;
-        this.keyCode = keyCode;
-        this.modifiers = modifiers;
-        this.onKeyRelease = onKeyRelease;
-    }
-
-    /**
-     * Instantiates a new AWTKeyStroke with default parameters:
-     * KeyEvent.CHAR_UNDEFINED key char, KeyEvent.VK_UNDEFINED key code, without
-     * modifiers and false key realized value.
-     */
-    protected AWTKeyStroke() {
-        this(KeyEvent.CHAR_UNDEFINED, KeyEvent.VK_UNDEFINED, 0, false);
-    }
-
-    /**
-     * Returns the unique number value for AWTKeyStroke object.
-     * 
-     * @return the integer unique value of the AWTKeyStroke object.
-     */
-    @Override
-    public int hashCode() {
-        return modifiers + (keyCode != KeyEvent.VK_UNDEFINED ? keyCode : keyChar)
-                + (onKeyRelease ? -1 : 0);
-    }
-
-    /**
-     * Gets the set of modifiers for the AWTKeyStroke object.
-     * 
-     * @return the integer value which contains modifiers.
-     */
-    public final int getModifiers() {
-        return modifiers;
-    }
-
-    /**
-     * Compares this AWTKeyStroke object to the specified object.
-     * 
-     * @param anObject
-     *            the specified AWTKeyStroke object to compare with this
-     *            instance.
-     * @return true if objects are identical, false otherwise.
-     */
-    @Override
-    public final boolean equals(Object anObject) {
-        if (anObject instanceof AWTKeyStroke) {
-            AWTKeyStroke key = (AWTKeyStroke)anObject;
-            return ((key.keyCode == keyCode) && (key.keyChar == keyChar)
-                    && (key.modifiers == modifiers) && (key.onKeyRelease == onKeyRelease));
-        }
-        return false;
-    }
-
-    /**
-     * Returns the string representation of the AWTKeyStroke. This string should
-     * contain key stroke properties.
-     * 
-     * @return the string representation of the AWTKeyStroke.
-     */
-    @Override
-    public String toString() {
-        int type = getKeyEventType();
-        return InputEvent.getModifiersExText(getModifiers()) + " " + //$NON-NLS-1$
-                keyEventTypesMap.get(new Integer(type)) + " " + //$NON-NLS-1$
-                (type == KeyEvent.KEY_TYPED ? new String(new char[] {
-                    keyChar
-                }) : KeyEvent.getKeyText(keyCode));
-    }
-
-    /**
-     * Gets the key code for the AWTKeyStroke object.
-     * 
-     * @return the key code for the AWTKeyStroke object.
-     */
-    public final int getKeyCode() {
-        return keyCode;
-    }
-
-    /**
-     * Gets the key character for the AWTKeyStroke object.
-     * 
-     * @return the key character for the AWTKeyStroke object.
-     */
-    public final char getKeyChar() {
-        return keyChar;
-    }
-
-    /**
-     * Gets the AWT key stroke.
-     * 
-     * @param keyChar
-     *            the key char.
-     * @param keyCode
-     *            the key code.
-     * @param modifiers
-     *            the modifiers.
-     * @param onKeyRelease
-     *            the on key release.
-     * @return the AWT key stroke.
-     */
-    private static AWTKeyStroke getAWTKeyStroke(char keyChar, int keyCode, int modifiers,
-            boolean onKeyRelease) {
-        AWTKeyStroke key = newInstance(keyChar, keyCode, modifiers, onKeyRelease);
-
-        AWTKeyStroke value = cache.get(key);
-        if (value == null) {
-            value = key;
-            cache.put(key, value);
-        }
-        return value;
-    }
-
-    /**
-     * New instance.
-     * 
-     * @param keyChar
-     *            the key char.
-     * @param keyCode
-     *            the key code.
-     * @param modifiers
-     *            the modifiers.
-     * @param onKeyRelease
-     *            the on key release.
-     * @return the AWT key stroke.
-     */
-    private static AWTKeyStroke newInstance(char keyChar, int keyCode, int modifiers,
-            boolean onKeyRelease) {
-        AWTKeyStroke key;
-        // ???AWT
-        // if (subConstructor == null) {
-        key = new AWTKeyStroke();
-        // ???AWT
-        // } else {
-        // try {
-        // key = (AWTKeyStroke) subConstructor.newInstance();
-        // } catch (Exception e) {
-        // throw new RuntimeException(e);
-        // }
-        // }
-        int allModifiers = getAllModifiers(modifiers);
-        key.setAWTKeyStroke(keyChar, keyCode, allModifiers, onKeyRelease);
-        return key;
-    }
-
-    /**
-     * Adds the mask.
-     * 
-     * @param mod
-     *            the mod.
-     * @param mask
-     *            the mask.
-     * @return the int.
-     */
-    private static int addMask(int mod, int mask) {
-        return ((mod & mask) != 0) ? (mod | mask) : mod;
-    }
-
-    /**
-     * Return all (old & new) modifiers corresponding to.
-     * 
-     * @param mod
-     *            old or new modifiers.
-     * @return old and new modifiers together.
-     */
-    static int getAllModifiers(int mod) {
-        int allMod = mod;
-        int shift = (InputEvent.SHIFT_MASK | InputEvent.SHIFT_DOWN_MASK);
-        int ctrl = (InputEvent.CTRL_MASK | InputEvent.CTRL_DOWN_MASK);
-        int meta = (InputEvent.META_MASK | InputEvent.META_DOWN_MASK);
-        int alt = (InputEvent.ALT_MASK | InputEvent.ALT_DOWN_MASK);
-        int altGr = (InputEvent.ALT_GRAPH_MASK | InputEvent.ALT_GRAPH_DOWN_MASK);
-        // button modifiers are not converted between old & new
-
-        allMod = addMask(allMod, shift);
-        allMod = addMask(allMod, ctrl);
-        allMod = addMask(allMod, meta);
-        allMod = addMask(allMod, alt);
-        allMod = addMask(allMod, altGr);
-
-        return allMod;
-    }
-
-    /**
-     * Returns an instance of AWTKeyStroke for parsed string. The string must
-     * have the following syntax:
-     *<p>
-     * &lt;modifiers&gt;* (&lt;typedID&gt; | &lt;pressedReleasedID&gt;)
-     *<p>
-     * modifiers := shift | control | ctrl | meta | alt | altGraph <br>
-     * typedID := typed <typedKey> <br>
-     * typedKey := string of length 1 giving the Unicode character. <br>
-     * pressedReleasedID := (pressed | released) <key> <br>
-     * key := KeyEvent key code name, i.e. the name following "VK_".
-     * <p>
-     * 
-     * @param s
-     *            the String which contains key stroke parameters.
-     * @return the AWTKeyStroke for string.
-     * @throws IllegalArgumentException
-     *             if string has incorrect format or null.
-     */
-    public static AWTKeyStroke getAWTKeyStroke(String s) {
-        if (s == null) {
-            // awt.65=null argument
-            throw new IllegalArgumentException(Messages.getString("awt.65")); //$NON-NLS-1$
-        }
-
-        StringTokenizer tokenizer = new StringTokenizer(s);
-
-        Boolean release = null;
-        int modifiers = 0;
-        int keyCode = KeyEvent.VK_UNDEFINED;
-        char keyChar = KeyEvent.CHAR_UNDEFINED;
-        boolean typed = false;
-        long modifier = 0;
-        String token = null;
-        do {
-            token = getNextToken(tokenizer);
-            modifier = parseModifier(token);
-            modifiers |= modifier;
-        } while (modifier > 0);
-
-        typed = parseTypedID(token);
-
-        if (typed) {
-            token = getNextToken(tokenizer);
-            keyChar = parseTypedKey(token);
-
-        }
-        if (keyChar == KeyEvent.CHAR_UNDEFINED) {
-            release = parsePressedReleasedID(token);
-            if (release != null) {
-                token = getNextToken(tokenizer);
-            }
-            keyCode = parseKey(token);
-        }
-        if (tokenizer.hasMoreTokens()) {
-            // awt.66=Invalid format
-            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
-        }
-
-        return getAWTKeyStroke(keyChar, keyCode, modifiers, release == Boolean.TRUE);
-    }
-
-    /**
-     * Gets the next token.
-     * 
-     * @param tokenizer
-     *            the tokenizer.
-     * @return the next token.
-     */
-    private static String getNextToken(StringTokenizer tokenizer) {
-        try {
-            return tokenizer.nextToken();
-        } catch (NoSuchElementException exception) {
-            // awt.66=Invalid format
-            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Gets the key code.
-     * 
-     * @param s
-     *            the s.
-     * @return the key code.
-     */
-    static int getKeyCode(String s) {
-        try {
-            Field vk = KeyEvent.class.getField("VK_" + s); //$NON-NLS-1$
-            return vk.getInt(null);
-        } catch (Exception e) {
-            if (s.length() != 1) {
-                // awt.66=Invalid format
-                throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
-            }
-            return KeyEvent.VK_UNDEFINED;
-        }
-    }
-
-    /**
-     * Gets an instance of the AWTKeyStroke for specified character.
-     * 
-     * @param keyChar
-     *            the keyboard character value.
-     * @return a AWTKeyStroke for specified character.
-     */
-    public static AWTKeyStroke getAWTKeyStroke(char keyChar) {
-        return getAWTKeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false);
-    }
-
-    /**
-     * Returns an instance of AWTKeyStroke for a given key code, set of
-     * modifiers, and specified key released flag value. The key codes are
-     * defined in java.awt.event.KeyEvent class. The set of modifiers is given
-     * as a bitwise combination of masks taken from the following list:
-     * <ul>
-     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.ALT_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.CTRL_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.META_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.SHIFT_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.ALT_GRAPH_MASK</li> <li>
-     * java.awt.event.InputEvent.ALT_MASK</li> <li>
-     * java.awt.event.InputEvent.CTRL_MASK</li> <li>
-     * java.awt.event.InputEvent.META_MASK</li> <li>
-     * java.awt.event.InputEvent.SHIFT_MASK</li>
-     * </ul>
-     * <br>
-     * 
-     * @param keyCode
-     *            the specified key code of keyboard.
-     * @param modifiers
-     *            the bit set of modifiers.
-     * @param onKeyRelease
-     *            the value which represents whether this AWTKeyStroke shall
-     *            represents a key release.
-     * @return the AWTKeyStroke.
-     */
-    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers, boolean onKeyRelease) {
-        return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers, onKeyRelease);
-    }
-
-    /**
-     * Returns AWTKeyStroke for a specified character and set of modifiers. The
-     * set of modifiers is given as a bitwise combination of masks taken from
-     * the following list:
-     * <ul>
-     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.ALT_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.CTRL_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.META_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.SHIFT_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.ALT_GRAPH_MASK</li> <li>
-     * java.awt.event.InputEvent.ALT_MASK</li> <li>
-     * java.awt.event.InputEvent.CTRL_MASK</li> <li>
-     * java.awt.event.InputEvent.META_MASK</li> <li>
-     * java.awt.event.InputEvent.SHIFT_MASK</li>
-     * </ul>
-     * 
-     * @param keyChar
-     *            the Character object which represents keyboard character
-     *            value.
-     * @param modifiers
-     *            the bit set of modifiers.
-     * @return the AWTKeyStroke object.
-     * @throws IllegalArgumentException
-     *             if keyChar value is null.
-     */
-    public static AWTKeyStroke getAWTKeyStroke(Character keyChar, int modifiers) {
-        if (keyChar == null) {
-            // awt.01='{0}' parameter is null
-            throw new IllegalArgumentException(Messages.getString("awt.01", "keyChar")); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        return getAWTKeyStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED, modifiers, false);
-    }
-
-    /**
-     * Returns an instance of AWTKeyStroke for a specified key code and set of
-     * modifiers. The key codes are defined in java.awt.event.KeyEvent class.
-     * The set of modifiers is given as a bitwise combination of masks taken
-     * from the following list:
-     * <ul>
-     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.ALT_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.CTRL_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.META_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.SHIFT_DOWN_MASK</li> <li>
-     * java.awt.event.InputEvent.ALT_GRAPH_MASK</li> <li>
-     * java.awt.event.InputEvent.ALT_MASK</li> <li>
-     * java.awt.event.InputEvent.CTRL_MASK</li> <li>
-     * java.awt.event.InputEvent.META_MASK</li> <li>
-     * java.awt.event.InputEvent.SHIFT_MASK</li>
-     * </ul>
-     * 
-     * @param keyCode
-     *            the specified key code of keyboard.
-     * @param modifiers
-     *            the bit set of modifiers.
-     * @return the AWTKeyStroke.
-     */
-    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers) {
-        return getAWTKeyStroke(keyCode, modifiers, false);
-    }
-
-    /**
-     * Gets the AWTKeyStroke for a key event. This method obtains the key char
-     * and key code from the specified key event.
-     * 
-     * @param anEvent
-     *            the key event which identifies the desired AWTKeyStroke.
-     * @return the AWTKeyStroke for the key event.
-     */
-    public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent anEvent) {
-        int id = anEvent.getID();
-        char undef = KeyEvent.CHAR_UNDEFINED;
-        char keyChar = (id == KeyEvent.KEY_TYPED ? anEvent.getKeyChar() : undef);
-        int keyCode = (keyChar == undef ? anEvent.getKeyCode() : KeyEvent.VK_UNDEFINED);
-        return getAWTKeyStroke(keyChar, keyCode, anEvent.getModifiersEx(),
-                id == KeyEvent.KEY_RELEASED);
-    }
-
-    /**
-     * Gets the key event type for the AWTKeyStroke object.
-     * 
-     * @return the key event type: KeyEvent.KEY_PRESSED, KeyEvent.KEY_TYPED, or
-     *         KeyEvent.KEY_RELEASED.
-     */
-    public final int getKeyEventType() {
-        if (keyCode == KeyEvent.VK_UNDEFINED) {
-            return KeyEvent.KEY_TYPED;
-        }
-        return (onKeyRelease ? KeyEvent.KEY_RELEASED : KeyEvent.KEY_PRESSED);
-    }
-
-    /**
-     * Returns true if the key event is associated with the AWTKeyStroke is
-     * KEY_RELEASED, false otherwise.
-     * 
-     * @return true, if if the key event associated with the AWTKeyStroke is
-     *         KEY_RELEASED, false otherwise.
-     */
-    public final boolean isOnKeyRelease() {
-        return onKeyRelease;
-    }
-
-    /**
-     * Read resolve.
-     * 
-     * @return the object.
-     * @throws ObjectStreamException
-     *             the object stream exception.
-     */
-    protected Object readResolve() throws ObjectStreamException {
-        return getAWTKeyStroke(this.keyChar, this.keyCode, this.modifiers, this.onKeyRelease);
-    }
-
-    /**
-     * Register subclass.
-     * 
-     * @param subclass
-     *            the subclass.
-     */
-    protected static void registerSubclass(Class<?> subclass) {
-        // ???AWT
-        /*
-         * if (subclass == null) { // awt.01='{0}' parameter is null throw new
-         * IllegalArgumentException(Messages.getString("awt.01", "subclass"));
-         * //$NON-NLS-1$ //$NON-NLS-2$ } if (!
-         * AWTKeyStroke.class.isAssignableFrom(subclass)) { // awt.67=subclass
-         * is not derived from AWTKeyStroke throw new
-         * ClassCastException(Messages.getString("awt.67")); //$NON-NLS-1$ } try
-         * { subConstructor = subclass.getDeclaredConstructor();
-         * subConstructor.setAccessible(true); } catch (SecurityException e) {
-         * throw new RuntimeException(e); } catch (NoSuchMethodException e) { //
-         * awt.68=subclass could not be instantiated throw new
-         * IllegalArgumentException(Messages.getString("awt.68")); //$NON-NLS-1$
-         * } cache.clear(); //flush the cache
-         */
-    }
-
-    /**
-     * Parses the modifier.
-     * 
-     * @param strMod
-     *            the str mod.
-     * @return the long.
-     */
-    private static long parseModifier(String strMod) {
-        long modifiers = 0l;
-        if (strMod.equals("shift")) { //$NON-NLS-1$
-            modifiers |= InputEvent.SHIFT_DOWN_MASK;
-        } else if (strMod.equals("control") || strMod.equals("ctrl")) { //$NON-NLS-1$ //$NON-NLS-2$
-            modifiers |= InputEvent.CTRL_DOWN_MASK;
-        } else if (strMod.equals("meta")) { //$NON-NLS-1$
-            modifiers |= InputEvent.META_DOWN_MASK;
-        } else if (strMod.equals("alt")) { //$NON-NLS-1$
-            modifiers |= InputEvent.ALT_DOWN_MASK;
-        } else if (strMod.equals("altGraph")) { //$NON-NLS-1$
-            modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
-        } else if (strMod.equals("button1")) { //$NON-NLS-1$
-            modifiers |= InputEvent.BUTTON1_DOWN_MASK;
-        } else if (strMod.equals("button2")) { //$NON-NLS-1$
-            modifiers |= InputEvent.BUTTON2_DOWN_MASK;
-        } else if (strMod.equals("button3")) { //$NON-NLS-1$
-            modifiers |= InputEvent.BUTTON3_DOWN_MASK;
-        }
-        return modifiers;
-    }
-
-    /**
-     * Parses the typed id.
-     * 
-     * @param strTyped
-     *            the str typed.
-     * @return true, if successful.
-     */
-    private static boolean parseTypedID(String strTyped) {
-        if (strTyped.equals("typed")) { //$NON-NLS-1$
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parses the typed key.
-     * 
-     * @param strChar
-     *            the str char.
-     * @return the char.
-     */
-    private static char parseTypedKey(String strChar) {
-        char keyChar = KeyEvent.CHAR_UNDEFINED;
-
-        if (strChar.length() != 1) {
-            // awt.66=Invalid format
-            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
-        }
-        keyChar = strChar.charAt(0);
-        return keyChar;
-    }
-
-    /**
-     * Parses the pressed released id.
-     * 
-     * @param str
-     *            the str.
-     * @return the boolean.
-     */
-    private static Boolean parsePressedReleasedID(String str) {
-
-        if (str.equals("pressed")) { //$NON-NLS-1$
-            return Boolean.FALSE;
-        } else if (str.equals("released")) { //$NON-NLS-1$
-            return Boolean.TRUE;
-        }
-        return null;
-    }
-
-    /**
-     * Parses the key.
-     * 
-     * @param strCode
-     *            the str code.
-     * @return the int.
-     */
-    private static int parseKey(String strCode) {
-        int keyCode = KeyEvent.VK_UNDEFINED;
-
-        keyCode = getKeyCode(strCode);
-
-        if (keyCode == KeyEvent.VK_UNDEFINED) {
-            // awt.66=Invalid format
-            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
-        }
-        return keyCode;
-    }
-}
diff --git a/awt/java/awt/AWTListenerList.java b/awt/java/awt/AWTListenerList.java
deleted file mode 100644
index 3327d63..0000000
--- a/awt/java/awt/AWTListenerList.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.awt;
-
-import java.util.EventListener;
-
-import org.apache.harmony.awt.ListenerList;
-
-final class AWTListenerList<T extends EventListener> extends ListenerList<T> {
-    private static final long serialVersionUID = -2622077171532840953L;
-
-    private final Component owner;
-    
-    AWTListenerList() {
-        super();
-        this.owner = null;
-    }
-
-    AWTListenerList(Component owner) {
-        super();
-        this.owner = owner;
-    }
-
-    @Override
-    public void addUserListener(T listener) {
-        super.addUserListener(listener);
-
-        if (owner != null) {
-            owner.deprecatedEventHandler = false;
-        }
-    }
-}
diff --git a/awt/java/awt/AWTPermission.java b/awt/java/awt/AWTPermission.java
deleted file mode 100644
index 4bd8357..0000000
--- a/awt/java/awt/AWTPermission.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.security.BasicPermission;
-
-/**
- * The AWTPermission specifies the name of the permission and the corresponding
- * action list.
- * 
- * @since Android 1.0
- */
-public final class AWTPermission extends BasicPermission {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 8890392402588814465L;
-
-    /**
-     * Instantiates a new AWTPermission with defined name and actions.
-     * 
-     * @param name
-     *            the name of a new AWTPermission.
-     * @param actions
-     *            the actions of a new AWTPermission.
-     */
-    public AWTPermission(String name, String actions) {
-        super(name, actions);
-    }
-
-    /**
-     * Instantiates a new AWT permission with the defined name.
-     * 
-     * @param name
-     *            the name of a new AWTPermission.
-     */
-    public AWTPermission(String name) {
-        super(name);
-    }
-
-}
diff --git a/awt/java/awt/ActiveEvent.java b/awt/java/awt/ActiveEvent.java
deleted file mode 100644
index 7044623..0000000
--- a/awt/java/awt/ActiveEvent.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * This interface defines events that know how to dispatch themselves. Such
- * event can be placed upon the event queue and its dispatch method will be
- * called when the event is dispatched.
- * 
- * @since Android 1.0
- */
-public interface ActiveEvent {
-
-    /**
-     * Dispatches the event to the listeners of the event's source, or does
-     * whatever it is this event is supposed to do.
-     */
-    public void dispatch();
-
-}
diff --git a/awt/java/awt/Adjustable.java b/awt/java/awt/Adjustable.java
deleted file mode 100644
index baf80f7..0000000
--- a/awt/java/awt/Adjustable.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.event.AdjustmentListener;
-
-/**
- * The Adjustable interface represents an adjustable numeric value contained
- * within a bounded range of values, such as the current location in scrollable
- * region or the value of a gauge.
- * 
- * @since Android 1.0
- */
-public interface Adjustable {
-
-    /**
-     * The Constant HORIZONTAL indicates that the Adjustable's orientation is
-     * horizontal.
-     */
-    public static final int HORIZONTAL = 0;
-
-    /**
-     * The Constant VERTICAL indicates that the Adjustable's orientation is
-     * vertical.
-     */
-    public static final int VERTICAL = 1;
-
-    /**
-     * The Constant NO_ORIENTATION indicates that the Adjustable has no
-     * orientation.
-     */
-    public static final int NO_ORIENTATION = 2;
-
-    /**
-     * Gets the value of the Adjustable.
-     * 
-     * @return the current value of the Adjustable.
-     */
-    public int getValue();
-
-    /**
-     * Sets the value to the Adjustable object.
-     * 
-     * @param a0
-     *            the new value of the Adjustable object.
-     */
-    public void setValue(int a0);
-
-    /**
-     * Adds the AdjustmentListener to current Adjustment.
-     * 
-     * @param a0
-     *            the AdjustmentListener object.
-     */
-    public void addAdjustmentListener(AdjustmentListener a0);
-
-    /**
-     * Gets the block increment of the Adjustable.
-     * 
-     * @return the block increment of the Adjustable.
-     */
-    public int getBlockIncrement();
-
-    /**
-     * Gets the maximum value of the Adjustable.
-     * 
-     * @return the maximum value of the Adjustable.
-     */
-    public int getMaximum();
-
-    /**
-     * Gets the minimum value of the Adjustable.
-     * 
-     * @return the minimum value of the Adjustable.
-     */
-    public int getMinimum();
-
-    /**
-     * Gets the orientation of the Adjustable.
-     * 
-     * @return the orientation of the Adjustable.
-     */
-    public int getOrientation();
-
-    /**
-     * Gets the unit increment of the Adjustable.
-     * 
-     * @return the unit increment of the Adjustable.
-     */
-    public int getUnitIncrement();
-
-    /**
-     * Gets the visible amount of the Adjustable.
-     * 
-     * @return the visible amount of the Adjustable.
-     */
-    public int getVisibleAmount();
-
-    /**
-     * Removes the adjustment listener of the Adjustable.
-     * 
-     * @param a0
-     *            the specified AdjustmentListener to be removed.
-     */
-    public void removeAdjustmentListener(AdjustmentListener a0);
-
-    /**
-     * Sets the block increment for the Adjustable.
-     * 
-     * @param a0
-     *            the new block increment.
-     */
-    public void setBlockIncrement(int a0);
-
-    /**
-     * Sets the maximum value of the Adjustable.
-     * 
-     * @param a0
-     *            the new maximum of the Adjustable.
-     */
-    public void setMaximum(int a0);
-
-    /**
-     * Sets the minimum value of the Adjustable.
-     * 
-     * @param a0
-     *            the new minimum of the Adjustable.
-     */
-    public void setMinimum(int a0);
-
-    /**
-     * Sets the unit increment of the Adjustable.
-     * 
-     * @param a0
-     *            the new unit increment of the Adjustable.
-     */
-    public void setUnitIncrement(int a0);
-
-    /**
-     * Sets the visible amount of the Adjustable.
-     * 
-     * @param a0
-     *            the new visible amount of the Adjustable.
-     */
-    public void setVisibleAmount(int a0);
-
-}
diff --git a/awt/java/awt/AlphaComposite.java b/awt/java/awt/AlphaComposite.java
deleted file mode 100644
index 8389eb4..0000000
--- a/awt/java/awt/AlphaComposite.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.Composite;
-import java.awt.CompositeContext;
-import java.awt.RenderingHints;
-import java.awt.image.ColorModel;
-
-import org.apache.harmony.awt.gl.ICompositeContext;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The AlphaComposite class defines a basic alpha compositing rules for
- * combining source and destination colors to achieve blending and transparency
- * effects with graphics and images.
- * 
- * @since Android 1.0
- */
-public final class AlphaComposite implements Composite {
-
-    /**
-     * The Constant CLEAR indicates that both the color and the alpha of the
-     * destination are cleared (Porter-Duff Clear rule).
-     */
-    public static final int CLEAR = 1;
-
-    /**
-     * The Constant SRC indicates that the source is copied to the destination
-     * (Porter-Duff Source rule).
-     */
-    public static final int SRC = 2;
-
-    /**
-     * The Constant DST indicates that the destination is left untouched
-     * (Porter-Duff Destination rule).
-     */
-    public static final int DST = 9;
-
-    /**
-     * The Constant SRC_OVER indicates that the source is composited over the
-     * destination (Porter-Duff Source Over Destination rule).
-     */
-    public static final int SRC_OVER = 3;
-
-    /**
-     * The Constant DST_OVER indicates that The destination is composited over
-     * the source and the result replaces the destination (Porter-Duff
-     * Destination Over Source rule).
-     */
-    public static final int DST_OVER = 4;
-
-    /**
-     * The Constant SRC_IN indicates that the part of the source lying inside of
-     * the destination replaces the destination (Porter-Duff Source In
-     * Destination rule).
-     */
-    public static final int SRC_IN = 5;
-
-    /**
-     * The Constant DST_IN indicates that the part of the destination lying
-     * inside of the source replaces the destination (Porter-Duff Destination In
-     * Source rule).
-     */
-    public static final int DST_IN = 6;
-
-    /**
-     * The Constant SRC_OUT indicates that the part of the source lying outside
-     * of the destination replaces the destination (Porter-Duff Source Held Out
-     * By Destination rule).
-     */
-    public static final int SRC_OUT = 7;
-
-    /**
-     * The Constant DST_OUT indicates that the part of the destination lying
-     * outside of the source replaces the destination (Porter-Duff Destination
-     * Held Out By Source rule).
-     */
-    public static final int DST_OUT = 8;
-
-    /**
-     * The Constant SRC_ATOP indicates that the part of the source lying inside
-     * of the destination is composited onto the destination (Porter-Duff Source
-     * Atop Destination rule).
-     */
-    public static final int SRC_ATOP = 10;
-
-    /**
-     * The Constant DST_ATOP indicates that the part of the destination lying
-     * inside of the source is composited over the source and replaces the
-     * destination (Porter-Duff Destination Atop Source rule).
-     */
-    public static final int DST_ATOP = 11;
-
-    /**
-     * The Constant XOR indicates that the part of the source that lies outside
-     * of the destination is combined with the part of the destination that lies
-     * outside of the source (Porter-Duff Source Xor Destination rule).
-     */
-    public static final int XOR = 12;
-
-    /**
-     * AlphaComposite object with the opaque CLEAR rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite Clear = new AlphaComposite(CLEAR);
-
-    /**
-     * AlphaComposite object with the opaque SRC rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite Src = new AlphaComposite(SRC);
-
-    /**
-     * AlphaComposite object with the opaque DST rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite Dst = new AlphaComposite(DST);
-
-    /**
-     * AlphaComposite object with the opaque SRC_OVER rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite SrcOver = new AlphaComposite(SRC_OVER);
-
-    /**
-     * AlphaComposite object with the opaque DST_OVER rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite DstOver = new AlphaComposite(DST_OVER);
-
-    /**
-     * AlphaComposite object with the opaque SRC_IN rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite SrcIn = new AlphaComposite(SRC_IN);
-
-    /**
-     * AlphaComposite object with the opaque DST_IN rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite DstIn = new AlphaComposite(DST_IN);
-
-    /**
-     * AlphaComposite object with the opaque SRC_OUT rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite SrcOut = new AlphaComposite(SRC_OUT);
-
-    /**
-     * AlphaComposite object with the opaque DST_OUT rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite DstOut = new AlphaComposite(DST_OUT);
-
-    /**
-     * AlphaComposite object with the opaque SRC_ATOP rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite SrcAtop = new AlphaComposite(SRC_ATOP);
-
-    /**
-     * AlphaComposite object with the opaque DST_ATOP rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite DstAtop = new AlphaComposite(DST_ATOP);
-
-    /**
-     * AlphaComposite object with the opaque XOR rule and an alpha of 1.0f.
-     */
-    public static final AlphaComposite Xor = new AlphaComposite(XOR);
-
-    /**
-     * The rule.
-     */
-    private int rule;
-
-    /**
-     * The alpha.
-     */
-    private float alpha;
-
-    /**
-     * Instantiates a new alpha composite. Creates a context for the compositing
-     * operation. The context contains state that is used in performing the
-     * compositing operation.
-     * 
-     * @param rule
-     *            the rule.
-     * @param alpha
-     *            the alpha.
-     */
-    private AlphaComposite(int rule, float alpha) {
-        if (rule < CLEAR || rule > XOR) {
-            // awt.11D=Unknown rule
-            throw new IllegalArgumentException(Messages.getString("awt.11D")); //$NON-NLS-1$
-        }
-        if (alpha < 0.0f || alpha > 1.0f) {
-            // awt.11E=Wrong alpha value
-            throw new IllegalArgumentException(Messages.getString("awt.11E")); //$NON-NLS-1$
-        }
-
-        this.rule = rule;
-        this.alpha = alpha;
-    }
-
-    /**
-     * Instantiates a new alpha composite.
-     * 
-     * @param rule
-     *            the rule.
-     */
-    private AlphaComposite(int rule) {
-        this(rule, 1.0f);
-    }
-
-    /**
-     * Creates a CompositeContext object with the specified source ColorModel,
-     * destination ColorModel and RenderingHints parameters for a composing
-     * operation.
-     * 
-     * @param srcColorModel
-     *            the source's ColorModel.
-     * @param dstColorModel
-     *            the destination's ColorModel.
-     * @param hints
-     *            the RenderingHints object.
-     * @return the CompositeContext object.
-     * @see java.awt.Composite#createContext(java.awt.image.ColorModel,
-     *      java.awt.image.ColorModel, java.awt.RenderingHints)
-     */
-    public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel,
-            RenderingHints hints) {
-        return new ICompositeContext(this, srcColorModel, dstColorModel);
-    }
-
-    /**
-     * Compares the AlphaComposite object with the specified object.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if the AlphaComposite object is equal to the specified
-     *         object.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof AlphaComposite)) {
-            return false;
-        }
-        AlphaComposite other = (AlphaComposite)obj;
-        return (this.rule == other.getRule() && this.alpha == other.getAlpha());
-    }
-
-    /**
-     * Returns the hash code of the AlphaComposite object.
-     * 
-     * @return the hash code of the AlphaComposite object.
-     */
-    @Override
-    public int hashCode() {
-        int hash = Float.floatToIntBits(alpha);
-        int tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= rule;
-        return hash;
-    }
-
-    /**
-     * Gets the compositing rule of this AlphaComposite object.
-     * 
-     * @return the compositing rule of this AlphaComposite object.
-     */
-    public int getRule() {
-        return rule;
-    }
-
-    /**
-     * Gets the alpha value of this AlphaComposite object; returns 1.0 if this
-     * AlphaComposite object doesn't have alpha value.
-     * 
-     * @return the alpha value of this AlphaComposite object or 1.0 if this
-     *         AlphaComposite object doesn't have alpha value.
-     */
-    public float getAlpha() {
-        return alpha;
-    }
-
-    /**
-     * Gets the AlphaComposite instance with the specified rule and alpha value.
-     * 
-     * @param rule
-     *            the compositing rule.
-     * @param alpha
-     *            the alpha value.
-     * @return the AlphaComposite instance.
-     */
-    public static AlphaComposite getInstance(int rule, float alpha) {
-        if (alpha == 1.0f) {
-            return getInstance(rule);
-        }
-        return new AlphaComposite(rule, alpha);
-    }
-
-    /**
-     * Gets the AlphaComposite instance with the specified rule.
-     * 
-     * @param rule
-     *            the compositing rule.
-     * @return the AlphaComposite instance.
-     */
-    public static AlphaComposite getInstance(int rule) {
-        switch (rule) {
-            case CLEAR:
-                return Clear;
-            case SRC:
-                return Src;
-            case DST:
-                return Dst;
-            case SRC_OVER:
-                return SrcOver;
-            case DST_OVER:
-                return DstOver;
-            case SRC_IN:
-                return SrcIn;
-            case DST_IN:
-                return DstIn;
-            case SRC_OUT:
-                return SrcOut;
-            case DST_OUT:
-                return DstOut;
-            case SRC_ATOP:
-                return SrcAtop;
-            case DST_ATOP:
-                return DstAtop;
-            case XOR:
-                return Xor;
-            default:
-                // awt.11D=Unknown rule
-                throw new IllegalArgumentException(Messages.getString("awt.11D")); //$NON-NLS-1$
-        }
-    }
-
-}
diff --git a/awt/java/awt/BasicStroke.java b/awt/java/awt/BasicStroke.java
deleted file mode 100644
index 2457815..0000000
--- a/awt/java/awt/BasicStroke.java
+++ /dev/null
@@ -1,2443 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.geom.GeneralPath;
-import java.awt.geom.PathIterator;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.misc.HashCode;
-
-/**
- * The BasicStroke class specifies a set of rendering attributes for the
- * outlines of graphics primitives. The BasicStroke attributes describe the
- * shape of the pen which draws the outline of a Shape and the decorations
- * applied at the ends and joins of path segments of the Shape. The BasicStroke
- * has the following rendering attributes:
- * <p>
- * <ul>
- * <li>line width -the pen width which draws the outlines.</li>
- * <li>end caps - indicates the decoration applied to the ends of unclosed
- * subpaths and dash segments. The BasicStroke defines three different
- * decorations: CAP_BUTT, CAP_ROUND, and CAP_SQUARE.</li>
- * <li>line joins - indicates the decoration applied at the intersection of two
- * path segments and at the intersection of the endpoints of a subpath. The
- * BasicStroke defines three decorations: JOIN_BEVEL, JOIN_MITER, and
- * JOIN_ROUND.</li>
- * <li>miter limit - the limit to trim a line join that has a JOIN_MITER
- * decoration.</li>
- * <li>dash attributes - the definition of how to make a dash pattern by
- * alternating between opaque and transparent sections</li>
- * </ul>
- * </p>
- * 
- * @since Android 1.0
- */
-public class BasicStroke implements Stroke {
-
-    /**
-     * The Constant CAP_BUTT indicates the ends of unclosed subpaths and dash
-     * segments have no added decoration.
-     */
-    public static final int CAP_BUTT = 0;
-
-    /**
-     * The Constant CAP_ROUND indicates the ends of unclosed subpaths and dash
-     * segments have a round decoration.
-     */
-    public static final int CAP_ROUND = 1;
-
-    /**
-     * The Constant CAP_SQUARE indicates the ends of unclosed subpaths and dash
-     * segments have a square projection.
-     */
-    public static final int CAP_SQUARE = 2;
-
-    /**
-     * The Constant JOIN_MITER indicates that path segments are joined by
-     * extending their outside edges until they meet.
-     */
-    public static final int JOIN_MITER = 0;
-
-    /**
-     * The Constant JOIN_ROUND indicates that path segments are joined by
-     * rounding off the corner at a radius of half the line width.
-     */
-    public static final int JOIN_ROUND = 1;
-
-    /**
-     * The Constant JOIN_BEVEL indicates that path segments are joined by
-     * connecting the outer corners of their wide outlines with a straight
-     * segment.
-     */
-    public static final int JOIN_BEVEL = 2;
-
-    /**
-     * Constants for calculating.
-     */
-    static final int MAX_LEVEL = 20; // Maximal deepness of curve subdivision
-
-    /**
-     * The Constant CURVE_DELTA.
-     */
-    static final double CURVE_DELTA = 2.0; // Width tolerance
-
-    /**
-     * The Constant CORNER_ANGLE.
-     */
-    static final double CORNER_ANGLE = 4.0; // Minimum corner angle
-
-    /**
-     * The Constant CORNER_ZERO.
-     */
-    static final double CORNER_ZERO = 0.01; // Zero angle
-
-    /**
-     * The Constant CUBIC_ARC.
-     */
-    static final double CUBIC_ARC = 4.0 / 3.0 * (Math.sqrt(2.0) - 1);
-
-    /**
-     * Stroke width.
-     */
-    float width;
-
-    /**
-     * Stroke cap type.
-     */
-    int cap;
-
-    /**
-     * Stroke join type.
-     */
-    int join;
-
-    /**
-     * Stroke miter limit.
-     */
-    float miterLimit;
-
-    /**
-     * Stroke dashes array.
-     */
-    float dash[];
-
-    /**
-     * Stroke dash phase.
-     */
-    float dashPhase;
-
-    /**
-     * The temporary pre-calculated values.
-     */
-    double curveDelta;
-
-    /**
-     * The corner delta.
-     */
-    double cornerDelta;
-
-    /**
-     * The zero delta.
-     */
-    double zeroDelta;
-
-    /**
-     * The w2.
-     */
-    double w2;
-
-    /**
-     * The fmy.
-     */
-    double fmx, fmy;
-
-    /**
-     * The smy.
-     */
-    double scx, scy, smx, smy;
-
-    /**
-     * The cy.
-     */
-    double mx, my, cx, cy;
-
-    /**
-     * The temporary indicators.
-     */
-    boolean isMove;
-
-    /**
-     * The is first.
-     */
-    boolean isFirst;
-
-    /**
-     * The check move.
-     */
-    boolean checkMove;
-
-    /**
-     * The temporary and destination work paths.
-     */
-    BufferedPath dst, lp, rp, sp;
-
-    /**
-     * Stroke dasher class.
-     */
-    Dasher dasher;
-
-    /**
-     * Instantiates a new BasicStroke with default width, cap, join, limit, dash
-     * attributes parameters. The default parameters are a solid line of width
-     * 1.0, CAP_SQUARE, JOIN_MITER, a miter limit of 10.0, null dash attributes,
-     * and a dash phase of 0.0f.
-     */
-    public BasicStroke() {
-        this(1.0f, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
-    }
-
-    /**
-     * Instantiates a new BasicStroke with the specified width, caps, joins,
-     * limit, dash attributes, dash phase parameters.
-     * 
-     * @param width
-     *            the width of BasikStroke.
-     * @param cap
-     *            the end decoration of BasikStroke.
-     * @param join
-     *            the join segments decoration.
-     * @param miterLimit
-     *            the limit to trim the miter join.
-     * @param dash
-     *            the array with the dashing pattern.
-     * @param dashPhase
-     *            the offset to start the dashing pattern.
-     */
-    public BasicStroke(float width, int cap, int join, float miterLimit, float[] dash,
-            float dashPhase) {
-        if (width < 0.0f) {
-            // awt.133=Negative width
-            throw new IllegalArgumentException(Messages.getString("awt.133")); //$NON-NLS-1$
-        }
-        if (cap != CAP_BUTT && cap != CAP_ROUND && cap != CAP_SQUARE) {
-            // awt.134=Illegal cap
-            throw new IllegalArgumentException(Messages.getString("awt.134")); //$NON-NLS-1$
-        }
-        if (join != JOIN_MITER && join != JOIN_ROUND && join != JOIN_BEVEL) {
-            // awt.135=Illegal join
-            throw new IllegalArgumentException(Messages.getString("awt.135")); //$NON-NLS-1$
-        }
-        if (join == JOIN_MITER && miterLimit < 1.0f) {
-            // awt.136=miterLimit less than 1.0f
-            throw new IllegalArgumentException(Messages.getString("awt.136")); //$NON-NLS-1$
-        }
-        if (dash != null) {
-            if (dashPhase < 0.0f) {
-                // awt.137=Negative dashPhase
-                throw new IllegalArgumentException(Messages.getString("awt.137")); //$NON-NLS-1$
-            }
-            if (dash.length == 0) {
-                // awt.138=Zero dash length
-                throw new IllegalArgumentException(Messages.getString("awt.138")); //$NON-NLS-1$
-            }
-            ZERO: {
-                for (int i = 0; i < dash.length; i++) {
-                    if (dash[i] < 0.0) {
-                        // awt.139=Negative dash[{0}]
-                        throw new IllegalArgumentException(Messages.getString("awt.139", i)); //$NON-NLS-1$
-                    }
-                    if (dash[i] > 0.0) {
-                        break ZERO;
-                    }
-                }
-                // awt.13A=All dash lengths zero
-                throw new IllegalArgumentException(Messages.getString("awt.13A")); //$NON-NLS-1$
-            }
-        }
-        this.width = width;
-        this.cap = cap;
-        this.join = join;
-        this.miterLimit = miterLimit;
-        this.dash = dash;
-        this.dashPhase = dashPhase;
-    }
-
-    /**
-     * Instantiates a new BasicStroke with specified width, cap, join, limit and
-     * default dash attributes parameters.
-     * 
-     * @param width
-     *            the width of BasikStroke.
-     * @param cap
-     *            the end decoration of BasikStroke.
-     * @param join
-     *            the join segments decoration.
-     * @param miterLimit
-     *            the limit to trim the miter join.
-     */
-    public BasicStroke(float width, int cap, int join, float miterLimit) {
-        this(width, cap, join, miterLimit, null, 0.0f);
-    }
-
-    /**
-     * Instantiates a new BasicStroke with specified width, cap, join and
-     * default limit and dash attributes parameters.
-     * 
-     * @param width
-     *            the width of BasikStroke.
-     * @param cap
-     *            the end decoration of BasikStroke.
-     * @param join
-     *            the join segments decoration.
-     */
-    public BasicStroke(float width, int cap, int join) {
-        this(width, cap, join, 10.0f, null, 0.0f);
-    }
-
-    /**
-     * Instantiates a new BasicStroke with specified width and default cap,
-     * join, limit, dash attributes parameters.
-     * 
-     * @param width
-     *            the width of BasicStroke.
-     */
-    public BasicStroke(float width) {
-        this(width, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
-    }
-
-    /**
-     * Gets the line width of the BasicStroke.
-     * 
-     * @return the line width of the BasicStroke.
-     */
-    public float getLineWidth() {
-        return width;
-    }
-
-    /**
-     * Gets the end cap style of the BasicStroke.
-     * 
-     * @return the end cap style of the BasicStroke.
-     */
-    public int getEndCap() {
-        return cap;
-    }
-
-    /**
-     * Gets the line join style of the BasicStroke.
-     * 
-     * @return the line join style of the BasicStroke.
-     */
-    public int getLineJoin() {
-        return join;
-    }
-
-    /**
-     * Gets the miter limit of the BasicStroke (the limit to trim the miter
-     * join).
-     * 
-     * @return the miter limit of the BasicStroke.
-     */
-    public float getMiterLimit() {
-        return miterLimit;
-    }
-
-    /**
-     * Gets the dash attributes array of the BasicStroke.
-     * 
-     * @return the dash attributes array of the BasicStroke.
-     */
-    public float[] getDashArray() {
-        return dash;
-    }
-
-    /**
-     * Gets the dash phase of the BasicStroke.
-     * 
-     * @return the dash phase of the BasicStroke.
-     */
-    public float getDashPhase() {
-        return dashPhase;
-    }
-
-    /**
-     * Returns hash code of this BasicStroke.
-     * 
-     * @return the hash code of this BasicStroke.
-     */
-    @Override
-    public int hashCode() {
-        HashCode hash = new HashCode();
-        hash.append(width);
-        hash.append(cap);
-        hash.append(join);
-        hash.append(miterLimit);
-        if (dash != null) {
-            hash.append(dashPhase);
-            for (float element : dash) {
-                hash.append(element);
-            }
-        }
-        return hash.hashCode();
-    }
-
-    /**
-     * Compares this BasicStroke object with the specified Object.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if the Object is a BasicStroke with the same data values as
-     *         this BasicStroke; false otherwise.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (obj instanceof BasicStroke) {
-            BasicStroke bs = (BasicStroke)obj;
-            return bs.width == width && bs.cap == cap && bs.join == join
-                    && bs.miterLimit == miterLimit && bs.dashPhase == dashPhase
-                    && java.util.Arrays.equals(bs.dash, dash);
-        }
-        return false;
-    }
-
-    /**
-     * Calculates allowable curve derivation.
-     * 
-     * @param width
-     *            the width.
-     * @return the curve delta.
-     */
-    double getCurveDelta(double width) {
-        double a = width + CURVE_DELTA;
-        double cos = 1.0 - 2.0 * width * width / (a * a);
-        double sin = Math.sqrt(1.0 - cos * cos);
-        return Math.abs(sin / cos);
-    }
-
-    /**
-     * Calculates the value to detect a small angle.
-     * 
-     * @param width
-     *            the width.
-     * @return the corner delta.
-     */
-    double getCornerDelta(double width) {
-        return width * width * Math.sin(Math.PI * CORNER_ANGLE / 180.0);
-    }
-
-    /**
-     * Calculates value to detect a zero angle.
-     * 
-     * @param width
-     *            the width.
-     * @return the zero delta.
-     */
-    double getZeroDelta(double width) {
-        return width * width * Math.sin(Math.PI * CORNER_ZERO / 180.0);
-    }
-
-    /**
-     * Creates a Shape from the outline of the specified shape drawn with this
-     * BasicStroke.
-     * 
-     * @param s
-     *            the specified Shape to be stroked.
-     * @return the Shape of the stroked outline.
-     * @see java.awt.Stroke#createStrokedShape(java.awt.Shape)
-     */
-    public Shape createStrokedShape(Shape s) {
-        w2 = width / 2.0;
-        curveDelta = getCurveDelta(w2);
-        cornerDelta = getCornerDelta(w2);
-        zeroDelta = getZeroDelta(w2);
-
-        dst = new BufferedPath();
-        lp = new BufferedPath();
-        rp = new BufferedPath();
-
-        if (dash == null) {
-            createSolidShape(s.getPathIterator(null));
-        } else {
-            createDashedShape(s.getPathIterator(null));
-        }
-
-        return dst.createGeneralPath();
-    }
-
-    /**
-     * Generates a shape with a solid (not dashed) outline.
-     * 
-     * @param p
-     *            the PathIterator of source shape.
-     */
-    void createSolidShape(PathIterator p) {
-        double coords[] = new double[6];
-        mx = my = cx = cy = 0.0;
-        isMove = false;
-        isFirst = false;
-        checkMove = true;
-        boolean isClosed = true;
-
-        while (!p.isDone()) {
-            switch (p.currentSegment(coords)) {
-                case PathIterator.SEG_MOVETO:
-                    if (!isClosed) {
-                        closeSolidShape();
-                    }
-                    rp.clean();
-                    mx = cx = coords[0];
-                    my = cy = coords[1];
-                    isMove = true;
-                    isClosed = false;
-                    break;
-                case PathIterator.SEG_LINETO:
-                    addLine(cx, cy, cx = coords[0], cy = coords[1], true);
-                    break;
-                case PathIterator.SEG_QUADTO:
-                    addQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3]);
-                    break;
-                case PathIterator.SEG_CUBICTO:
-                    addCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4],
-                            cy = coords[5]);
-                    break;
-                case PathIterator.SEG_CLOSE:
-                    addLine(cx, cy, mx, my, false);
-                    addJoin(lp, mx, my, lp.xMove, lp.yMove, true);
-                    addJoin(rp, mx, my, rp.xMove, rp.yMove, false);
-                    lp.closePath();
-                    rp.closePath();
-                    lp.appendReverse(rp);
-                    isClosed = true;
-                    break;
-            }
-            p.next();
-        }
-        if (!isClosed) {
-            closeSolidShape();
-        }
-
-        dst = lp;
-    }
-
-    /**
-     * Closes solid shape path.
-     */
-    void closeSolidShape() {
-        addCap(lp, cx, cy, rp.xLast, rp.yLast);
-        lp.combine(rp);
-        addCap(lp, mx, my, lp.xMove, lp.yMove);
-        lp.closePath();
-    }
-
-    /**
-     * Generates dashed stroked shape.
-     * 
-     * @param p
-     *            the PathIterator of source shape.
-     */
-    void createDashedShape(PathIterator p) {
-        double coords[] = new double[6];
-        mx = my = cx = cy = 0.0;
-        smx = smy = scx = scy = 0.0;
-        isMove = false;
-        checkMove = false;
-        boolean isClosed = true;
-
-        while (!p.isDone()) {
-            switch (p.currentSegment(coords)) {
-                case PathIterator.SEG_MOVETO:
-
-                    if (!isClosed) {
-                        closeDashedShape();
-                    }
-
-                    dasher = new Dasher(dash, dashPhase);
-                    lp.clean();
-                    rp.clean();
-                    sp = null;
-                    isFirst = true;
-                    isMove = true;
-                    isClosed = false;
-                    mx = cx = coords[0];
-                    my = cy = coords[1];
-                    break;
-                case PathIterator.SEG_LINETO:
-                    addDashLine(cx, cy, cx = coords[0], cy = coords[1]);
-                    break;
-                case PathIterator.SEG_QUADTO:
-                    addDashQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3]);
-                    break;
-                case PathIterator.SEG_CUBICTO:
-                    addDashCubic(cx, cy, coords[0], coords[1], coords[2], coords[3],
-                            cx = coords[4], cy = coords[5]);
-                    break;
-                case PathIterator.SEG_CLOSE:
-                    addDashLine(cx, cy, cx = mx, cy = my);
-
-                    if (dasher.isConnected()) {
-                        // Connect current and head segments
-                        addJoin(lp, fmx, fmy, sp.xMove, sp.yMove, true);
-                        lp.join(sp);
-                        addJoin(lp, fmx, fmy, rp.xLast, rp.yLast, true);
-                        lp.combine(rp);
-                        addCap(lp, smx, smy, lp.xMove, lp.yMove);
-                        lp.closePath();
-                        dst.append(lp);
-                        sp = null;
-                    } else {
-                        closeDashedShape();
-                    }
-
-                    isClosed = true;
-                    break;
-            }
-            p.next();
-        }
-
-        if (!isClosed) {
-            closeDashedShape();
-        }
-
-    }
-
-    /**
-     * Closes dashed shape path.
-     */
-    void closeDashedShape() {
-        // Add head segment
-        if (sp != null) {
-            addCap(sp, fmx, fmy, sp.xMove, sp.yMove);
-            sp.closePath();
-            dst.append(sp);
-        }
-        if (lp.typeSize > 0) {
-            // Close current segment
-            if (!dasher.isClosed()) {
-                addCap(lp, scx, scy, rp.xLast, rp.yLast);
-                lp.combine(rp);
-                addCap(lp, smx, smy, lp.xMove, lp.yMove);
-                lp.closePath();
-            }
-            dst.append(lp);
-        }
-    }
-
-    /**
-     * Adds cap to the work path.
-     * 
-     * @param p
-     *            the BufferedPath object of work path.
-     * @param x0
-     *            the x coordinate of the source path.
-     * @param y0
-     *            the y coordinate on the source path.
-     * @param x2
-     *            the x coordinate of the next point on the work path.
-     * @param y2
-     *            the y coordinate of the next point on the work path.
-     */
-    void addCap(BufferedPath p, double x0, double y0, double x2, double y2) {
-        double x1 = p.xLast;
-        double y1 = p.yLast;
-        double x10 = x1 - x0;
-        double y10 = y1 - y0;
-        double x20 = x2 - x0;
-        double y20 = y2 - y0;
-
-        switch (cap) {
-            case CAP_BUTT:
-                p.lineTo(x2, y2);
-                break;
-            case CAP_ROUND:
-                double mx = x10 * CUBIC_ARC;
-                double my = y10 * CUBIC_ARC;
-
-                double x3 = x0 + y10;
-                double y3 = y0 - x10;
-
-                x10 *= CUBIC_ARC;
-                y10 *= CUBIC_ARC;
-                x20 *= CUBIC_ARC;
-                y20 *= CUBIC_ARC;
-
-                p.cubicTo(x1 + y10, y1 - x10, x3 + mx, y3 + my, x3, y3);
-                p.cubicTo(x3 - mx, y3 - my, x2 - y20, y2 + x20, x2, y2);
-                break;
-            case CAP_SQUARE:
-                p.lineTo(x1 + y10, y1 - x10);
-                p.lineTo(x2 - y20, y2 + x20);
-                p.lineTo(x2, y2);
-                break;
-        }
-    }
-
-    /**
-     * Adds bevel and miter join to the work path.
-     * 
-     * @param p
-     *            the BufferedPath object of work path.
-     * @param x0
-     *            the x coordinate of the source path.
-     * @param y0
-     *            the y coordinate on the source path.
-     * @param x2
-     *            the x coordinate of the next point on the work path.
-     * @param y2
-     *            the y coordinate of the next point on the work path.
-     * @param isLeft
-     *            the orientation of work path, true if work path lies to the
-     *            left from source path, false otherwise.
-     */
-    void addJoin(BufferedPath p, double x0, double y0, double x2, double y2, boolean isLeft) {
-        double x1 = p.xLast;
-        double y1 = p.yLast;
-        double x10 = x1 - x0;
-        double y10 = y1 - y0;
-        double x20 = x2 - x0;
-        double y20 = y2 - y0;
-        double sin0 = x10 * y20 - y10 * x20;
-
-        // Small corner
-        if (-cornerDelta < sin0 && sin0 < cornerDelta) {
-            double cos0 = x10 * x20 + y10 * y20;
-            if (cos0 > 0.0) {
-                // if zero corner do nothing
-                if (-zeroDelta > sin0 || sin0 > zeroDelta) {
-                    double x3 = x0 + w2 * w2 * (y20 - y10) / sin0;
-                    double y3 = y0 + w2 * w2 * (x10 - x20) / sin0;
-                    p.setLast(x3, y3);
-                }
-                return;
-            }
-            // Zero corner
-            if (-zeroDelta < sin0 && sin0 < zeroDelta) {
-                p.lineTo(x2, y2);
-            }
-            return;
-        }
-
-        if (isLeft ^ (sin0 < 0.0)) {
-            // Twisted corner
-            p.lineTo(x0, y0);
-            p.lineTo(x2, y2);
-        } else {
-            switch (join) {
-                case JOIN_BEVEL:
-                    p.lineTo(x2, y2);
-                    break;
-                case JOIN_MITER:
-                    double s1 = x1 * x10 + y1 * y10;
-                    double s2 = x2 * x20 + y2 * y20;
-                    double x3 = (s1 * y20 - s2 * y10) / sin0;
-                    double y3 = (s2 * x10 - s1 * x20) / sin0;
-                    double x30 = x3 - x0;
-                    double y30 = y3 - y0;
-                    double miterLength = Math.sqrt(x30 * x30 + y30 * y30);
-                    if (miterLength < miterLimit * w2) {
-                        p.lineTo(x3, y3);
-                    }
-                    p.lineTo(x2, y2);
-                    break;
-                case JOIN_ROUND:
-                    addRoundJoin(p, x0, y0, x2, y2, isLeft);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Adds round join to the work path.
-     * 
-     * @param p
-     *            the BufferedPath object of work path.
-     * @param x0
-     *            the x coordinate of the source path.
-     * @param y0
-     *            the y coordinate on the source path.
-     * @param x2
-     *            the x coordinate of the next point on the work path.
-     * @param y2
-     *            the y coordinate of the next point on the work path.
-     * @param isLeft
-     *            the orientation of work path, true if work path lies to the
-     *            left from source path, false otherwise.
-     */
-    void addRoundJoin(BufferedPath p, double x0, double y0, double x2, double y2, boolean isLeft) {
-        double x1 = p.xLast;
-        double y1 = p.yLast;
-        double x10 = x1 - x0;
-        double y10 = y1 - y0;
-        double x20 = x2 - x0;
-        double y20 = y2 - y0;
-
-        double x30 = x10 + x20;
-        double y30 = y10 + y20;
-
-        double l30 = Math.sqrt(x30 * x30 + y30 * y30);
-
-        if (l30 < 1E-5) {
-            p.lineTo(x2, y2);
-            return;
-        }
-
-        double w = w2 / l30;
-
-        x30 *= w;
-        y30 *= w;
-
-        double x3 = x0 + x30;
-        double y3 = y0 + y30;
-
-        double cos = x10 * x20 + y10 * y20;
-        double a = Math.acos(cos / (w2 * w2));
-        if (cos >= 0.0) {
-            double k = 4.0 / 3.0 * Math.tan(a / 4.0);
-            if (isLeft) {
-                k = -k;
-            }
-
-            x10 *= k;
-            y10 *= k;
-            x20 *= k;
-            y20 *= k;
-
-            p.cubicTo(x1 - y10, y1 + x10, x2 + y20, y2 - x20, x2, y2);
-        } else {
-            double k = 4.0 / 3.0 * Math.tan(a / 8.0);
-            if (isLeft) {
-                k = -k;
-            }
-
-            x10 *= k;
-            y10 *= k;
-            x20 *= k;
-            y20 *= k;
-            x30 *= k;
-            y30 *= k;
-
-            p.cubicTo(x1 - y10, y1 + x10, x3 + y30, y3 - x30, x3, y3);
-            p.cubicTo(x3 - y30, y3 + x30, x2 + y20, y2 - x20, x2, y2);
-        }
-
-    }
-
-    /**
-     * Adds solid line segment to the work path.
-     * 
-     * @param x1
-     *            the x coordinate of the start line point.
-     * @param y1
-     *            the y coordinate of the start line point.
-     * @param x2
-     *            the x coordinate of the end line point.
-     * @param y2
-     *            the y coordinate of the end line point.
-     * @param zero
-     *            if true it's allowable to add zero length line segment.
-     */
-    void addLine(double x1, double y1, double x2, double y2, boolean zero) {
-        double dx = x2 - x1;
-        double dy = y2 - y1;
-
-        if (dx == 0.0 && dy == 0.0) {
-            if (!zero) {
-                return;
-            }
-            dx = w2;
-            dy = 0;
-        } else {
-            double w = w2 / Math.sqrt(dx * dx + dy * dy);
-            dx *= w;
-            dy *= w;
-        }
-
-        double lx1 = x1 - dy;
-        double ly1 = y1 + dx;
-        double rx1 = x1 + dy;
-        double ry1 = y1 - dx;
-
-        if (checkMove) {
-            if (isMove) {
-                isMove = false;
-                lp.moveTo(lx1, ly1);
-                rp.moveTo(rx1, ry1);
-            } else {
-                addJoin(lp, x1, y1, lx1, ly1, true);
-                addJoin(rp, x1, y1, rx1, ry1, false);
-            }
-        }
-
-        lp.lineTo(x2 - dy, y2 + dx);
-        rp.lineTo(x2 + dy, y2 - dx);
-    }
-
-    /**
-     * Adds solid quad segment to the work path.
-     * 
-     * @param x1
-     *            the x coordinate of the first control point.
-     * @param y1
-     *            the y coordinate of the first control point.
-     * @param x2
-     *            the x coordinate of the second control point.
-     * @param y2
-     *            the y coordinate of the second control point.
-     * @param x3
-     *            the x coordinate of the third control point.
-     * @param y3
-     *            the y coordinate of the third control point.
-     */
-    void addQuad(double x1, double y1, double x2, double y2, double x3, double y3) {
-        double x21 = x2 - x1;
-        double y21 = y2 - y1;
-        double x23 = x2 - x3;
-        double y23 = y2 - y3;
-
-        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
-        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
-
-        if (l21 == 0.0 && l23 == 0.0) {
-            addLine(x1, y1, x3, y3, false);
-            return;
-        }
-
-        if (l21 == 0.0) {
-            addLine(x2, y2, x3, y3, false);
-            return;
-        }
-
-        if (l23 == 0.0) {
-            addLine(x1, y1, x2, y2, false);
-            return;
-        }
-
-        double w;
-        w = w2 / l21;
-        double mx1 = -y21 * w;
-        double my1 = x21 * w;
-        w = w2 / l23;
-        double mx3 = y23 * w;
-        double my3 = -x23 * w;
-
-        double lx1 = x1 + mx1;
-        double ly1 = y1 + my1;
-        double rx1 = x1 - mx1;
-        double ry1 = y1 - my1;
-
-        if (checkMove) {
-            if (isMove) {
-                isMove = false;
-                lp.moveTo(lx1, ly1);
-                rp.moveTo(rx1, ry1);
-            } else {
-                addJoin(lp, x1, y1, lx1, ly1, true);
-                addJoin(rp, x1, y1, rx1, ry1, false);
-            }
-        }
-
-        if (x21 * y23 - y21 * x23 == 0.0) {
-            // On line curve
-            if (x21 * x23 + y21 * y23 > 0.0) {
-                // Twisted curve
-                if (l21 == l23) {
-                    double px = x1 + (x21 + x23) / 4.0;
-                    double py = y1 + (y21 + y23) / 4.0;
-                    lp.lineTo(px + mx1, py + my1);
-                    rp.lineTo(px - mx1, py - my1);
-                    lp.lineTo(px - mx1, py - my1);
-                    rp.lineTo(px + mx1, py + my1);
-                    lp.lineTo(x3 - mx1, y3 - my1);
-                    rp.lineTo(x3 + mx1, y3 + my1);
-                } else {
-                    double px1, py1;
-                    double k = l21 / (l21 + l23);
-                    double px = x1 + (x21 + x23) * k * k;
-                    double py = y1 + (y21 + y23) * k * k;
-                    px1 = (x1 + px) / 2.0;
-                    py1 = (y1 + py) / 2.0;
-                    lp.quadTo(px1 + mx1, py1 + my1, px + mx1, py + my1);
-                    rp.quadTo(px1 - mx1, py1 - my1, px - mx1, py - my1);
-                    lp.lineTo(px - mx1, py - my1);
-                    rp.lineTo(px + mx1, py + my1);
-                    px1 = (x3 + px) / 2.0;
-                    py1 = (y3 + py) / 2.0;
-                    lp.quadTo(px1 - mx1, py1 - my1, x3 - mx1, y3 - my1);
-                    rp.quadTo(px1 + mx1, py1 + my1, x3 + mx1, y3 + my1);
-                }
-            } else {
-                // Simple curve
-                lp.quadTo(x2 + mx1, y2 + my1, x3 + mx3, y3 + my3);
-                rp.quadTo(x2 - mx1, y2 - my1, x3 - mx3, y3 - my3);
-            }
-        } else {
-            addSubQuad(x1, y1, x2, y2, x3, y3, 0);
-        }
-    }
-
-    /**
-     * Subdivides solid quad curve to make outline for source quad segment and
-     * adds it to work path.
-     * 
-     * @param x1
-     *            the x coordinate of the first control point.
-     * @param y1
-     *            the y coordinate of the first control point.
-     * @param x2
-     *            the x coordinate of the second control point.
-     * @param y2
-     *            the y coordinate of the second control point.
-     * @param x3
-     *            the x coordinate of the third control point.
-     * @param y3
-     *            the y coordinate of the third control point.
-     * @param level
-     *            the maximum level of subdivision deepness.
-     */
-    void addSubQuad(double x1, double y1, double x2, double y2, double x3, double y3, int level) {
-        double x21 = x2 - x1;
-        double y21 = y2 - y1;
-        double x23 = x2 - x3;
-        double y23 = y2 - y3;
-
-        double cos = x21 * x23 + y21 * y23;
-        double sin = x21 * y23 - y21 * x23;
-
-        if (level < MAX_LEVEL && (cos >= 0.0 || (Math.abs(sin / cos) > curveDelta))) {
-            double c1x = (x2 + x1) / 2.0;
-            double c1y = (y2 + y1) / 2.0;
-            double c2x = (x2 + x3) / 2.0;
-            double c2y = (y2 + y3) / 2.0;
-            double c3x = (c1x + c2x) / 2.0;
-            double c3y = (c1y + c2y) / 2.0;
-            addSubQuad(x1, y1, c1x, c1y, c3x, c3y, level + 1);
-            addSubQuad(c3x, c3y, c2x, c2y, x3, y3, level + 1);
-        } else {
-            double w;
-            double l21 = Math.sqrt(x21 * x21 + y21 * y21);
-            double l23 = Math.sqrt(x23 * x23 + y23 * y23);
-            w = w2 / sin;
-            double mx2 = (x21 * l23 + x23 * l21) * w;
-            double my2 = (y21 * l23 + y23 * l21) * w;
-            w = w2 / l23;
-            double mx3 = y23 * w;
-            double my3 = -x23 * w;
-            lp.quadTo(x2 + mx2, y2 + my2, x3 + mx3, y3 + my3);
-            rp.quadTo(x2 - mx2, y2 - my2, x3 - mx3, y3 - my3);
-        }
-    }
-
-    /**
-     * Adds solid cubic segment to the work path.
-     * 
-     * @param x1
-     *            the x coordinate of the first control point.
-     * @param y1
-     *            the y coordinate of the first control point.
-     * @param x2
-     *            the x coordinate of the second control point.
-     * @param y2
-     *            the y coordinate of the second control point.
-     * @param x3
-     *            the x coordinate of the third control point.
-     * @param y3
-     *            the y coordinate of the third control point.
-     * @param x4
-     *            the x coordinate of the fours control point.
-     * @param y4
-     *            the y coordinate of the fours control point.
-     */
-    void addCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4,
-            double y4) {
-        double x12 = x1 - x2;
-        double y12 = y1 - y2;
-        double x23 = x2 - x3;
-        double y23 = y2 - y3;
-        double x34 = x3 - x4;
-        double y34 = y3 - y4;
-
-        double l12 = Math.sqrt(x12 * x12 + y12 * y12);
-        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
-        double l34 = Math.sqrt(x34 * x34 + y34 * y34);
-
-        // All edges are zero
-        if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
-            addLine(x1, y1, x4, y4, false);
-            return;
-        }
-
-        // One zero edge
-        if (l12 == 0.0 && l23 == 0.0) {
-            addLine(x3, y3, x4, y4, false);
-            return;
-        }
-
-        if (l23 == 0.0 && l34 == 0.0) {
-            addLine(x1, y1, x2, y2, false);
-            return;
-        }
-
-        if (l12 == 0.0 && l34 == 0.0) {
-            addLine(x2, y2, x3, y3, false);
-            return;
-        }
-
-        double w, mx1, my1, mx4, my4;
-        boolean onLine;
-
-        if (l12 == 0.0) {
-            w = w2 / l23;
-            mx1 = y23 * w;
-            my1 = -x23 * w;
-            w = w2 / l34;
-            mx4 = y34 * w;
-            my4 = -x34 * w;
-            onLine = -x23 * y34 + y23 * x34 == 0.0; // sin3
-        } else if (l34 == 0.0) {
-            w = w2 / l12;
-            mx1 = y12 * w;
-            my1 = -x12 * w;
-            w = w2 / l23;
-            mx4 = y23 * w;
-            my4 = -x23 * w;
-            onLine = -x12 * y23 + y12 * x23 == 0.0; // sin2
-        } else {
-            w = w2 / l12;
-            mx1 = y12 * w;
-            my1 = -x12 * w;
-            w = w2 / l34;
-            mx4 = y34 * w;
-            my4 = -x34 * w;
-            if (l23 == 0.0) {
-                onLine = -x12 * y34 + y12 * x34 == 0.0;
-            } else {
-                onLine = -x12 * y34 + y12 * x34 == 0.0 && -x12 * y23 + y12 * x23 == 0.0 && // sin2
-                        -x23 * y34 + y23 * x34 == 0.0; // sin3
-            }
-        }
-
-        double lx1 = x1 + mx1;
-        double ly1 = y1 + my1;
-        double rx1 = x1 - mx1;
-        double ry1 = y1 - my1;
-
-        if (checkMove) {
-            if (isMove) {
-                isMove = false;
-                lp.moveTo(lx1, ly1);
-                rp.moveTo(rx1, ry1);
-            } else {
-                addJoin(lp, x1, y1, lx1, ly1, true);
-                addJoin(rp, x1, y1, rx1, ry1, false);
-            }
-        }
-
-        if (onLine) {
-            if ((x1 == x2 && y1 < y2) || x1 < x2) {
-                l12 = -l12;
-            }
-            if ((x2 == x3 && y2 < y3) || x2 < x3) {
-                l23 = -l23;
-            }
-            if ((x3 == x4 && y3 < y4) || x3 < x4) {
-                l34 = -l34;
-            }
-            double d = l23 * l23 - l12 * l34;
-            double roots[] = new double[3];
-            int rc = 0;
-            if (d == 0.0) {
-                double t = (l12 - l23) / (l12 + l34 - l23 - l23);
-                if (0.0 < t && t < 1.0) {
-                    roots[rc++] = t;
-                }
-            } else if (d > 0.0) {
-                d = Math.sqrt(d);
-                double z = l12 + l34 - l23 - l23;
-                double t;
-                t = (l12 - l23 + d) / z;
-                if (0.0 < t && t < 1.0) {
-                    roots[rc++] = t;
-                }
-                t = (l12 - l23 - d) / z;
-                if (0.0 < t && t < 1.0) {
-                    roots[rc++] = t;
-                }
-            }
-
-            if (rc > 0) {
-                // Sort roots
-                if (rc == 2 && roots[0] > roots[1]) {
-                    double tmp = roots[0];
-                    roots[0] = roots[1];
-                    roots[1] = tmp;
-                }
-                roots[rc++] = 1.0;
-
-                double ax = -x34 - x12 + x23 + x23;
-                double ay = -y34 - y12 + y23 + y23;
-                double bx = 3.0 * (-x23 + x12);
-                double by = 3.0 * (-y23 + y12);
-                double cx = 3.0 * (-x12);
-                double cy = 3.0 * (-y12);
-                double xPrev = x1;
-                double yPrev = y1;
-                for (int i = 0; i < rc; i++) {
-                    double t = roots[i];
-                    double px = t * (t * (t * ax + bx) + cx) + x1;
-                    double py = t * (t * (t * ay + by) + cy) + y1;
-                    double px1 = (xPrev + px) / 2.0;
-                    double py1 = (yPrev + py) / 2.0;
-                    lp.cubicTo(px1 + mx1, py1 + my1, px1 + mx1, py1 + my1, px + mx1, py + my1);
-                    rp.cubicTo(px1 - mx1, py1 - my1, px1 - mx1, py1 - my1, px - mx1, py - my1);
-                    if (i < rc - 1) {
-                        lp.lineTo(px - mx1, py - my1);
-                        rp.lineTo(px + mx1, py + my1);
-                    }
-                    xPrev = px;
-                    yPrev = py;
-                    mx1 = -mx1;
-                    my1 = -my1;
-                }
-            } else {
-                lp.cubicTo(x2 + mx1, y2 + my1, x3 + mx4, y3 + my4, x4 + mx4, y4 + my4);
-                rp.cubicTo(x2 - mx1, y2 - my1, x3 - mx4, y3 - my4, x4 - mx4, y4 - my4);
-            }
-        } else {
-            addSubCubic(x1, y1, x2, y2, x3, y3, x4, y4, 0);
-        }
-    }
-
-    /**
-     * Subdivides solid cubic curve to make outline for source quad segment and
-     * adds it to work path.
-     * 
-     * @param x1
-     *            the x coordinate of the first control point.
-     * @param y1
-     *            the y coordinate of the first control point.
-     * @param x2
-     *            the x coordinate of the second control point.
-     * @param y2
-     *            the y coordinate of the second control point.
-     * @param x3
-     *            the x coordinate of the third control point.
-     * @param y3
-     *            the y coordinate of the third control point.
-     * @param x4
-     *            the x coordinate of the fours control point.
-     * @param y4
-     *            the y coordinate of the fours control point.
-     * @param level
-     *            the maximum level of subdivision deepness.
-     */
-    void addSubCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4,
-            double y4, int level) {
-        double x12 = x1 - x2;
-        double y12 = y1 - y2;
-        double x23 = x2 - x3;
-        double y23 = y2 - y3;
-        double x34 = x3 - x4;
-        double y34 = y3 - y4;
-
-        double cos2 = -x12 * x23 - y12 * y23;
-        double cos3 = -x23 * x34 - y23 * y34;
-        double sin2 = -x12 * y23 + y12 * x23;
-        double sin3 = -x23 * y34 + y23 * x34;
-        double sin0 = -x12 * y34 + y12 * x34;
-        double cos0 = -x12 * x34 - y12 * y34;
-
-        if (level < MAX_LEVEL
-                && (sin2 != 0.0 || sin3 != 0.0 || sin0 != 0.0)
-                && (cos2 >= 0.0 || cos3 >= 0.0 || cos0 >= 0.0
-                        || (Math.abs(sin2 / cos2) > curveDelta)
-                        || (Math.abs(sin3 / cos3) > curveDelta) || (Math.abs(sin0 / cos0) > curveDelta))) {
-            double cx = (x2 + x3) / 2.0;
-            double cy = (y2 + y3) / 2.0;
-            double lx2 = (x2 + x1) / 2.0;
-            double ly2 = (y2 + y1) / 2.0;
-            double rx3 = (x3 + x4) / 2.0;
-            double ry3 = (y3 + y4) / 2.0;
-            double lx3 = (cx + lx2) / 2.0;
-            double ly3 = (cy + ly2) / 2.0;
-            double rx2 = (cx + rx3) / 2.0;
-            double ry2 = (cy + ry3) / 2.0;
-            cx = (lx3 + rx2) / 2.0;
-            cy = (ly3 + ry2) / 2.0;
-            addSubCubic(x1, y1, lx2, ly2, lx3, ly3, cx, cy, level + 1);
-            addSubCubic(cx, cy, rx2, ry2, rx3, ry3, x4, y4, level + 1);
-        } else {
-            double w, mx1, my1, mx2, my2, mx3, my3, mx4, my4;
-            double l12 = Math.sqrt(x12 * x12 + y12 * y12);
-            double l23 = Math.sqrt(x23 * x23 + y23 * y23);
-            double l34 = Math.sqrt(x34 * x34 + y34 * y34);
-
-            if (l12 == 0.0) {
-                w = w2 / l23;
-                mx1 = y23 * w;
-                my1 = -x23 * w;
-                w = w2 / l34;
-                mx4 = y34 * w;
-                my4 = -x34 * w;
-            } else if (l34 == 0.0) {
-                w = w2 / l12;
-                mx1 = y12 * w;
-                my1 = -x12 * w;
-                w = w2 / l23;
-                mx4 = y23 * w;
-                my4 = -x23 * w;
-            } else {
-                // Common case
-                w = w2 / l12;
-                mx1 = y12 * w;
-                my1 = -x12 * w;
-                w = w2 / l34;
-                mx4 = y34 * w;
-                my4 = -x34 * w;
-            }
-
-            if (sin2 == 0.0) {
-                mx2 = mx1;
-                my2 = my1;
-            } else {
-                w = w2 / sin2;
-                mx2 = -(x12 * l23 - x23 * l12) * w;
-                my2 = -(y12 * l23 - y23 * l12) * w;
-            }
-            if (sin3 == 0.0) {
-                mx3 = mx4;
-                my3 = my4;
-            } else {
-                w = w2 / sin3;
-                mx3 = -(x23 * l34 - x34 * l23) * w;
-                my3 = -(y23 * l34 - y34 * l23) * w;
-            }
-
-            lp.cubicTo(x2 + mx2, y2 + my2, x3 + mx3, y3 + my3, x4 + mx4, y4 + my4);
-            rp.cubicTo(x2 - mx2, y2 - my2, x3 - mx3, y3 - my3, x4 - mx4, y4 - my4);
-        }
-    }
-
-    /**
-     * Adds dashed line segment to the work path.
-     * 
-     * @param x1
-     *            the x coordinate of the start line point.
-     * @param y1
-     *            the y coordinate of the start line point.
-     * @param x2
-     *            the x coordinate of the end line point.
-     * @param y2
-     *            the y coordinate of the end line point.
-     */
-    void addDashLine(double x1, double y1, double x2, double y2) {
-        double x21 = x2 - x1;
-        double y21 = y2 - y1;
-
-        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
-
-        if (l21 == 0.0) {
-            return;
-        }
-
-        double px1, py1;
-        px1 = py1 = 0.0;
-        double w = w2 / l21;
-        double mx = -y21 * w;
-        double my = x21 * w;
-
-        dasher.init(new DashIterator.Line(l21));
-
-        while (!dasher.eof()) {
-            double t = dasher.getValue();
-            scx = x1 + t * x21;
-            scy = y1 + t * y21;
-
-            if (dasher.isOpen()) {
-                px1 = scx;
-                py1 = scy;
-                double lx1 = px1 + mx;
-                double ly1 = py1 + my;
-                double rx1 = px1 - mx;
-                double ry1 = py1 - my;
-                if (isMove) {
-                    isMove = false;
-                    smx = px1;
-                    smy = py1;
-                    rp.clean();
-                    lp.moveTo(lx1, ly1);
-                    rp.moveTo(rx1, ry1);
-                } else {
-                    addJoin(lp, x1, y1, lx1, ly1, true);
-                    addJoin(rp, x1, y1, rx1, ry1, false);
-                }
-            } else if (dasher.isContinue()) {
-                double px2 = scx;
-                double py2 = scy;
-                lp.lineTo(px2 + mx, py2 + my);
-                rp.lineTo(px2 - mx, py2 - my);
-                if (dasher.close) {
-                    addCap(lp, px2, py2, rp.xLast, rp.yLast);
-                    lp.combine(rp);
-                    if (isFirst) {
-                        isFirst = false;
-                        fmx = smx;
-                        fmy = smy;
-                        sp = lp;
-                        lp = new BufferedPath();
-                    } else {
-                        addCap(lp, smx, smy, lp.xMove, lp.yMove);
-                        lp.closePath();
-                    }
-                    isMove = true;
-                }
-            }
-
-            dasher.next();
-        }
-    }
-
-    /**
-     * Adds dashed quad segment to the work path.
-     * 
-     * @param x1
-     *            the x coordinate of the first control point.
-     * @param y1
-     *            the y coordinate of the first control point.
-     * @param x2
-     *            the x coordinate of the second control point.
-     * @param y2
-     *            the y coordinate of the second control point.
-     * @param x3
-     *            the x coordinate of the third control point.
-     * @param y3
-     *            the y coordinate of the third control point.
-     */
-    void addDashQuad(double x1, double y1, double x2, double y2, double x3, double y3) {
-
-        double x21 = x2 - x1;
-        double y21 = y2 - y1;
-        double x23 = x2 - x3;
-        double y23 = y2 - y3;
-
-        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
-        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
-
-        if (l21 == 0.0 && l23 == 0.0) {
-            return;
-        }
-
-        if (l21 == 0.0) {
-            addDashLine(x2, y2, x3, y3);
-            return;
-        }
-
-        if (l23 == 0.0) {
-            addDashLine(x1, y1, x2, y2);
-            return;
-        }
-
-        double ax = x1 + x3 - x2 - x2;
-        double ay = y1 + y3 - y2 - y2;
-        double bx = x2 - x1;
-        double by = y2 - y1;
-        double cx = x1;
-        double cy = y1;
-
-        double px1, py1, dx1, dy1;
-        px1 = py1 = dx1 = dy1 = 0.0;
-        double prev = 0.0;
-
-        dasher.init(new DashIterator.Quad(x1, y1, x2, y2, x3, y3));
-
-        while (!dasher.eof()) {
-            double t = dasher.getValue();
-            double dx = t * ax + bx;
-            double dy = t * ay + by;
-            scx = t * (dx + bx) + cx; // t^2 * ax + 2.0 * t * bx + cx
-            scy = t * (dy + by) + cy; // t^2 * ay + 2.0 * t * by + cy
-            if (dasher.isOpen()) {
-                px1 = scx;
-                py1 = scy;
-                dx1 = dx;
-                dy1 = dy;
-                double w = w2 / Math.sqrt(dx1 * dx1 + dy1 * dy1);
-                double mx1 = -dy1 * w;
-                double my1 = dx1 * w;
-                double lx1 = px1 + mx1;
-                double ly1 = py1 + my1;
-                double rx1 = px1 - mx1;
-                double ry1 = py1 - my1;
-                if (isMove) {
-                    isMove = false;
-                    smx = px1;
-                    smy = py1;
-                    rp.clean();
-                    lp.moveTo(lx1, ly1);
-                    rp.moveTo(rx1, ry1);
-                } else {
-                    addJoin(lp, x1, y1, lx1, ly1, true);
-                    addJoin(rp, x1, y1, rx1, ry1, false);
-                }
-            } else if (dasher.isContinue()) {
-                double px3 = scx;
-                double py3 = scy;
-                double sx = x2 - x23 * prev;
-                double sy = y2 - y23 * prev;
-                double t2 = (t - prev) / (1 - prev);
-                double px2 = px1 + (sx - px1) * t2;
-                double py2 = py1 + (sy - py1) * t2;
-
-                addQuad(px1, py1, px2, py2, px3, py3);
-                if (dasher.isClosed()) {
-                    addCap(lp, px3, py3, rp.xLast, rp.yLast);
-                    lp.combine(rp);
-                    if (isFirst) {
-                        isFirst = false;
-                        fmx = smx;
-                        fmy = smy;
-                        sp = lp;
-                        lp = new BufferedPath();
-                    } else {
-                        addCap(lp, smx, smy, lp.xMove, lp.yMove);
-                        lp.closePath();
-                    }
-                    isMove = true;
-                }
-            }
-
-            prev = t;
-            dasher.next();
-        }
-    }
-
-    /**
-     * Adds dashed cubic segment to the work path.
-     * 
-     * @param x1
-     *            the x coordinate of the first control point.
-     * @param y1
-     *            the y coordinate of the first control point.
-     * @param x2
-     *            the x coordinate of the second control point.
-     * @param y2
-     *            the y coordinate of the second control point.
-     * @param x3
-     *            the x coordinate of the third control point.
-     * @param y3
-     *            the y coordinate of the third control point.
-     * @param x4
-     *            the x coordinate of the fours control point.
-     * @param y4
-     *            the y coordinate of the fours control point.
-     */
-    void addDashCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4,
-            double y4) {
-
-        double x12 = x1 - x2;
-        double y12 = y1 - y2;
-        double x23 = x2 - x3;
-        double y23 = y2 - y3;
-        double x34 = x3 - x4;
-        double y34 = y3 - y4;
-
-        double l12 = Math.sqrt(x12 * x12 + y12 * y12);
-        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
-        double l34 = Math.sqrt(x34 * x34 + y34 * y34);
-
-        // All edges are zero
-        if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
-            // NOTHING
-            return;
-        }
-
-        // One zero edge
-        if (l12 == 0.0 && l23 == 0.0) {
-            addDashLine(x3, y3, x4, y4);
-            return;
-        }
-
-        if (l23 == 0.0 && l34 == 0.0) {
-            addDashLine(x1, y1, x2, y2);
-            return;
-        }
-
-        if (l12 == 0.0 && l34 == 0.0) {
-            addDashLine(x2, y2, x3, y3);
-            return;
-        }
-
-        double ax = x4 - x1 + 3.0 * (x2 - x3);
-        double ay = y4 - y1 + 3.0 * (y2 - y3);
-        double bx = 3.0 * (x1 + x3 - x2 - x2);
-        double by = 3.0 * (y1 + y3 - y2 - y2);
-        double cx = 3.0 * (x2 - x1);
-        double cy = 3.0 * (y2 - y1);
-        double dx = x1;
-        double dy = y1;
-
-        double px1 = 0.0;
-        double py1 = 0.0;
-        double prev = 0.0;
-
-        dasher.init(new DashIterator.Cubic(x1, y1, x2, y2, x3, y3, x4, y4));
-
-        while (!dasher.eof()) {
-
-            double t = dasher.getValue();
-            scx = t * (t * (t * ax + bx) + cx) + dx;
-            scy = t * (t * (t * ay + by) + cy) + dy;
-            if (dasher.isOpen()) {
-                px1 = scx;
-                py1 = scy;
-                double dx1 = t * (t * (ax + ax + ax) + bx + bx) + cx;
-                double dy1 = t * (t * (ay + ay + ay) + by + by) + cy;
-                double w = w2 / Math.sqrt(dx1 * dx1 + dy1 * dy1);
-                double mx1 = -dy1 * w;
-                double my1 = dx1 * w;
-                double lx1 = px1 + mx1;
-                double ly1 = py1 + my1;
-                double rx1 = px1 - mx1;
-                double ry1 = py1 - my1;
-                if (isMove) {
-                    isMove = false;
-                    smx = px1;
-                    smy = py1;
-                    rp.clean();
-                    lp.moveTo(lx1, ly1);
-                    rp.moveTo(rx1, ry1);
-                } else {
-                    addJoin(lp, x1, y1, lx1, ly1, true);
-                    addJoin(rp, x1, y1, rx1, ry1, false);
-                }
-            } else if (dasher.isContinue()) {
-                double sx1 = x2 - x23 * prev;
-                double sy1 = y2 - y23 * prev;
-                double sx2 = x3 - x34 * prev;
-                double sy2 = y3 - y34 * prev;
-                double sx3 = sx1 + (sx2 - sx1) * prev;
-                double sy3 = sy1 + (sy2 - sy1) * prev;
-                double t2 = (t - prev) / (1 - prev);
-                double sx4 = sx3 + (sx2 - sx3) * t2;
-                double sy4 = sy3 + (sy2 - sy3) * t2;
-
-                double px4 = scx;
-                double py4 = scy;
-                double px2 = px1 + (sx3 - px1) * t2;
-                double py2 = py1 + (sy3 - py1) * t2;
-                double px3 = px2 + (sx4 - px2) * t2;
-                double py3 = py2 + (sy4 - py2) * t2;
-
-                addCubic(px1, py1, px2, py2, px3, py3, px4, py4);
-                if (dasher.isClosed()) {
-                    addCap(lp, px4, py4, rp.xLast, rp.yLast);
-                    lp.combine(rp);
-                    if (isFirst) {
-                        isFirst = false;
-                        fmx = smx;
-                        fmy = smy;
-                        sp = lp;
-                        lp = new BufferedPath();
-                    } else {
-                        addCap(lp, smx, smy, lp.xMove, lp.yMove);
-                        lp.closePath();
-                    }
-                    isMove = true;
-                }
-            }
-
-            prev = t;
-            dasher.next();
-        }
-    }
-
-    /**
-     * Dasher class provides dashing for particular dash style.
-     */
-    class Dasher {
-
-        /**
-         * The pos.
-         */
-        double pos;
-
-        /**
-         * The first.
-         */
-        boolean close, visible, first;
-
-        /**
-         * The dash.
-         */
-        float dash[];
-
-        /**
-         * The phase.
-         */
-        float phase;
-
-        /**
-         * The index.
-         */
-        int index;
-
-        /**
-         * The iter.
-         */
-        DashIterator iter;
-
-        /**
-         * Instantiates a new dasher.
-         * 
-         * @param dash
-         *            the dash.
-         * @param phase
-         *            the phase.
-         */
-        Dasher(float dash[], float phase) {
-            this.dash = dash;
-            this.phase = phase;
-            index = 0;
-            pos = phase;
-            visible = true;
-            while (pos >= dash[index]) {
-                visible = !visible;
-                pos -= dash[index];
-                index = (index + 1) % dash.length;
-            }
-            pos = -pos;
-            first = visible;
-        }
-
-        /**
-         * Inits the.
-         * 
-         * @param iter
-         *            the iter.
-         */
-        void init(DashIterator iter) {
-            this.iter = iter;
-            close = true;
-        }
-
-        /**
-         * Checks if is open.
-         * 
-         * @return true, if is open.
-         */
-        boolean isOpen() {
-            return visible && pos < iter.length;
-        }
-
-        /**
-         * Checks if is continue.
-         * 
-         * @return true, if is continue.
-         */
-        boolean isContinue() {
-            return !visible && pos > 0;
-        }
-
-        /**
-         * Checks if is closed.
-         * 
-         * @return true, if is closed.
-         */
-        boolean isClosed() {
-            return close;
-        }
-
-        /**
-         * Checks if is connected.
-         * 
-         * @return true, if is connected.
-         */
-        boolean isConnected() {
-            return first && !close;
-        }
-
-        /**
-         * Eof.
-         * 
-         * @return true, if successful.
-         */
-        boolean eof() {
-            if (!close) {
-                pos -= iter.length;
-                return true;
-            }
-            if (pos >= iter.length) {
-                if (visible) {
-                    pos -= iter.length;
-                    return true;
-                }
-                close = pos == iter.length;
-            }
-            return false;
-        }
-
-        /**
-         * Next.
-         */
-        void next() {
-            if (close) {
-                pos += dash[index];
-                index = (index + 1) % dash.length;
-            } else {
-                // Go back
-                index = (index + dash.length - 1) % dash.length;
-                pos -= dash[index];
-            }
-            visible = !visible;
-        }
-
-        /**
-         * Gets the value.
-         * 
-         * @return the value.
-         */
-        double getValue() {
-            double t = iter.getNext(pos);
-            return t < 0 ? 0 : (t > 1 ? 1 : t);
-        }
-
-    }
-
-    /**
-     * DashIterator class provides dashing for particular segment type.
-     */
-    static abstract class DashIterator {
-
-        /**
-         * The Constant FLATNESS.
-         */
-        static final double FLATNESS = 1.0;
-
-        /**
-         * The Class Line.
-         */
-        static class Line extends DashIterator {
-
-            /**
-             * Instantiates a new line.
-             * 
-             * @param len
-             *            the len.
-             */
-            Line(double len) {
-                length = len;
-            }
-
-            @Override
-            double getNext(double dashPos) {
-                return dashPos / length;
-            }
-
-        }
-
-        /**
-         * The Class Quad.
-         */
-        static class Quad extends DashIterator {
-
-            /**
-             * The val size.
-             */
-            int valSize;
-
-            /**
-             * The val pos.
-             */
-            int valPos;
-
-            /**
-             * The cur len.
-             */
-            double curLen;
-
-            /**
-             * The prev len.
-             */
-            double prevLen;
-
-            /**
-             * The last len.
-             */
-            double lastLen;
-
-            /**
-             * The values.
-             */
-            double[] values;
-
-            /**
-             * The step.
-             */
-            double step;
-
-            /**
-             * Instantiates a new quad.
-             * 
-             * @param x1
-             *            the x1.
-             * @param y1
-             *            the y1.
-             * @param x2
-             *            the x2.
-             * @param y2
-             *            the y2.
-             * @param x3
-             *            the x3.
-             * @param y3
-             *            the y3.
-             */
-            Quad(double x1, double y1, double x2, double y2, double x3, double y3) {
-
-                double nx = x1 + x3 - x2 - x2;
-                double ny = y1 + y3 - y2 - y2;
-
-                int n = (int)(1 + Math.sqrt(0.75 * (Math.abs(nx) + Math.abs(ny)) * FLATNESS));
-                step = 1.0 / n;
-
-                double ax = x1 + x3 - x2 - x2;
-                double ay = y1 + y3 - y2 - y2;
-                double bx = 2.0 * (x2 - x1);
-                double by = 2.0 * (y2 - y1);
-
-                double dx1 = step * (step * ax + bx);
-                double dy1 = step * (step * ay + by);
-                double dx2 = step * (step * ax * 2.0);
-                double dy2 = step * (step * ay * 2.0);
-                double vx = x1;
-                double vy = y1;
-
-                valSize = n;
-                values = new double[valSize];
-                double pvx = vx;
-                double pvy = vy;
-                length = 0.0;
-                for (int i = 0; i < n; i++) {
-                    vx += dx1;
-                    vy += dy1;
-                    dx1 += dx2;
-                    dy1 += dy2;
-                    double lx = vx - pvx;
-                    double ly = vy - pvy;
-                    values[i] = Math.sqrt(lx * lx + ly * ly);
-                    length += values[i];
-                    pvx = vx;
-                    pvy = vy;
-                }
-
-                valPos = 0;
-                curLen = 0.0;
-                prevLen = 0.0;
-            }
-
-            @Override
-            double getNext(double dashPos) {
-                double t = 2.0;
-                while (curLen <= dashPos && valPos < valSize) {
-                    prevLen = curLen;
-                    curLen += lastLen = values[valPos++];
-                }
-                if (curLen > dashPos) {
-                    t = (valPos - 1 + (dashPos - prevLen) / lastLen) * step;
-                }
-                return t;
-            }
-
-        }
-
-        /**
-         * The Class Cubic.
-         */
-        static class Cubic extends DashIterator {
-
-            /**
-             * The val size.
-             */
-            int valSize;
-
-            /**
-             * The val pos.
-             */
-            int valPos;
-
-            /**
-             * The cur len.
-             */
-            double curLen;
-
-            /**
-             * The prev len.
-             */
-            double prevLen;
-
-            /**
-             * The last len.
-             */
-            double lastLen;
-
-            /**
-             * The values.
-             */
-            double[] values;
-
-            /**
-             * The step.
-             */
-            double step;
-
-            /**
-             * Instantiates a new cubic.
-             * 
-             * @param x1
-             *            the x1.
-             * @param y1
-             *            the y1.
-             * @param x2
-             *            the x2.
-             * @param y2
-             *            the y2.
-             * @param x3
-             *            the x3.
-             * @param y3
-             *            the y3.
-             * @param x4
-             *            the x4.
-             * @param y4
-             *            the y4.
-             */
-            Cubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4,
-                    double y4) {
-
-                double nx1 = x1 + x3 - x2 - x2;
-                double ny1 = y1 + y3 - y2 - y2;
-                double nx2 = x2 + x4 - x3 - x3;
-                double ny2 = y2 + y4 - y3 - y3;
-
-                double max = Math.max(Math.abs(nx1) + Math.abs(ny1), Math.abs(nx2) + Math.abs(ny2));
-                int n = (int)(1 + Math.sqrt(0.75 * max) * FLATNESS);
-                step = 1.0 / n;
-
-                double ax = x4 - x1 + 3.0 * (x2 - x3);
-                double ay = y4 - y1 + 3.0 * (y2 - y3);
-                double bx = 3.0 * (x1 + x3 - x2 - x2);
-                double by = 3.0 * (y1 + y3 - y2 - y2);
-                double cx = 3.0 * (x2 - x1);
-                double cy = 3.0 * (y2 - y1);
-
-                double dx1 = step * (step * (step * ax + bx) + cx);
-                double dy1 = step * (step * (step * ay + by) + cy);
-                double dx2 = step * (step * (step * ax * 6.0 + bx * 2.0));
-                double dy2 = step * (step * (step * ay * 6.0 + by * 2.0));
-                double dx3 = step * (step * (step * ax * 6.0));
-                double dy3 = step * (step * (step * ay * 6.0));
-                double vx = x1;
-                double vy = y1;
-
-                valSize = n;
-                values = new double[valSize];
-                double pvx = vx;
-                double pvy = vy;
-                length = 0.0;
-                for (int i = 0; i < n; i++) {
-                    vx += dx1;
-                    vy += dy1;
-                    dx1 += dx2;
-                    dy1 += dy2;
-                    dx2 += dx3;
-                    dy2 += dy3;
-                    double lx = vx - pvx;
-                    double ly = vy - pvy;
-                    values[i] = Math.sqrt(lx * lx + ly * ly);
-                    length += values[i];
-                    pvx = vx;
-                    pvy = vy;
-                }
-
-                valPos = 0;
-                curLen = 0.0;
-                prevLen = 0.0;
-            }
-
-            @Override
-            double getNext(double dashPos) {
-                double t = 2.0;
-                while (curLen <= dashPos && valPos < valSize) {
-                    prevLen = curLen;
-                    curLen += lastLen = values[valPos++];
-                }
-                if (curLen > dashPos) {
-                    t = (valPos - 1 + (dashPos - prevLen) / lastLen) * step;
-                }
-                return t;
-            }
-
-        }
-
-        /**
-         * The length.
-         */
-        double length;
-
-        /**
-         * Gets the next.
-         * 
-         * @param dashPos
-         *            the dash pos.
-         * @return the next.
-         */
-        abstract double getNext(double dashPos);
-
-    }
-
-    /**
-     * BufferedPath class provides work path storing and processing.
-     */
-    static class BufferedPath {
-
-        /**
-         * The Constant bufCapacity.
-         */
-        private static final int bufCapacity = 10;
-
-        /**
-         * The point shift.
-         */
-        static int pointShift[] = {
-                2, // MOVETO
-                2, // LINETO
-                4, // QUADTO
-                6, // CUBICTO
-                0
-        }; // CLOSE
-
-        /**
-         * The types.
-         */
-        byte[] types;
-
-        /**
-         * The points.
-         */
-        float[] points;
-
-        /**
-         * The type size.
-         */
-        int typeSize;
-
-        /**
-         * The point size.
-         */
-        int pointSize;
-
-        /**
-         * The x last.
-         */
-        float xLast;
-
-        /**
-         * The y last.
-         */
-        float yLast;
-
-        /**
-         * The x move.
-         */
-        float xMove;
-
-        /**
-         * The y move.
-         */
-        float yMove;
-
-        /**
-         * Instantiates a new buffered path.
-         */
-        public BufferedPath() {
-            types = new byte[bufCapacity];
-            points = new float[bufCapacity * 2];
-        }
-
-        /**
-         * Check buf.
-         * 
-         * @param typeCount
-         *            the type count.
-         * @param pointCount
-         *            the point count.
-         */
-        void checkBuf(int typeCount, int pointCount) {
-            if (typeSize + typeCount > types.length) {
-                byte tmp[] = new byte[typeSize + Math.max(bufCapacity, typeCount)];
-                System.arraycopy(types, 0, tmp, 0, typeSize);
-                types = tmp;
-            }
-            if (pointSize + pointCount > points.length) {
-                float tmp[] = new float[pointSize + Math.max(bufCapacity * 2, pointCount)];
-                System.arraycopy(points, 0, tmp, 0, pointSize);
-                points = tmp;
-            }
-        }
-
-        /**
-         * Checks if is empty.
-         * 
-         * @return true, if is empty.
-         */
-        boolean isEmpty() {
-            return typeSize == 0;
-        }
-
-        /**
-         * Clean.
-         */
-        void clean() {
-            typeSize = 0;
-            pointSize = 0;
-        }
-
-        /**
-         * Move to.
-         * 
-         * @param x
-         *            the x.
-         * @param y
-         *            the y.
-         */
-        void moveTo(double x, double y) {
-            checkBuf(1, 2);
-            types[typeSize++] = PathIterator.SEG_MOVETO;
-            points[pointSize++] = xMove = (float)x;
-            points[pointSize++] = yMove = (float)y;
-        }
-
-        /**
-         * Line to.
-         * 
-         * @param x
-         *            the x.
-         * @param y
-         *            the y.
-         */
-        void lineTo(double x, double y) {
-            checkBuf(1, 2);
-            types[typeSize++] = PathIterator.SEG_LINETO;
-            points[pointSize++] = xLast = (float)x;
-            points[pointSize++] = yLast = (float)y;
-        }
-
-        /**
-         * Quad to.
-         * 
-         * @param x1
-         *            the x1.
-         * @param y1
-         *            the y1.
-         * @param x2
-         *            the x2.
-         * @param y2
-         *            the y2.
-         */
-        void quadTo(double x1, double y1, double x2, double y2) {
-            checkBuf(1, 4);
-            types[typeSize++] = PathIterator.SEG_QUADTO;
-            points[pointSize++] = (float)x1;
-            points[pointSize++] = (float)y1;
-            points[pointSize++] = xLast = (float)x2;
-            points[pointSize++] = yLast = (float)y2;
-        }
-
-        /**
-         * Cubic to.
-         * 
-         * @param x1
-         *            the x1.
-         * @param y1
-         *            the y1.
-         * @param x2
-         *            the x2.
-         * @param y2
-         *            the y2.
-         * @param x3
-         *            the x3.
-         * @param y3
-         *            the y3.
-         */
-        void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3) {
-            checkBuf(1, 6);
-            types[typeSize++] = PathIterator.SEG_CUBICTO;
-            points[pointSize++] = (float)x1;
-            points[pointSize++] = (float)y1;
-            points[pointSize++] = (float)x2;
-            points[pointSize++] = (float)y2;
-            points[pointSize++] = xLast = (float)x3;
-            points[pointSize++] = yLast = (float)y3;
-        }
-
-        /**
-         * Close path.
-         */
-        void closePath() {
-            checkBuf(1, 0);
-            types[typeSize++] = PathIterator.SEG_CLOSE;
-        }
-
-        /**
-         * Sets the last.
-         * 
-         * @param x
-         *            the x.
-         * @param y
-         *            the y.
-         */
-        void setLast(double x, double y) {
-            points[pointSize - 2] = xLast = (float)x;
-            points[pointSize - 1] = yLast = (float)y;
-        }
-
-        /**
-         * Append.
-         * 
-         * @param p
-         *            the p.
-         */
-        void append(BufferedPath p) {
-            checkBuf(p.typeSize, p.pointSize);
-            System.arraycopy(p.points, 0, points, pointSize, p.pointSize);
-            System.arraycopy(p.types, 0, types, typeSize, p.typeSize);
-            pointSize += p.pointSize;
-            typeSize += p.typeSize;
-            xLast = points[pointSize - 2];
-            yLast = points[pointSize - 1];
-        }
-
-        /**
-         * Append reverse.
-         * 
-         * @param p
-         *            the p.
-         */
-        void appendReverse(BufferedPath p) {
-            checkBuf(p.typeSize, p.pointSize);
-            // Skip last point, beacause it's the first point of the second path
-            for (int i = p.pointSize - 2; i >= 0; i -= 2) {
-                points[pointSize++] = p.points[i + 0];
-                points[pointSize++] = p.points[i + 1];
-            }
-            // Skip first type, beacuse it's always MOVETO
-            int closeIndex = 0;
-            for (int i = p.typeSize - 1; i >= 0; i--) {
-                byte type = p.types[i];
-                if (type == PathIterator.SEG_MOVETO) {
-                    types[closeIndex] = PathIterator.SEG_MOVETO;
-                    types[typeSize++] = PathIterator.SEG_CLOSE;
-                } else {
-                    if (type == PathIterator.SEG_CLOSE) {
-                        closeIndex = typeSize;
-                    }
-                    types[typeSize++] = type;
-                }
-            }
-            xLast = points[pointSize - 2];
-            yLast = points[pointSize - 1];
-        }
-
-        /**
-         * Join.
-         * 
-         * @param p
-         *            the p.
-         */
-        void join(BufferedPath p) {
-            // Skip MOVETO
-            checkBuf(p.typeSize - 1, p.pointSize - 2);
-            System.arraycopy(p.points, 2, points, pointSize, p.pointSize - 2);
-            System.arraycopy(p.types, 1, types, typeSize, p.typeSize - 1);
-            pointSize += p.pointSize - 2;
-            typeSize += p.typeSize - 1;
-            xLast = points[pointSize - 2];
-            yLast = points[pointSize - 1];
-        }
-
-        /**
-         * Combine.
-         * 
-         * @param p
-         *            the p.
-         */
-        void combine(BufferedPath p) {
-            checkBuf(p.typeSize - 1, p.pointSize - 2);
-            // Skip last point, beacause it's the first point of the second path
-            for (int i = p.pointSize - 4; i >= 0; i -= 2) {
-                points[pointSize++] = p.points[i + 0];
-                points[pointSize++] = p.points[i + 1];
-            }
-            // Skip first type, beacuse it's always MOVETO
-            for (int i = p.typeSize - 1; i >= 1; i--) {
-                types[typeSize++] = p.types[i];
-            }
-            xLast = points[pointSize - 2];
-            yLast = points[pointSize - 1];
-        }
-
-        /**
-         * Creates the general path.
-         * 
-         * @return the general path.
-         */
-        GeneralPath createGeneralPath() {
-            GeneralPath p = new GeneralPath();
-            int j = 0;
-            for (int i = 0; i < typeSize; i++) {
-                int type = types[i];
-                switch (type) {
-                    case PathIterator.SEG_MOVETO:
-                        p.moveTo(points[j], points[j + 1]);
-                        break;
-                    case PathIterator.SEG_LINETO:
-                        p.lineTo(points[j], points[j + 1]);
-                        break;
-                    case PathIterator.SEG_QUADTO:
-                        p.quadTo(points[j], points[j + 1], points[j + 2], points[j + 3]);
-                        break;
-                    case PathIterator.SEG_CUBICTO:
-                        p.curveTo(points[j], points[j + 1], points[j + 2], points[j + 3],
-                                points[j + 4], points[j + 5]);
-                        break;
-                    case PathIterator.SEG_CLOSE:
-                        p.closePath();
-                        break;
-                }
-                j += pointShift[type];
-            }
-            return p;
-        }
-
-    }
-
-}
diff --git a/awt/java/awt/BufferCapabilities.java b/awt/java/awt/BufferCapabilities.java
deleted file mode 100644
index cd5fe7b..0000000
--- a/awt/java/awt/BufferCapabilities.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * The BufferCapabilities class represents the capabilities and other properties
- * of the image buffers.
- * 
- * @since Android 1.0
- */
-public class BufferCapabilities implements Cloneable {
-
-    /**
-     * The front buffer capabilities.
-     */
-    private final ImageCapabilities frontBufferCapabilities;
-
-    /**
-     * The back buffer capabilities.
-     */
-    private final ImageCapabilities backBufferCapabilities;
-
-    /**
-     * The flip contents.
-     */
-    private final FlipContents flipContents;
-
-    /**
-     * Instantiates a new BufferCapabilities object.
-     * 
-     * @param frontBufferCapabilities
-     *            the front buffer capabilities, can not be null.
-     * @param backBufferCapabilities
-     *            the the back and intermediate buffers capabilities, can not be
-     *            null.
-     * @param flipContents
-     *            the back buffer contents after page flipping, null if page
-     *            flipping is not used.
-     */
-    public BufferCapabilities(ImageCapabilities frontBufferCapabilities,
-            ImageCapabilities backBufferCapabilities, FlipContents flipContents) {
-        if (frontBufferCapabilities == null || backBufferCapabilities == null) {
-            throw new IllegalArgumentException();
-        }
-
-        this.frontBufferCapabilities = frontBufferCapabilities;
-        this.backBufferCapabilities = backBufferCapabilities;
-        this.flipContents = flipContents;
-    }
-
-    /**
-     * Returns a copy of the BufferCapabilities object.
-     * 
-     * @return a copy of the BufferCapabilities object.
-     */
-    @Override
-    public Object clone() {
-        return new BufferCapabilities(frontBufferCapabilities, backBufferCapabilities, flipContents);
-    }
-
-    /**
-     * Gets the image capabilities of the front buffer.
-     * 
-     * @return the ImageCapabilities object represented capabilities of the
-     *         front buffer.
-     */
-    public ImageCapabilities getFrontBufferCapabilities() {
-        return frontBufferCapabilities;
-    }
-
-    /**
-     * Gets the image capabilities of the back buffer.
-     * 
-     * @return the ImageCapabilities object represented capabilities of the back
-     *         buffer.
-     */
-    public ImageCapabilities getBackBufferCapabilities() {
-        return backBufferCapabilities;
-    }
-
-    /**
-     * Gets the flip contents of the back buffer after page-flipping.
-     * 
-     * @return the FlipContents of the back buffer after page-flipping.
-     */
-    public FlipContents getFlipContents() {
-        return flipContents;
-    }
-
-    /**
-     * Checks if the buffer strategy uses page flipping.
-     * 
-     * @return true, if the buffer strategy uses page flipping, false otherwise.
-     */
-    public boolean isPageFlipping() {
-        return flipContents != null;
-    }
-
-    /**
-     * Checks if page flipping is only available in full-screen mode.
-     * 
-     * @return true, if page flipping is only available in full-screen mode,
-     *         false otherwise.
-     */
-    public boolean isFullScreenRequired() {
-        return false;
-    }
-
-    /**
-     * Checks if page flipping can be performed using more than two buffers.
-     * 
-     * @return true, if page flipping can be performed using more than two
-     *         buffers, false otherwise.
-     */
-    public boolean isMultiBufferAvailable() {
-        return false;
-    }
-
-    /**
-     * The FlipContents class represents a set of possible back buffer contents
-     * after page-flipping.
-     * 
-     * @since Android 1.0
-     */
-    public static final class FlipContents {
-
-        /**
-         * The back buffered contents are cleared with the background color
-         * after flipping.
-         */
-        public static final FlipContents BACKGROUND = new FlipContents();
-
-        /**
-         * The back buffered contents are copied to the front buffer before
-         * flipping.
-         */
-        public static final FlipContents COPIED = new FlipContents();
-
-        /**
-         * The back buffer contents are the prior contents of the front buffer.
-         */
-        public static final FlipContents PRIOR = new FlipContents();
-
-        /**
-         * The back buffer contents are undefined after flipping
-         */
-        public static final FlipContents UNDEFINED = new FlipContents();
-
-        /**
-         * Instantiates a new flip contents.
-         */
-        private FlipContents() {
-
-        }
-
-        /**
-         * Returns the hash code of the FlipContents object.
-         * 
-         * @return the hash code of the FlipContents object.
-         */
-        @Override
-        public int hashCode() {
-            return super.hashCode();
-        }
-
-        /**
-         * Returns the String representation of the FlipContents object.
-         * 
-         * @return the string
-         */
-        @Override
-        public String toString() {
-            return super.toString();
-        }
-    }
-}
diff --git a/awt/java/awt/Color.java b/awt/java/awt/Color.java
deleted file mode 100644
index 93c532d..0000000
--- a/awt/java/awt/Color.java
+++ /dev/null
@@ -1,990 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.color.ColorSpace;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBufferInt;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-import java.io.Serializable;
-import java.util.Arrays;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Color class defines colors in the default sRGB color space or in the
- * specified ColorSpace. Every Color contains alpha value. The alpha value
- * defines the transparency of a color and can be represented by a float value
- * in the range 0.0 - 1.0 or 0 - 255.
- * 
- * @since Android 1.0
- */
-public class Color implements Paint, Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 118526816881161077L;
-
-    /*
-     * The values of the following colors are based on 1.5 release behavior
-     * which can be revealed using the following or similar code: Color c =
-     * Color.white; System.out.println(c);
-     */
-
-    /**
-     * The color white.
-     */
-    public static final Color white = new Color(255, 255, 255);
-
-    /**
-     * The color white.
-     */
-    public static final Color WHITE = white;
-
-    /**
-     * The color light gray.
-     */
-    public static final Color lightGray = new Color(192, 192, 192);
-
-    /**
-     * The color light gray.
-     */
-    public static final Color LIGHT_GRAY = lightGray;
-
-    /**
-     * The color gray.
-     */
-    public static final Color gray = new Color(128, 128, 128);
-
-    /**
-     * The color gray.
-     */
-    public static final Color GRAY = gray;
-
-    /**
-     * The color dark gray.
-     */
-    public static final Color darkGray = new Color(64, 64, 64);
-
-    /**
-     * The color dark gray.
-     */
-    public static final Color DARK_GRAY = darkGray;
-
-    /**
-     * The color black.
-     */
-    public static final Color black = new Color(0, 0, 0);
-
-    /**
-     * The color black.
-     */
-    public static final Color BLACK = black;
-
-    /**
-     * The color red.
-     */
-    public static final Color red = new Color(255, 0, 0);
-
-    /**
-     * The color red.
-     */
-    public static final Color RED = red;
-
-    /**
-     * The color pink.
-     */
-    public static final Color pink = new Color(255, 175, 175);
-
-    /**
-     * The color pink.
-     */
-    public static final Color PINK = pink;
-
-    /**
-     * The color orange.
-     */
-    public static final Color orange = new Color(255, 200, 0);
-
-    /**
-     * The color orange.
-     */
-    public static final Color ORANGE = orange;
-
-    /**
-     * The color yellow.
-     */
-    public static final Color yellow = new Color(255, 255, 0);
-
-    /**
-     * The color yellow.
-     */
-    public static final Color YELLOW = yellow;
-
-    /**
-     * The color green.
-     */
-    public static final Color green = new Color(0, 255, 0);
-
-    /**
-     * The color green.
-     */
-    public static final Color GREEN = green;
-
-    /**
-     * The color magenta.
-     */
-    public static final Color magenta = new Color(255, 0, 255);
-
-    /**
-     * The color magenta.
-     */
-    public static final Color MAGENTA = magenta;
-
-    /**
-     * The color cyan.
-     */
-    public static final Color cyan = new Color(0, 255, 255);
-
-    /**
-     * The color cyan.
-     */
-    public static final Color CYAN = cyan;
-
-    /**
-     * The color blue.
-     */
-    public static final Color blue = new Color(0, 0, 255);
-
-    /**
-     * The color blue.
-     */
-    public static final Color BLUE = blue;
-
-    /**
-     * integer RGB value.
-     */
-    int value;
-
-    /**
-     * Float sRGB value.
-     */
-    private float[] frgbvalue;
-
-    /**
-     * Color in an arbitrary color space with <code>float</code> components. If
-     * null, other value should be used.
-     */
-    private float fvalue[];
-
-    /**
-     * Float alpha value. If frgbvalue is null, this is not valid data.
-     */
-    private float falpha;
-
-    /**
-     * The color's color space if applicable.
-     */
-    private ColorSpace cs;
-
-    /*
-     * The value of the SCALE_FACTOR is based on 1.5 release behavior which can
-     * be revealed using the following code: Color c = new Color(100, 100, 100);
-     * Color bc = c.brighter(); System.out.println("Brighter factor: " +
-     * ((float)c.getRed())/((float)bc.getRed())); Color dc = c.darker();
-     * System.out.println("Darker factor: " +
-     * ((float)dc.getRed())/((float)c.getRed())); The result is the same for
-     * brighter and darker methods, so we need only one scale factor for both.
-     */
-    /**
-     * The Constant SCALE_FACTOR.
-     */
-    private static final double SCALE_FACTOR = 0.7;
-
-    /**
-     * The Constant MIN_SCALABLE.
-     */
-    private static final int MIN_SCALABLE = 3; // should increase when
-
-    // multiplied by SCALE_FACTOR
-
-    /**
-     * The current paint context.
-     */
-    transient private PaintContext currentPaintContext;
-
-    /**
-     * Creates a color in the specified ColorSpace, the specified color
-     * components and the specified alpha.
-     * 
-     * @param cspace
-     *            the ColorSpace to be used to define the components.
-     * @param components
-     *            the components.
-     * @param alpha
-     *            the alpha.
-     */
-    public Color(ColorSpace cspace, float[] components, float alpha) {
-        int nComps = cspace.getNumComponents();
-        float comp;
-        fvalue = new float[nComps];
-
-        for (int i = 0; i < nComps; i++) {
-            comp = components[i];
-            if (comp < 0.0f || comp > 1.0f) {
-                // awt.107=Color parameter outside of expected range: component
-                // {0}.
-                throw new IllegalArgumentException(Messages.getString("awt.107", i)); //$NON-NLS-1$
-            }
-            fvalue[i] = components[i];
-        }
-
-        if (alpha < 0.0f || alpha > 1.0f) {
-            // awt.108=Alpha value outside of expected range.
-            throw new IllegalArgumentException(Messages.getString("awt.108")); //$NON-NLS-1$
-        }
-        falpha = alpha;
-
-        cs = cspace;
-
-        frgbvalue = cs.toRGB(fvalue);
-
-        value = ((int)(frgbvalue[2] * 255 + 0.5)) | (((int)(frgbvalue[1] * 255 + 0.5)) << 8)
-                | (((int)(frgbvalue[0] * 255 + 0.5)) << 16) | (((int)(falpha * 255 + 0.5)) << 24);
-    }
-
-    /**
-     * Instantiates a new sRGB color with the specified combined RGBA value
-     * consisting of the alpha component in bits 24-31, the red component in
-     * bits 16-23, the green component in bits 8-15, and the blue component in
-     * bits 0-7. If the hasalpha argument is false, the alpha has default value
-     * - 255.
-     * 
-     * @param rgba
-     *            the RGBA components.
-     * @param hasAlpha
-     *            the alpha parameter is true if alpha bits are valid, false
-     *            otherwise.
-     */
-    public Color(int rgba, boolean hasAlpha) {
-        if (!hasAlpha) {
-            value = rgba | 0xFF000000;
-        } else {
-            value = rgba;
-        }
-    }
-
-    /**
-     * Instantiates a new color with the specified red, green, blue and alpha
-     * components.
-     * 
-     * @param r
-     *            the red component.
-     * @param g
-     *            the green component.
-     * @param b
-     *            the blue component.
-     * @param a
-     *            the alpha component.
-     */
-    public Color(int r, int g, int b, int a) {
-        if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b || (a & 0xFF) != a) {
-            // awt.109=Color parameter outside of expected range.
-            throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
-        }
-        value = b | (g << 8) | (r << 16) | (a << 24);
-    }
-
-    /**
-     * Instantiates a new opaque sRGB color with the specified red, green, and
-     * blue values. The Alpha component is set to the default - 1.0.
-     * 
-     * @param r
-     *            the red component.
-     * @param g
-     *            the green component.
-     * @param b
-     *            the blue component.
-     */
-    public Color(int r, int g, int b) {
-        if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b) {
-            // awt.109=Color parameter outside of expected range.
-            throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
-        }
-        // 0xFF for alpha channel
-        value = b | (g << 8) | (r << 16) | 0xFF000000;
-    }
-
-    /**
-     * Instantiates a new sRGB color with the specified RGB value consisting of
-     * the red component in bits 16-23, the green component in bits 8-15, and
-     * the blue component in bits 0-7. Alpha has default value - 255.
-     * 
-     * @param rgb
-     *            the RGB components.
-     */
-    public Color(int rgb) {
-        value = rgb | 0xFF000000;
-    }
-
-    /**
-     * Instantiates a new color with the specified red, green, blue and alpha
-     * components.
-     * 
-     * @param r
-     *            the red component.
-     * @param g
-     *            the green component.
-     * @param b
-     *            the blue component.
-     * @param a
-     *            the alpha component.
-     */
-    public Color(float r, float g, float b, float a) {
-        this((int)(r * 255 + 0.5), (int)(g * 255 + 0.5), (int)(b * 255 + 0.5), (int)(a * 255 + 0.5));
-        falpha = a;
-        fvalue = new float[3];
-        fvalue[0] = r;
-        fvalue[1] = g;
-        fvalue[2] = b;
-        frgbvalue = fvalue;
-    }
-
-    /**
-     * Instantiates a new color with the specified red, green, and blue
-     * components and default alpha value - 1.0.
-     * 
-     * @param r
-     *            the red component.
-     * @param g
-     *            the green component.
-     * @param b
-     *            the blue component.
-     */
-    public Color(float r, float g, float b) {
-        this(r, g, b, 1.0f);
-    }
-
-    public PaintContext createContext(ColorModel cm, Rectangle r, Rectangle2D r2d,
-            AffineTransform xform, RenderingHints rhs) {
-        if (currentPaintContext != null) {
-            return currentPaintContext;
-        }
-        currentPaintContext = new Color.ColorPaintContext(value);
-        return currentPaintContext;
-    }
-
-    /**
-     * Returns a string representation of the Color object.
-     * 
-     * @return the string representation of the Color object.
-     */
-    @Override
-    public String toString() {
-        /*
-         * The format of the string is based on 1.5 release behavior which can
-         * be revealed using the following code: Color c = new Color(1, 2, 3);
-         * System.out.println(c);
-         */
-
-        return getClass().getName() + "[r=" + getRed() + //$NON-NLS-1$
-                ",g=" + getGreen() + //$NON-NLS-1$
-                ",b=" + getBlue() + //$NON-NLS-1$
-                "]"; //$NON-NLS-1$
-    }
-
-    /**
-     * Compares the specified Object to the Color.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if the specified Object is a Color whose value is equal to
-     *         this Color, false otherwise.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof Color) {
-            return ((Color)obj).value == this.value;
-        }
-        return false;
-    }
-
-    /**
-     * Returns a float array containing the color and alpha components of the
-     * Color in the specified ColorSpace.
-     * 
-     * @param colorSpace
-     *            the specified ColorSpace.
-     * @param components
-     *            the results of this method will be written to this float
-     *            array. If null, a float array will be created.
-     * @return the color and alpha components in a float array.
-     */
-    public float[] getComponents(ColorSpace colorSpace, float[] components) {
-        int nComps = colorSpace.getNumComponents();
-        if (components == null) {
-            components = new float[nComps + 1];
-        }
-
-        getColorComponents(colorSpace, components);
-
-        if (frgbvalue != null) {
-            components[nComps] = falpha;
-        } else {
-            components[nComps] = getAlpha() / 255f;
-        }
-
-        return components;
-    }
-
-    /**
-     * Returns a float array containing the color components of the Color in the
-     * specified ColorSpace.
-     * 
-     * @param colorSpace
-     *            the specified ColorSpace.
-     * @param components
-     *            the results of this method will be written to this float
-     *            array. If null, a float array will be created.
-     * @return the color components in a float array.
-     */
-    public float[] getColorComponents(ColorSpace colorSpace, float[] components) {
-        float[] cieXYZComponents = getColorSpace().toCIEXYZ(getColorComponents(null));
-        float[] csComponents = colorSpace.fromCIEXYZ(cieXYZComponents);
-
-        if (components == null) {
-            return csComponents;
-        }
-
-        for (int i = 0; i < csComponents.length; i++) {
-            components[i] = csComponents[i];
-        }
-
-        return components;
-    }
-
-    /**
-     * Gets the ColorSpace of this Color.
-     * 
-     * @return the ColorSpace object.
-     */
-    public ColorSpace getColorSpace() {
-        if (cs == null) {
-            cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-        }
-
-        return cs;
-    }
-
-    /**
-     * Creates a new Color which is a darker than this Color according to a
-     * fixed scale factor.
-     * 
-     * @return the darker Color.
-     */
-    public Color darker() {
-        return new Color((int)(getRed() * SCALE_FACTOR), (int)(getGreen() * SCALE_FACTOR),
-                (int)(getBlue() * SCALE_FACTOR));
-    }
-
-    /**
-     * Creates a new Color which is a brighter than this Color.
-     * 
-     * @return the brighter Color.
-     */
-    public Color brighter() {
-
-        int r = getRed();
-        int b = getBlue();
-        int g = getGreen();
-
-        if (r == 0 && b == 0 && g == 0) {
-            return new Color(MIN_SCALABLE, MIN_SCALABLE, MIN_SCALABLE);
-        }
-
-        if (r < MIN_SCALABLE && r != 0) {
-            r = MIN_SCALABLE;
-        } else {
-            r = (int)(r / SCALE_FACTOR);
-            r = (r > 255) ? 255 : r;
-        }
-
-        if (b < MIN_SCALABLE && b != 0) {
-            b = MIN_SCALABLE;
-        } else {
-            b = (int)(b / SCALE_FACTOR);
-            b = (b > 255) ? 255 : b;
-        }
-
-        if (g < MIN_SCALABLE && g != 0) {
-            g = MIN_SCALABLE;
-        } else {
-            g = (int)(g / SCALE_FACTOR);
-            g = (g > 255) ? 255 : g;
-        }
-
-        return new Color(r, g, b);
-    }
-
-    /**
-     * Returns a float array containing the color and alpha components of the
-     * Color in the default sRGB color space.
-     * 
-     * @param components
-     *            the results of this method will be written to this float
-     *            array. A new float array will be created if this argument is
-     *            null.
-     * @return the RGB color and alpha components in a float array.
-     */
-    public float[] getRGBComponents(float[] components) {
-        if (components == null) {
-            components = new float[4];
-        }
-
-        if (frgbvalue != null) {
-            components[3] = falpha;
-        } else {
-            components[3] = getAlpha() / 255f;
-        }
-
-        getRGBColorComponents(components);
-
-        return components;
-    }
-
-    /**
-     * Returns a float array containing the color components of the Color in the
-     * default sRGB color space.
-     * 
-     * @param components
-     *            the results of this method will be written to this float
-     *            array. A new float array will be created if this argument is
-     *            null.
-     * @return the RGB color components in a float array.
-     */
-    public float[] getRGBColorComponents(float[] components) {
-        if (components == null) {
-            components = new float[3];
-        }
-
-        if (frgbvalue != null) {
-            components[2] = frgbvalue[2];
-            components[1] = frgbvalue[1];
-            components[0] = frgbvalue[0];
-        } else {
-            components[2] = getBlue() / 255f;
-            components[1] = getGreen() / 255f;
-            components[0] = getRed() / 255f;
-        }
-
-        return components;
-    }
-
-    /**
-     * Returns a float array which contains the color and alpha components of
-     * the Color in the ColorSpace of the Color.
-     * 
-     * @param components
-     *            the results of this method will be written to this float
-     *            array. A new float array will be created if this argument is
-     *            null.
-     * @return the color and alpha components in a float array.
-     */
-    public float[] getComponents(float[] components) {
-        if (fvalue == null) {
-            return getRGBComponents(components);
-        }
-
-        int nColorComps = fvalue.length;
-
-        if (components == null) {
-            components = new float[nColorComps + 1];
-        }
-
-        getColorComponents(components);
-
-        components[nColorComps] = falpha;
-
-        return components;
-    }
-
-    /**
-     * Returns a float array which contains the color components of the Color in
-     * the ColorSpace of the Color.
-     * 
-     * @param components
-     *            the results of this method will be written to this float
-     *            array. A new float array will be created if this argument is
-     *            null.
-     * @return the color components in a float array.
-     */
-    public float[] getColorComponents(float[] components) {
-        if (fvalue == null) {
-            return getRGBColorComponents(components);
-        }
-
-        if (components == null) {
-            components = new float[fvalue.length];
-        }
-
-        for (int i = 0; i < fvalue.length; i++) {
-            components[i] = fvalue[i];
-        }
-
-        return components;
-    }
-
-    /**
-     * Returns a hash code of this Color object.
-     * 
-     * @return a hash code of this Color object.
-     */
-    @Override
-    public int hashCode() {
-        return value;
-    }
-
-    public int getTransparency() {
-        switch (getAlpha()) {
-            case 0xff:
-                return Transparency.OPAQUE;
-            case 0:
-                return Transparency.BITMASK;
-            default:
-                return Transparency.TRANSLUCENT;
-        }
-    }
-
-    /**
-     * Gets the red component of the Color in the range 0-255.
-     * 
-     * @return the red component of the Color.
-     */
-    public int getRed() {
-        return (value >> 16) & 0xFF;
-    }
-
-    /**
-     * Gets the RGB value that represents the color in the default sRGB
-     * ColorModel.
-     * 
-     * @return the RGB color value in the default sRGB ColorModel.
-     */
-    public int getRGB() {
-        return value;
-    }
-
-    /**
-     * Gets the green component of the Color in the range 0-255.
-     * 
-     * @return the green component of the Color.
-     */
-    public int getGreen() {
-        return (value >> 8) & 0xFF;
-    }
-
-    /**
-     * Gets the blue component of the Color in the range 0-255.
-     * 
-     * @return the blue component of the Color.
-     */
-    public int getBlue() {
-        return value & 0xFF;
-    }
-
-    /**
-     * Gets the alpha component of the Color in the range 0-255.
-     * 
-     * @return the alpha component of the Color.
-     */
-    public int getAlpha() {
-        return (value >> 24) & 0xFF;
-    }
-
-    /**
-     * Gets the Color from the specified string, or returns the Color specified
-     * by the second parameter.
-     * 
-     * @param nm
-     *            the specified string.
-     * @param def
-     *            the default Color.
-     * @return the color from the specified string, or the Color specified by
-     *         the second parameter.
-     */
-    public static Color getColor(String nm, Color def) {
-        Integer integer = Integer.getInteger(nm);
-
-        if (integer == null) {
-            return def;
-        }
-
-        return new Color(integer.intValue());
-    }
-
-    /**
-     * Gets the Color from the specified string, or returns the Color converted
-     * from the second parameter.
-     * 
-     * @param nm
-     *            the specified string.
-     * @param def
-     *            the default Color.
-     * @return the color from the specified string, or the Color converted from
-     *         the second parameter.
-     */
-    public static Color getColor(String nm, int def) {
-        Integer integer = Integer.getInteger(nm);
-
-        if (integer == null) {
-            return new Color(def);
-        }
-
-        return new Color(integer.intValue());
-    }
-
-    /**
-     * Gets the Color from the specified String.
-     * 
-     * @param nm
-     *            the specified string.
-     * @return the Color object, or null.
-     */
-    public static Color getColor(String nm) {
-        Integer integer = Integer.getInteger(nm);
-
-        if (integer == null) {
-            return null;
-        }
-
-        return new Color(integer.intValue());
-    }
-
-    /**
-     * Decodes a String to an integer and returns the specified opaque Color.
-     * 
-     * @param nm
-     *            the String which represents an opaque color as a 24-bit
-     *            integer.
-     * @return the Color object from the given String.
-     * @throws NumberFormatException
-     *             if the specified string can not be converted to an integer.
-     */
-    public static Color decode(String nm) throws NumberFormatException {
-        Integer integer = Integer.decode(nm);
-        return new Color(integer.intValue());
-    }
-
-    /**
-     * Gets a Color object using the specified values of the HSB color model.
-     * 
-     * @param h
-     *            the hue component of the Color.
-     * @param s
-     *            the saturation of the Color.
-     * @param b
-     *            the brightness of the Color.
-     * @return a color object with the specified hue, saturation and brightness
-     *         values.
-     */
-    public static Color getHSBColor(float h, float s, float b) {
-        return new Color(HSBtoRGB(h, s, b));
-    }
-
-    /**
-     * Converts the Color specified by the RGB model to an equivalent color in
-     * the HSB model.
-     * 
-     * @param r
-     *            the red component.
-     * @param g
-     *            the green component.
-     * @param b
-     *            the blue component.
-     * @param hsbvals
-     *            the array of result hue, saturation, brightness values or
-     *            null.
-     * @return the float array of hue, saturation, brightness values.
-     */
-    public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
-        if (hsbvals == null) {
-            hsbvals = new float[3];
-        }
-
-        int V = Math.max(b, Math.max(r, g));
-        int temp = Math.min(b, Math.min(r, g));
-
-        float H, S, B;
-
-        B = V / 255.f;
-
-        if (V == temp) {
-            H = S = 0;
-        } else {
-            S = (V - temp) / ((float)V);
-
-            float Cr = (V - r) / (float)(V - temp);
-            float Cg = (V - g) / (float)(V - temp);
-            float Cb = (V - b) / (float)(V - temp);
-
-            if (r == V) {
-                H = Cb - Cg;
-            } else if (g == V) {
-                H = 2 + Cr - Cb;
-            } else {
-                H = 4 + Cg - Cr;
-            }
-
-            H /= 6.f;
-            if (H < 0) {
-                H++;
-            }
-        }
-
-        hsbvals[0] = H;
-        hsbvals[1] = S;
-        hsbvals[2] = B;
-
-        return hsbvals;
-    }
-
-    /**
-     * Converts the Color specified by the HSB model to an equivalent color in
-     * the default RGB model.
-     * 
-     * @param hue
-     *            the hue component of the Color.
-     * @param saturation
-     *            the saturation of the Color.
-     * @param brightness
-     *            the brightness of the Color.
-     * @return the RGB value of the color with the specified hue, saturation and
-     *         brightness.
-     */
-    public static int HSBtoRGB(float hue, float saturation, float brightness) {
-        float fr, fg, fb;
-
-        if (saturation == 0) {
-            fr = fg = fb = brightness;
-        } else {
-            float H = (hue - (float)Math.floor(hue)) * 6;
-            int I = (int)Math.floor(H);
-            float F = H - I;
-            float M = brightness * (1 - saturation);
-            float N = brightness * (1 - saturation * F);
-            float K = brightness * (1 - saturation * (1 - F));
-
-            switch (I) {
-                case 0:
-                    fr = brightness;
-                    fg = K;
-                    fb = M;
-                    break;
-                case 1:
-                    fr = N;
-                    fg = brightness;
-                    fb = M;
-                    break;
-                case 2:
-                    fr = M;
-                    fg = brightness;
-                    fb = K;
-                    break;
-                case 3:
-                    fr = M;
-                    fg = N;
-                    fb = brightness;
-                    break;
-                case 4:
-                    fr = K;
-                    fg = M;
-                    fb = brightness;
-                    break;
-                case 5:
-                    fr = brightness;
-                    fg = M;
-                    fb = N;
-                    break;
-                default:
-                    fr = fb = fg = 0; // impossible, to supress compiler error
-            }
-        }
-
-        int r = (int)(fr * 255. + 0.5);
-        int g = (int)(fg * 255. + 0.5);
-        int b = (int)(fb * 255. + 0.5);
-
-        return (r << 16) | (g << 8) | b | 0xFF000000;
-    }
-
-    /**
-     * The Class ColorPaintContext.
-     */
-    class ColorPaintContext implements PaintContext {
-
-        /**
-         * The RGB value.
-         */
-        int rgbValue;
-
-        /**
-         * The saved raster.
-         */
-        WritableRaster savedRaster = null;
-
-        /**
-         * Instantiates a new color paint context.
-         * 
-         * @param rgb
-         *            the RGB value.
-         */
-        protected ColorPaintContext(int rgb) {
-            rgbValue = rgb;
-        }
-
-        public void dispose() {
-            savedRaster = null;
-        }
-
-        public ColorModel getColorModel() {
-            return ColorModel.getRGBdefault();
-        }
-
-        public Raster getRaster(int x, int y, int w, int h) {
-            if (savedRaster == null || w != savedRaster.getWidth() || h != savedRaster.getHeight()) {
-                savedRaster = getColorModel().createCompatibleWritableRaster(w, h);
-
-                // Suppose we have here simple INT/RGB color/sample model
-                DataBufferInt intBuffer = (DataBufferInt)savedRaster.getDataBuffer();
-                int rgbValues[] = intBuffer.getData();
-                int rgbFillValue = rgbValue;
-                Arrays.fill(rgbValues, rgbFillValue);
-            }
-
-            return savedRaster;
-        }
-    }
-}
diff --git a/awt/java/awt/Component.java b/awt/java/awt/Component.java
deleted file mode 100644
index c52a9f4..0000000
--- a/awt/java/awt/Component.java
+++ /dev/null
@@ -1,6020 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.awt;
-
-//import java.awt.dnd.DropTarget;
-import java.awt.event.ComponentEvent;
-import java.awt.event.ComponentListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
-import java.awt.event.HierarchyBoundsListener;
-import java.awt.event.HierarchyEvent;
-import java.awt.event.HierarchyListener;
-import java.awt.event.InputMethodEvent;
-import java.awt.event.InputMethodListener;
-import java.awt.event.InvocationEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
-import java.awt.event.PaintEvent;
-import java.awt.event.WindowEvent;
-import java.awt.im.InputContext;
-import java.awt.im.InputMethodRequests;
-import java.awt.image.BufferStrategy;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.ImageObserver;
-import java.awt.image.ImageProducer;
-import java.awt.image.VolatileImage;
-import java.awt.image.WritableRaster;
-import java.awt.peer.ComponentPeer;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EventListener;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-//???AWT
-//import javax.accessibility.Accessible;
-//import javax.accessibility.AccessibleComponent;
-//import javax.accessibility.AccessibleContext;
-//import javax.accessibility.AccessibleRole;
-//import javax.accessibility.AccessibleState;
-//import javax.accessibility.AccessibleStateSet;
-
-import org.apache.harmony.awt.ClipRegion; //import org.apache.harmony.awt.FieldsAccessor;
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.awt.state.State; //import org.apache.harmony.awt.text.TextFieldKit;
-//import org.apache.harmony.awt.text.TextKit;
-import org.apache.harmony.awt.wtk.NativeWindow;
-import org.apache.harmony.luni.util.NotImplementedException;
-
-/**
- * The abstract Component class specifies an object with a graphical
- * representation that can be displayed on the screen and that can interact with
- * the user (for example: scrollbars, buttons, checkboxes).
- * 
- * @since Android 1.0
- */
-public abstract class Component implements ImageObserver, MenuContainer, Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -7644114512714619750L;
-
-    /**
-     * The Constant TOP_ALIGNMENT indicates the top alignment of the component.
-     */
-    public static final float TOP_ALIGNMENT = 0.0f;
-
-    /**
-     * The Constant CENTER_ALIGNMENT indicates the center alignment of the
-     * component.
-     */
-    public static final float CENTER_ALIGNMENT = 0.5f;
-
-    /**
-     * The Constant BOTTOM_ALIGNMENT indicates the bottom alignment of the
-     * component.
-     */
-    public static final float BOTTOM_ALIGNMENT = 1.0f;
-
-    /**
-     * The Constant LEFT_ALIGNMENT indicates the left alignment of the
-     * component.
-     */
-    public static final float LEFT_ALIGNMENT = 0.0f;
-
-    /**
-     * The Constant RIGHT_ALIGNMENT indicates the right alignment of the
-     * component.
-     */
-    public static final float RIGHT_ALIGNMENT = 1.0f;
-
-    /**
-     * The Constant childClassesFlags.
-     */
-    private static final Hashtable<Class<?>, Boolean> childClassesFlags = new Hashtable<Class<?>, Boolean>();
-
-    /**
-     * The Constant peer.
-     */
-    private static final ComponentPeer peer = new ComponentPeer() {
-    };
-
-    /**
-     * The Constant incrementalImageUpdate.
-     */
-    private static final boolean incrementalImageUpdate;
-
-    /**
-     * The toolkit.
-     */
-    final transient Toolkit toolkit = Toolkit.getDefaultToolkit();
-
-    // ???AWT
-    /*
-     * protected abstract class AccessibleAWTComponent extends AccessibleContext
-     * implements Serializable, AccessibleComponent { private static final long
-     * serialVersionUID = 642321655757800191L; protected class
-     * AccessibleAWTComponentHandler implements ComponentListener { protected
-     * AccessibleAWTComponentHandler() { } public void
-     * componentHidden(ComponentEvent e) { if (behaviour.isLightweight()) {
-     * return; } firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
-     * AccessibleState.VISIBLE, null); } public void
-     * componentMoved(ComponentEvent e) { } public void
-     * componentResized(ComponentEvent e) { } public void
-     * componentShown(ComponentEvent e) { if (behaviour.isLightweight()) {
-     * return; } firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
-     * null, AccessibleState.VISIBLE); } } protected class
-     * AccessibleAWTFocusHandler implements FocusListener { public void
-     * focusGained(FocusEvent e) { if (behaviour.isLightweight()) { return; }
-     * firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
-     * AccessibleState.FOCUSED); } public void focusLost(FocusEvent e) { if
-     * (behaviour.isLightweight()) { return; }
-     * firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
-     * AccessibleState.FOCUSED, null); } } protected ComponentListener
-     * accessibleAWTComponentHandler; protected FocusListener
-     * accessibleAWTFocusHandler;
-     */
-    /*
-     * Number of registered property change listeners.
-     */
-    /*
-     * int listenersCount; public void addFocusListener(FocusListener l) {
-     * Component.this.addFocusListener(l); }
-     * @Override public void addPropertyChangeListener(PropertyChangeListener
-     * listener) { toolkit.lockAWT(); try {
-     * super.addPropertyChangeListener(listener); listenersCount++; if
-     * (accessibleAWTComponentHandler == null) { accessibleAWTComponentHandler =
-     * new AccessibleAWTComponentHandler();
-     * Component.this.addComponentListener(accessibleAWTComponentHandler); } if
-     * (accessibleAWTFocusHandler == null) { accessibleAWTFocusHandler = new
-     * AccessibleAWTFocusHandler();
-     * Component.this.addFocusListener(accessibleAWTFocusHandler); } } finally {
-     * toolkit.unlockAWT(); } } public boolean contains(Point p) {
-     * toolkit.lockAWT(); try { return Component.this.contains(p); } finally {
-     * toolkit.unlockAWT(); } } public Accessible getAccessibleAt(Point arg0) {
-     * toolkit.lockAWT(); try { return null; } finally { toolkit.unlockAWT(); }
-     * } public Color getBackground() { toolkit.lockAWT(); try { return
-     * Component.this.getBackground(); } finally { toolkit.unlockAWT(); } }
-     * public Rectangle getBounds() { toolkit.lockAWT(); try { return
-     * Component.this.getBounds(); } finally { toolkit.unlockAWT(); } } public
-     * Cursor getCursor() { toolkit.lockAWT(); try { return
-     * Component.this.getCursor(); } finally { toolkit.unlockAWT(); } } public
-     * Font getFont() { toolkit.lockAWT(); try { return
-     * Component.this.getFont(); } finally { toolkit.unlockAWT(); } } public
-     * FontMetrics getFontMetrics(Font f) { toolkit.lockAWT(); try { return
-     * Component.this.getFontMetrics(f); } finally { toolkit.unlockAWT(); } }
-     * public Color getForeground() { toolkit.lockAWT(); try { return
-     * Component.this.getForeground(); } finally { toolkit.unlockAWT(); } }
-     * public Point getLocation() { toolkit.lockAWT(); try { return
-     * Component.this.getLocation(); } finally { toolkit.unlockAWT(); } } public
-     * Point getLocationOnScreen() { toolkit.lockAWT(); try { return
-     * Component.this.getLocationOnScreen(); } finally { toolkit.unlockAWT(); }
-     * } public Dimension getSize() { toolkit.lockAWT(); try { return
-     * Component.this.getSize(); } finally { toolkit.unlockAWT(); } } public
-     * boolean isEnabled() { toolkit.lockAWT(); try { return
-     * Component.this.isEnabled(); } finally { toolkit.unlockAWT(); } } public
-     * boolean isFocusTraversable() { toolkit.lockAWT(); try { return
-     * Component.this.isFocusTraversable(); } finally { toolkit.unlockAWT(); } }
-     * public boolean isShowing() { toolkit.lockAWT(); try { return
-     * Component.this.isShowing(); } finally { toolkit.unlockAWT(); } } public
-     * boolean isVisible() { toolkit.lockAWT(); try { return
-     * Component.this.isVisible(); } finally { toolkit.unlockAWT(); } } public
-     * void removeFocusListener(FocusListener l) {
-     * Component.this.removeFocusListener(l); }
-     * @Override public void removePropertyChangeListener(PropertyChangeListener
-     * listener) { toolkit.lockAWT(); try {
-     * super.removePropertyChangeListener(listener); listenersCount--; if
-     * (listenersCount > 0) { return; } // if there are no more listeners,
-     * remove handlers:
-     * Component.this.removeFocusListener(accessibleAWTFocusHandler);
-     * Component.this.removeComponentListener(accessibleAWTComponentHandler);
-     * accessibleAWTComponentHandler = null; accessibleAWTFocusHandler = null; }
-     * finally { toolkit.unlockAWT(); } } public void requestFocus() {
-     * toolkit.lockAWT(); try { Component.this.requestFocus(); } finally {
-     * toolkit.unlockAWT(); } } public void setBackground(Color color) {
-     * toolkit.lockAWT(); try { Component.this.setBackground(color); } finally {
-     * toolkit.unlockAWT(); } } public void setBounds(Rectangle r) {
-     * toolkit.lockAWT(); try { Component.this.setBounds(r); } finally {
-     * toolkit.unlockAWT(); } } public void setCursor(Cursor cursor) {
-     * toolkit.lockAWT(); try { Component.this.setCursor(cursor); } finally {
-     * toolkit.unlockAWT(); } } public void setEnabled(boolean enabled) {
-     * toolkit.lockAWT(); try { Component.this.setEnabled(enabled); } finally {
-     * toolkit.unlockAWT(); } } public void setFont(Font f) { toolkit.lockAWT();
-     * try { Component.this.setFont(f); } finally { toolkit.unlockAWT(); } }
-     * public void setForeground(Color color) { toolkit.lockAWT(); try {
-     * Component.this.setForeground(color); } finally { toolkit.unlockAWT(); } }
-     * public void setLocation(Point p) { toolkit.lockAWT(); try {
-     * Component.this.setLocation(p); } finally { toolkit.unlockAWT(); } }
-     * public void setSize(Dimension size) { toolkit.lockAWT(); try {
-     * Component.this.setSize(size); } finally { toolkit.unlockAWT(); } } public
-     * void setVisible(boolean visible) { toolkit.lockAWT(); try {
-     * Component.this.setVisible(visible); } finally { toolkit.unlockAWT(); } }
-     * @Override public Accessible getAccessibleParent() { toolkit.lockAWT();
-     * try { Accessible aParent = super.getAccessibleParent(); if (aParent !=
-     * null) { return aParent; } Container parent = getParent(); return (parent
-     * instanceof Accessible ? (Accessible) parent : null); } finally {
-     * toolkit.unlockAWT(); } }
-     * @Override public Accessible getAccessibleChild(int i) {
-     * toolkit.lockAWT(); try { return null; } finally { toolkit.unlockAWT(); }
-     * }
-     * @Override public int getAccessibleChildrenCount() { toolkit.lockAWT();
-     * try { return 0; } finally { toolkit.unlockAWT(); } }
-     * @Override public AccessibleComponent getAccessibleComponent() { return
-     * this; }
-     * @Override public String getAccessibleDescription() { return
-     * super.getAccessibleDescription(); // why override? }
-     * @Override public int getAccessibleIndexInParent() { toolkit.lockAWT();
-     * try { if (getAccessibleParent() == null) { return -1; } int count = 0;
-     * Container parent = getParent(); for (int i = 0; i <
-     * parent.getComponentCount(); i++) { Component aComp =
-     * parent.getComponent(i); if (aComp instanceof Accessible) { if (aComp ==
-     * Component.this) { return count; } ++count; } } return -1; } finally {
-     * toolkit.unlockAWT(); } }
-     * @Override public AccessibleRole getAccessibleRole() { toolkit.lockAWT();
-     * try { return AccessibleRole.AWT_COMPONENT; } finally {
-     * toolkit.unlockAWT(); } }
-     * @Override public AccessibleStateSet getAccessibleStateSet() {
-     * toolkit.lockAWT(); try { AccessibleStateSet set = new
-     * AccessibleStateSet(); if (isEnabled()) {
-     * set.add(AccessibleState.ENABLED); } if (isFocusable()) {
-     * set.add(AccessibleState.FOCUSABLE); } if (hasFocus()) {
-     * set.add(AccessibleState.FOCUSED); } if (isOpaque()) {
-     * set.add(AccessibleState.OPAQUE); } if (isShowing()) {
-     * set.add(AccessibleState.SHOWING); } if (isVisible()) {
-     * set.add(AccessibleState.VISIBLE); } return set; } finally {
-     * toolkit.unlockAWT(); } }
-     * @Override public Locale getLocale() throws IllegalComponentStateException
-     * { toolkit.lockAWT(); try { return Component.this.getLocale(); } finally {
-     * toolkit.unlockAWT(); } } }
-     */
-    /**
-     * The BltBufferStrategy class provides opportunity of blitting offscreen
-     * surfaces to a component. For more information on blitting, see <a
-     * href="http://en.wikipedia.org/wiki/Bit_blit">Bit blit</a>.
-     * 
-     * @since Android 1.0
-     */
-    protected class BltBufferStrategy extends BufferStrategy {
-
-        /**
-         * The back buffers.
-         */
-        protected VolatileImage[] backBuffers;
-
-        /**
-         * The caps.
-         */
-        protected BufferCapabilities caps;
-
-        /**
-         * The width.
-         */
-        protected int width;
-
-        /**
-         * The height.
-         */
-        protected int height;
-
-        /**
-         * The validated contents.
-         */
-        protected boolean validatedContents;
-
-        /**
-         * Instantiates a new BltBufferStrategy buffer strategy.
-         * 
-         * @param numBuffers
-         *            the number of buffers.
-         * @param caps
-         *            the BufferCapabilities.
-         * @throws NotImplementedException
-         *             the not implemented exception.
-         */
-        protected BltBufferStrategy(int numBuffers, BufferCapabilities caps)
-                throws org.apache.harmony.luni.util.NotImplementedException {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-        }
-
-        /**
-         * Returns true if the drawing buffer has been lost since the last call
-         * to getDrawGraphics.
-         * 
-         * @return true if the drawing buffer has been lost since the last call
-         *         to getDrawGraphics, false otherwise.
-         * @see java.awt.image.BufferStrategy#contentsLost()
-         */
-        @Override
-        public boolean contentsLost() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-            return false;
-        }
-
-        /**
-         * Returns true if the drawing buffer has been restored from a lost
-         * state and reinitialized to the default background color.
-         * 
-         * @return true if the drawing buffer has been restored from a lost
-         *         state and reinitialized to the default background color,
-         *         false otherwise.
-         * @see java.awt.image.BufferStrategy#contentsRestored()
-         */
-        @Override
-        public boolean contentsRestored() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-            return false;
-        }
-
-        /**
-         * Creates the back buffers.
-         * 
-         * @param numBuffers
-         *            the number of buffers.
-         */
-        protected void createBackBuffers(int numBuffers) {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-        }
-
-        /**
-         * Returns the BufferCapabilities of the buffer strategy.
-         * 
-         * @return the BufferCapabilities.
-         * @see java.awt.image.BufferStrategy#getCapabilities()
-         */
-        @Override
-        public BufferCapabilities getCapabilities() {
-            return (BufferCapabilities)caps.clone();
-        }
-
-        /**
-         * Gets Graphics of current buffer strategy.
-         * 
-         * @return the Graphics of current buffer strategy.
-         * @see java.awt.image.BufferStrategy#getDrawGraphics()
-         */
-        @Override
-        public Graphics getDrawGraphics() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-            return null;
-        }
-
-        /**
-         * Revalidates the lost drawing buffer.
-         */
-        protected void revalidate() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-        }
-
-        /**
-         * Shows the next available buffer.
-         * 
-         * @see java.awt.image.BufferStrategy#show()
-         */
-        @Override
-        public void show() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-        }
-    }
-
-    /**
-     * The FlipBufferStrategy class is for flipping buffers on a component.
-     * 
-     * @since Android 1.0
-     */
-    protected class FlipBufferStrategy extends BufferStrategy {
-
-        /**
-         * The Buffer Capabilities.
-         */
-        protected BufferCapabilities caps;
-
-        /**
-         * The drawing buffer.
-         */
-        protected Image drawBuffer;
-
-        /**
-         * The drawing VolatileImage buffer.
-         */
-        protected VolatileImage drawVBuffer;
-
-        /**
-         * The number of buffers.
-         */
-        protected int numBuffers;
-
-        /**
-         * The validated contents indicates if the drawing buffer is restored
-         * from lost state.
-         */
-        protected boolean validatedContents;
-
-        /**
-         * Instantiates a new flip buffer strategy.
-         * 
-         * @param numBuffers
-         *            the number of buffers.
-         * @param caps
-         *            the BufferCapabilities.
-         * @throws AWTException
-         *             if the capabilities supplied could not be supported or
-         *             met.
-         */
-        protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps) throws AWTException {
-            // ???AWT
-            /*
-             * if (!(Component.this instanceof Window) && !(Component.this
-             * instanceof Canvas)) { // awt.14B=Only Canvas or Window is allowed
-             * throw new ClassCastException(Messages.getString("awt.14B"));
-             * //$NON-NLS-1$ }
-             */
-            // TODO: throw new AWTException("Capabilities are not supported");
-            this.numBuffers = numBuffers;
-            this.caps = (BufferCapabilities)caps.clone();
-        }
-
-        /**
-         * Returns true if the drawing buffer has been lost since the last call
-         * to getDrawGraphics.
-         * 
-         * @return true if the drawing buffer has been lost since the last call
-         *         to getDrawGraphics, false otherwise.
-         * @see java.awt.image.BufferStrategy#contentsLost()
-         */
-        @Override
-        public boolean contentsLost() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-            return false;
-        }
-
-        /**
-         * Returns true if the drawing buffer has been restored from a lost
-         * state and reinitialized to the default background color.
-         * 
-         * @return true if the drawing buffer has been restored from a lost
-         *         state and reinitialized to the default background color,
-         *         false otherwise.
-         * @see java.awt.image.BufferStrategy#contentsRestored()
-         */
-        @Override
-        public boolean contentsRestored() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-            return false;
-        }
-
-        /**
-         * Creates flipping buffers with the specified buffer capabilities.
-         * 
-         * @param numBuffers
-         *            the number of buffers.
-         * @param caps
-         *            the BufferCapabilities.
-         * @throws AWTException
-         *             if the capabilities could not be supported or met.
-         */
-        protected void createBuffers(int numBuffers, BufferCapabilities caps) throws AWTException {
-            if (numBuffers < 2) {
-                // awt.14C=Number of buffers must be greater than one
-                throw new IllegalArgumentException(Messages.getString("awt.14C")); //$NON-NLS-1$
-            }
-            if (!caps.isPageFlipping()) {
-                // awt.14D=Buffer capabilities should support flipping
-                throw new IllegalArgumentException(Messages.getString("awt.14D")); //$NON-NLS-1$
-            }
-            if (!Component.this.behaviour.isDisplayable()) {
-                // awt.14E=Component should be displayable
-                throw new IllegalStateException(Messages.getString("awt.14E")); //$NON-NLS-1$
-            }
-            // TODO: throw new AWTException("Capabilities are not supported");
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-        }
-
-        /**
-         * Destroy buffers.
-         */
-        protected void destroyBuffers() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-        }
-
-        /**
-         * Flips the contents of the back buffer to the front buffer.
-         * 
-         * @param flipAction
-         *            the flip action.
-         */
-        protected void flip(BufferCapabilities.FlipContents flipAction) {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-        }
-
-        /**
-         * Gets the back buffer as Image.
-         * 
-         * @return the back buffer as Image.
-         */
-        protected Image getBackBuffer() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-            return null;
-        }
-
-        /**
-         * Returns the BufferCapabilities of the buffer strategy.
-         * 
-         * @return the BufferCapabilities.
-         * @see java.awt.image.BufferStrategy#getCapabilities()
-         */
-        @Override
-        public BufferCapabilities getCapabilities() {
-            return (BufferCapabilities)caps.clone();
-        }
-
-        /**
-         * Gets Graphics of current buffer strategy.
-         * 
-         * @return the Graphics of current buffer strategy.
-         * @see java.awt.image.BufferStrategy#getDrawGraphics()
-         */
-        @Override
-        public Graphics getDrawGraphics() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-            return null;
-        }
-
-        /**
-         * Revalidates the lost drawing buffer.
-         */
-        protected void revalidate() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-        }
-
-        /**
-         * Shows the next available buffer.
-         * 
-         * @see java.awt.image.BufferStrategy#show()
-         */
-        @Override
-        public void show() {
-            if (true) {
-                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-            }
-        }
-    }
-
-    /**
-     * The internal component's state utilized by the visual theme.
-     */
-    class ComponentState implements State {
-
-        /**
-         * The default minimum size.
-         */
-        private Dimension defaultMinimumSize = new Dimension();
-
-        /**
-         * Checks if the component is enabled.
-         * 
-         * @return true, if the component is enabled.
-         */
-        public boolean isEnabled() {
-            return enabled;
-        }
-
-        /**
-         * Checks if the component is visible.
-         * 
-         * @return true, if the component is visible.
-         */
-        public boolean isVisible() {
-            return visible;
-        }
-
-        /**
-         * Checks if is focused.
-         * 
-         * @return true, if is focused.
-         */
-        public boolean isFocused() {
-            // ???AWT: return isFocusOwner();
-            return false;
-        }
-
-        /**
-         * Gets the font.
-         * 
-         * @return the font.
-         */
-        public Font getFont() {
-            return Component.this.getFont();
-        }
-
-        /**
-         * Checks if the font has been set.
-         * 
-         * @return true, if the font has been set.
-         */
-        public boolean isFontSet() {
-            return font != null;
-        }
-
-        /**
-         * Gets the background color.
-         * 
-         * @return the background color.
-         */
-        public Color getBackground() {
-            Color c = Component.this.getBackground();
-            return (c != null) ? c : getDefaultBackground();
-        }
-
-        /**
-         * Checks if the background is set.
-         * 
-         * @return true, if the background is set.
-         */
-        public boolean isBackgroundSet() {
-            return backColor != null;
-        }
-
-        /**
-         * Gets the text color.
-         * 
-         * @return the text color.
-         */
-        public Color getTextColor() {
-            Color c = getForeground();
-            return (c != null) ? c : getDefaultForeground();
-        }
-
-        /**
-         * Checks if the text color is set.
-         * 
-         * @return true, if the text color is set.
-         */
-        public boolean isTextColorSet() {
-            return foreColor != null;
-        }
-
-        /**
-         * Gets the font metrics.
-         * 
-         * @return the font metrics.
-         */
-        @SuppressWarnings("deprecation")
-        public FontMetrics getFontMetrics() {
-            return toolkit.getFontMetrics(Component.this.getFont());
-        }
-
-        /**
-         * Gets the bounding rectangle.
-         * 
-         * @return the bounding rectangle.
-         */
-        public Rectangle getBounds() {
-            return new Rectangle(x, y, w, h);
-        }
-
-        /**
-         * Gets the size of the bounding rectangle.
-         * 
-         * @return the size of the bounding rectangle.
-         */
-        public Dimension getSize() {
-            return new Dimension(w, h);
-        }
-
-        /**
-         * Gets the window id.
-         * 
-         * @return the window id.
-         */
-        public long getWindowId() {
-            NativeWindow win = getNativeWindow();
-            return (win != null) ? win.getId() : 0;
-        }
-
-        /**
-         * Gets the default minimum size.
-         * 
-         * @return the default minimum size.
-         */
-        public Dimension getDefaultMinimumSize() {
-            if (defaultMinimumSize == null) {
-                calculate();
-            }
-            return defaultMinimumSize;
-        }
-
-        /**
-         * Sets the default minimum size.
-         * 
-         * @param size
-         *            the new default minimum size.
-         */
-        public void setDefaultMinimumSize(Dimension size) {
-            defaultMinimumSize = size;
-        }
-
-        /**
-         * Reset the default minimum size to null.
-         */
-        public void reset() {
-            defaultMinimumSize = null;
-        }
-
-        /**
-         * Calculate the default minimum size: to be overridden.
-         */
-        public void calculate() {
-            // to be overridden
-        }
-    }
-
-    // ???AWT: private transient AccessibleContext accessibleContext;
-
-    /**
-     * The behaviour.
-     */
-    final transient ComponentBehavior behaviour;
-
-    // ???AWT: Container parent;
-
-    /**
-     * The name.
-     */
-    private String name;
-
-    /**
-     * The auto name.
-     */
-    private boolean autoName = true;
-
-    /**
-     * The font.
-     */
-    private Font font;
-
-    /**
-     * The back color.
-     */
-    private Color backColor;
-
-    /**
-     * The fore color.
-     */
-    private Color foreColor;
-
-    /**
-     * The deprecated event handler.
-     */
-    boolean deprecatedEventHandler = true;
-
-    /**
-     * The enabled events.
-     */
-    private long enabledEvents;
-
-    /**
-     * The enabled AWT events.
-     */
-    private long enabledAWTEvents;
-
-    /**
-     * The component listeners.
-     */
-    private final AWTListenerList<ComponentListener> componentListeners = new AWTListenerList<ComponentListener>(
-            this);
-
-    /**
-     * The focus listeners.
-     */
-    private final AWTListenerList<FocusListener> focusListeners = new AWTListenerList<FocusListener>(
-            this);
-
-    /**
-     * The hierarchy listeners.
-     */
-    private final AWTListenerList<HierarchyListener> hierarchyListeners = new AWTListenerList<HierarchyListener>(
-            this);
-
-    /**
-     * The hierarchy bounds listeners.
-     */
-    private final AWTListenerList<HierarchyBoundsListener> hierarchyBoundsListeners = new AWTListenerList<HierarchyBoundsListener>(
-            this);
-
-    /**
-     * The key listeners.
-     */
-    private final AWTListenerList<KeyListener> keyListeners = new AWTListenerList<KeyListener>(this);
-
-    /**
-     * The mouse listeners.
-     */
-    private final AWTListenerList<MouseListener> mouseListeners = new AWTListenerList<MouseListener>(
-            this);
-
-    /**
-     * The mouse motion listeners.
-     */
-    private final AWTListenerList<MouseMotionListener> mouseMotionListeners = new AWTListenerList<MouseMotionListener>(
-            this);
-
-    /**
-     * The mouse wheel listeners.
-     */
-    private final AWTListenerList<MouseWheelListener> mouseWheelListeners = new AWTListenerList<MouseWheelListener>(
-            this);
-
-    /**
-     * The input method listeners.
-     */
-    private final AWTListenerList<InputMethodListener> inputMethodListeners = new AWTListenerList<InputMethodListener>(
-            this);
-
-    /**
-     * The x.
-     */
-    int x;
-
-    /**
-     * The y.
-     */
-    int y;
-
-    /**
-     * The w.
-     */
-    int w;
-
-    /**
-     * The h.
-     */
-    int h;
-
-    /**
-     * The maximum size.
-     */
-    private Dimension maximumSize;
-
-    /**
-     * The minimum size.
-     */
-    private Dimension minimumSize;
-
-    /**
-     * The preferred size.
-     */
-    private Dimension preferredSize;
-
-    /**
-     * The bounds mask param.
-     */
-    private int boundsMaskParam;
-
-    /**
-     * The ignore repaint.
-     */
-    private boolean ignoreRepaint;
-
-    /**
-     * The enabled.
-     */
-    private boolean enabled = true;
-
-    /**
-     * The input methods enabled.
-     */
-    private boolean inputMethodsEnabled = true;
-
-    /**
-     * The dispatch to im.
-     */
-    transient boolean dispatchToIM = true;
-
-    /**
-     * The focusable.
-     */
-    private boolean focusable = true; // By default, all Components return
-
-    // true from isFocusable() method
-    /**
-     * The visible.
-     */
-    boolean visible = true;
-
-    /**
-     * The called set focusable.
-     */
-    private boolean calledSetFocusable;
-
-    /**
-     * The overridden is focusable.
-     */
-    private boolean overridenIsFocusable = true;
-
-    /**
-     * The focus traversal keys enabled.
-     */
-    private boolean focusTraversalKeysEnabled = true;
-
-    /**
-     * Possible keys are: FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
-     * UP_CYCLE_TRAVERSAL_KEYS.
-     */
-    private final Map<Integer, Set<? extends AWTKeyStroke>> traversalKeys = new HashMap<Integer, Set<? extends AWTKeyStroke>>();
-
-    /**
-     * The traversal i ds.
-     */
-    int[] traversalIDs;
-
-    /**
-     * The locale.
-     */
-    private Locale locale;
-
-    /**
-     * The orientation.
-     */
-    private ComponentOrientation orientation;
-
-    /**
-     * The property change support.
-     */
-    private PropertyChangeSupport propertyChangeSupport;
-
-    // ???AWT: private ArrayList<PopupMenu> popups;
-
-    /**
-     * The coalescer.
-     */
-    private boolean coalescer;
-
-    /**
-     * The events table.
-     */
-    private Hashtable<Integer, LinkedList<AWTEvent>> eventsTable;
-
-    /**
-     * Cashed reference used during EventQueue.postEvent()
-     */
-    private LinkedList<AWTEvent> eventsList;
-
-    /**
-     * The hierarchy changing counter.
-     */
-    private int hierarchyChangingCounter;
-
-    /**
-     * The was showing.
-     */
-    private boolean wasShowing;
-
-    /**
-     * The was displayable.
-     */
-    private boolean wasDisplayable;
-
-    /**
-     * The cursor.
-     */
-    Cursor cursor;
-
-    // ???AWT: DropTarget dropTarget;
-
-    /**
-     * The mouse exited expected.
-     */
-    private boolean mouseExitedExpected;
-
-    /**
-     * The repaint region.
-     */
-    transient MultiRectArea repaintRegion;
-
-    // ???AWT: transient RedrawManager redrawManager;
-    /**
-     * The redraw manager.
-     */
-    transient Object redrawManager;
-
-    /**
-     * The valid.
-     */
-    private boolean valid;
-
-    /**
-     * The updated images.
-     */
-    private HashMap<Image, ImageParameters> updatedImages;
-
-    /**
-     * The lock object for private component's data which don't affect the
-     * component hierarchy.
-     */
-    private class ComponentLock {
-    }
-
-    /**
-     * The component lock.
-     */
-    private final transient Object componentLock = new ComponentLock();
-    static {
-        PrivilegedAction<String[]> action = new PrivilegedAction<String[]>() {
-            public String[] run() {
-                String properties[] = new String[2];
-                properties[0] = System.getProperty("awt.image.redrawrate", "100"); //$NON-NLS-1$ //$NON-NLS-2$
-                properties[1] = System.getProperty("awt.image.incrementaldraw", "true"); //$NON-NLS-1$ //$NON-NLS-2$
-                return properties;
-            }
-        };
-        String properties[] = AccessController.doPrivileged(action);
-        // FIXME: rate is never used, can this code and the get property above
-        // be removed?
-        // int rate;
-        //
-        // try {
-        // rate = Integer.decode(properties[0]).intValue();
-        // } catch (NumberFormatException e) {
-        // rate = 100;
-        // }
-        incrementalImageUpdate = properties[1].equals("true"); //$NON-NLS-1$
-    }
-
-    /**
-     * Instantiates a new component.
-     */
-    protected Component() {
-        toolkit.lockAWT();
-        try {
-            orientation = ComponentOrientation.UNKNOWN;
-            redrawManager = null;
-            // ???AWT
-            /*
-             * traversalIDs = this instanceof Container ?
-             * KeyboardFocusManager.contTraversalIDs :
-             * KeyboardFocusManager.compTraversalIDs; for (int element :
-             * traversalIDs) { traversalKeys.put(new Integer(element), null); }
-             * behaviour = createBehavior();
-             */
-            behaviour = null;
-
-            deriveCoalescerFlag();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Determine that the class inherited from Component declares the method
-     * coalesceEvents(), and put the results to the childClassesFlags map.
-     */
-    private void deriveCoalescerFlag() {
-        Class<?> thisClass = getClass();
-        boolean flag = true;
-        synchronized (childClassesFlags) {
-            Boolean flagWrapper = childClassesFlags.get(thisClass);
-            if (flagWrapper == null) {
-                Method coalesceMethod = null;
-                for (Class<?> c = thisClass; c != Component.class; c = c.getSuperclass()) {
-                    try {
-                        coalesceMethod = c.getDeclaredMethod("coalesceEvents", new Class[] { //$NON-NLS-1$
-                                        Class.forName("java.awt.AWTEvent"), //$NON-NLS-1$
-                                        Class.forName("java.awt.AWTEvent")}); //$NON-NLS-1$
-                    } catch (Exception e) {
-                    }
-                    if (coalesceMethod != null) {
-                        break;
-                    }
-                }
-                flag = (coalesceMethod != null);
-                childClassesFlags.put(thisClass, Boolean.valueOf(flag));
-            } else {
-                flag = flagWrapper.booleanValue();
-            }
-        }
-        coalescer = flag;
-        if (flag) {
-            eventsTable = new Hashtable<Integer, LinkedList<AWTEvent>>();
-        } else {
-            eventsTable = null;
-        }
-    }
-
-    /**
-     * Sets the name of the Component.
-     * 
-     * @param name
-     *            the new name of the Component.
-     */
-    public void setName(String name) {
-        String oldName;
-        toolkit.lockAWT();
-        try {
-            autoName = false;
-            oldName = this.name;
-            this.name = name;
-        } finally {
-            toolkit.unlockAWT();
-        }
-        firePropertyChange("name", oldName, name); //$NON-NLS-1$
-    }
-
-    /**
-     * Gets the name of this Component.
-     * 
-     * @return the name of this Component.
-     */
-    public String getName() {
-        toolkit.lockAWT();
-        try {
-            if ((name == null) && autoName) {
-                name = autoName();
-            }
-            return name;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Auto name.
-     * 
-     * @return the string.
-     */
-    String autoName() {
-        String name = getClass().getName();
-        if (name.indexOf("$") != -1) { //$NON-NLS-1$
-            return null;
-        }
-        // ???AWT
-        // int number = toolkit.autoNumber.nextComponent++;
-        int number = 0;
-        name = name.substring(name.lastIndexOf(".") + 1) + Integer.toString(number); //$NON-NLS-1$
-        return name;
-    }
-
-    /**
-     * Returns the string representation of the Component.
-     * 
-     * @return the string representation of the Component.
-     */
-    @Override
-    public String toString() {
-        /*
-         * The format is based on 1.5 release behavior which can be revealed by
-         * the following code: Component c = new Component(){};
-         * c.setVisible(false); System.out.println(c);
-         */
-        toolkit.lockAWT();
-        try {
-            return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    // ???AWT
-    /*
-     * public void add(PopupMenu popup) { toolkit.lockAWT(); try { if
-     * (popup.getParent() == this) { return; } if (popups == null) { popups =
-     * new ArrayList<PopupMenu>(); } popup.setParent(this); popups.add(popup); }
-     * finally { toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * Returns true, if the component contains the specified Point.
-     * 
-     * @param p
-     *            the Point.
-     * @return true, if the component contains the specified Point, false
-     *         otherwise.
-     */
-    public boolean contains(Point p) {
-        toolkit.lockAWT();
-        try {
-            return contains(p.x, p.y);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Returns true, if the component contains the point with the specified
-     * coordinates.
-     * 
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @return true, if the component contains the point with the specified
-     *         coordinates, false otherwise.
-     */
-    public boolean contains(int x, int y) {
-        toolkit.lockAWT();
-        try {
-            return inside(x, y);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Deprecated: replaced by replaced by getSize() method.
-     * 
-     * @return the dimension.
-     * @deprecated Replaced by getSize() method.
-     */
-    @Deprecated
-    public Dimension size() {
-        toolkit.lockAWT();
-        try {
-            return new Dimension(w, h);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    // ???AWT
-    /*
-     * public Container getParent() { toolkit.lockAWT(); try { return parent; }
-     * finally { toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * List.
-     * 
-     * @param out
-     *            the out.
-     * @param indent
-     *            the indent
-     * @return the nearest heavyweight ancestor in hierarchy or
-     *         <code>null</code> if not found.
-     */
-    // ???AWT
-    /*
-     * Component getHWAncestor() { return (parent != null ?
-     * parent.getHWSurface() : null); }
-     */
-
-    /**
-     * @return heavyweight component that is equal to or is a nearest
-     *         heavyweight container of the current component, or
-     *         <code>null</code> if not found.
-     */
-    // ???AWT
-    /*
-     * Component getHWSurface() { Component parent; for (parent = this; (parent
-     * != null) && (parent.isLightweight()); parent = parent .getParent()) { ; }
-     * return parent; } Window getWindowAncestor() { Component par; for (par =
-     * this; par != null && !(par instanceof Window); par = par.getParent()) { ;
-     * } return (Window) par; }
-     */
-
-    /**
-     * To be called by container
-     */
-    // ???AWT
-    /*
-     * void setParent(Container parent) { this.parent = parent;
-     * setRedrawManager(); } void setRedrawManager() { redrawManager =
-     * getRedrawManager(); } public void remove(MenuComponent menu) {
-     * toolkit.lockAWT(); try { if (menu.getParent() == this) {
-     * menu.setParent(null); popups.remove(menu); } } finally {
-     * toolkit.unlockAWT(); } }
-     */
-    /**
-     * Prints a list of this component with the specified number of leading
-     * whitespace characters to the specified PrintStream.
-     * 
-     * @param out
-     *            the output PrintStream object.
-     * @param indent
-     *            how many leading whitespace characters to prepend.
-     */
-    public void list(PrintStream out, int indent) {
-        toolkit.lockAWT();
-        try {
-            out.println(getIndentStr(indent) + this);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Prints a list of this component to the specified PrintWriter.
-     * 
-     * @param out
-     *            the output PrintWriter object.
-     */
-    public void list(PrintWriter out) {
-        toolkit.lockAWT();
-        try {
-            list(out, 1);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Prints a list of this component with the specified number of leading
-     * whitespace characters to the specified PrintWriter.
-     * 
-     * @param out
-     *            the output PrintWriter object.
-     * @param indent
-     *            how many leading whitespace characters to prepend.
-     */
-    public void list(PrintWriter out, int indent) {
-        toolkit.lockAWT();
-        try {
-            out.println(getIndentStr(indent) + this);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets a string composed of the desired number of whitespace characters.
-     * 
-     * @param indent
-     *            the length of the String to return.
-     * @return the string composed of the desired number of whitespace
-     *         characters.
-     */
-    String getIndentStr(int indent) {
-        char[] ind = new char[indent];
-        for (int i = 0; i < indent; ind[i++] = ' ') {
-            ;
-        }
-        return new String(ind);
-    }
-
-    /**
-     * Prints a list of this component to the specified PrintStream.
-     * 
-     * @param out
-     *            the output PrintStream object.
-     */
-    public void list(PrintStream out) {
-        toolkit.lockAWT();
-        try {
-            // default indent = 1
-            list(out, 1);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Prints a list of this component to the standard system output stream.
-     */
-    public void list() {
-        toolkit.lockAWT();
-        try {
-            list(System.out);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Prints this component.
-     * 
-     * @param g
-     *            the Graphics to be used for painting.
-     */
-    public void print(Graphics g) {
-        toolkit.lockAWT();
-        try {
-            paint(g);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Prints the component and all of its subcomponents.
-     * 
-     * @param g
-     *            the Graphics to be used for painting.
-     */
-    public void printAll(Graphics g) {
-        toolkit.lockAWT();
-        try {
-            paintAll(g);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the size of the Component specified by width and height parameters.
-     * 
-     * @param width
-     *            the width of the Component.
-     * @param height
-     *            the height of the Component.
-     */
-    public void setSize(int width, int height) {
-        toolkit.lockAWT();
-        try {
-            resize(width, height);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the size of the Component specified by Dimension object.
-     * 
-     * @param d
-     *            the new size of the Component.
-     */
-    public void setSize(Dimension d) {
-        toolkit.lockAWT();
-        try {
-            resize(d);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Deprecated: replaced by setSize(int, int) method.
-     * 
-     * @param width
-     *            the width.
-     * @param height
-     *            the height.
-     * @deprecated Replaced by setSize(int, int) method.
-     */
-    @Deprecated
-    public void resize(int width, int height) {
-        toolkit.lockAWT();
-        try {
-            boundsMaskParam = NativeWindow.BOUNDS_NOMOVE;
-            setBounds(x, y, width, height);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Deprecated: replaced by setSize(int, int) method.
-     * 
-     * @param size
-     *            the size.
-     * @deprecated Replaced by setSize(int, int) method.
-     */
-    @Deprecated
-    public void resize(Dimension size) {
-        toolkit.lockAWT();
-        try {
-            setSize(size.width, size.height);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not this component is completely opaque.
-     * 
-     * @return true, if this component is completely opaque, false by default.
-     */
-    public boolean isOpaque() {
-        toolkit.lockAWT();
-        try {
-            return behaviour.isOpaque();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Disables.
-     * 
-     * @deprecated Replaced by setEnabled(boolean) method.
-     */
-    @Deprecated
-    public void disable() {
-        toolkit.lockAWT();
-        try {
-            setEnabledImpl(false);
-        } finally {
-            toolkit.unlockAWT();
-        }
-        // ???AWT: fireAccessibleStateChange(AccessibleState.ENABLED, false);
-    }
-
-    /**
-     * Enables this component.
-     * 
-     * @deprecated Replaced by setEnabled(boolean) method.
-     */
-    @Deprecated
-    public void enable() {
-        toolkit.lockAWT();
-        try {
-            setEnabledImpl(true);
-        } finally {
-            toolkit.unlockAWT();
-        }
-        // ???AWT: fireAccessibleStateChange(AccessibleState.ENABLED, true);
-    }
-
-    /**
-     * Enables or disable this component.
-     * 
-     * @param b
-     *            the boolean parameter.
-     * @deprecated Replaced by setEnabled(boolean) method.
-     */
-    @Deprecated
-    public void enable(boolean b) {
-        toolkit.lockAWT();
-        try {
-            if (b) {
-                enable();
-            } else {
-                disable();
-            }
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Stores the location of this component to the specified Point object;
-     * returns the point of the component's top-left corner.
-     * 
-     * @param rv
-     *            the Point object where the component's top-left corner
-     *            position will be stored.
-     * @return the Point which specifies the component's top-left corner.
-     */
-    public Point getLocation(Point rv) {
-        toolkit.lockAWT();
-        try {
-            if (rv == null) {
-                rv = new Point();
-            }
-            rv.setLocation(getX(), getY());
-            return rv;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the location of this component on the form; returns the point of the
-     * component's top-left corner.
-     * 
-     * @return the Point which specifies the component's top-left corner.
-     */
-    public Point getLocation() {
-        toolkit.lockAWT();
-        try {
-            return location();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the size of this Component.
-     * 
-     * @return the size of this Component.
-     */
-    public Dimension getSize() {
-        toolkit.lockAWT();
-        try {
-            return size();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Stores the size of this Component to the specified Dimension object.
-     * 
-     * @param rv
-     *            the Dimension object where the size of the Component will be
-     *            stored.
-     * @return the Dimension of this Component.
-     */
-    public Dimension getSize(Dimension rv) {
-        toolkit.lockAWT();
-        try {
-            if (rv == null) {
-                rv = new Dimension();
-            }
-            rv.setSize(getWidth(), getHeight());
-            return rv;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not this Component is valid. A component is valid if it
-     * is correctly sized and positioned within its parent container and all its
-     * children are also valid.
-     * 
-     * @return true, if the Component is valid, false otherwise.
-     */
-    public boolean isValid() {
-        toolkit.lockAWT();
-        try {
-            return valid && behaviour.isDisplayable();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Deprecated: replaced by getComponentAt(int, int) method.
-     * 
-     * @return the Point.
-     * @deprecated Replaced by getComponentAt(int, int) method.
-     */
-    @Deprecated
-    public Point location() {
-        toolkit.lockAWT();
-        try {
-            return new Point(x, y);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Connects this Component to a native screen resource and makes it
-     * displayable. This method not be called directly by user applications.
-     */
-    public void addNotify() {
-        toolkit.lockAWT();
-        try {
-            prepare4HierarchyChange();
-            behaviour.addNotify();
-            // ???AWT
-            // finishHierarchyChange(this, parent, 0);
-            // if (dropTarget != null) {
-            // dropTarget.addNotify(peer);
-            // }
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Map to display.
-     * 
-     * @param b
-     *            the b.
-     */
-    void mapToDisplay(boolean b) {
-        // ???AWT
-        /*
-         * if (b && !isDisplayable()) { if ((this instanceof Window) || ((parent
-         * != null) && parent.isDisplayable())) { addNotify(); } } else if (!b
-         * && isDisplayable()) { removeNotify(); }
-         */
-    }
-
-    /**
-     * Gets the toolkit.
-     * 
-     * @return accessible context specific for particular component.
-     */
-    // ???AWT
-    /*
-     * AccessibleContext createAccessibleContext() { return null; } public
-     * AccessibleContext getAccessibleContext() { toolkit.lockAWT(); try { if
-     * (accessibleContext == null) { accessibleContext =
-     * createAccessibleContext(); } return accessibleContext; } finally {
-     * toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * Gets Toolkit for the current Component.
-     * 
-     * @return the Toolkit of this Component.
-     */
-    public Toolkit getToolkit() {
-        return toolkit;
-    }
-
-    /**
-     * Gets this component's locking object for AWT component tree and layout
-     * operations.
-     * 
-     * @return the tree locking object.
-     */
-    public final Object getTreeLock() {
-        return toolkit.awtTreeLock;
-    }
-
-    /**
-     * Handles the event. Use ActionListener instead of this.
-     * 
-     * @param evt
-     *            the Event.
-     * @param what
-     *            the event's key.
-     * @return true, if successful.
-     * @deprecated Use ActionListener class for registering event listener.
-     */
-    @Deprecated
-    public boolean action(Event evt, Object what) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Gets the property change support.
-     * 
-     * @return the property change support.
-     */
-    private PropertyChangeSupport getPropertyChangeSupport() {
-        synchronized (componentLock) {
-            if (propertyChangeSupport == null) {
-                propertyChangeSupport = new PropertyChangeSupport(this);
-            }
-            return propertyChangeSupport;
-        }
-    }
-
-    // ???AWT
-    /*
-     * public void addPropertyChangeListener(PropertyChangeListener listener) {
-     * getPropertyChangeSupport().addPropertyChangeListener(listener); } public
-     * void addPropertyChangeListener(String propertyName,
-     * PropertyChangeListener listener) {
-     * getPropertyChangeSupport().addPropertyChangeListener(propertyName,
-     * listener); } public void applyComponentOrientation(ComponentOrientation
-     * orientation) { toolkit.lockAWT(); try {
-     * setComponentOrientation(orientation); } finally { toolkit.unlockAWT(); }
-     * }
-     */
-
-    /**
-     * Returns true if the set of focus traversal keys for the given focus
-     * traversal operation has been explicitly defined for this Component.
-     * 
-     * @param id
-     *            the ID of traversal key.
-     * @return true, if the set of focus traversal keys for the given focus.
-     *         traversal operation has been explicitly defined for this
-     *         Component, false otherwise.
-     */
-    public boolean areFocusTraversalKeysSet(int id) {
-        toolkit.lockAWT();
-        try {
-            Integer Id = new Integer(id);
-            if (traversalKeys.containsKey(Id)) {
-                return traversalKeys.get(Id) != null;
-            }
-            // awt.14F=invalid focus traversal key identifier
-            throw new IllegalArgumentException(Messages.getString("awt.14F")); //$NON-NLS-1$
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the bounds of the Component.
-     * 
-     * @return the rectangle bounds of the Component.
-     * @deprecated Use getBounds() methood.
-     */
-    @Deprecated
-    public Rectangle bounds() {
-        toolkit.lockAWT();
-        try {
-            return new Rectangle(x, y, w, h);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Returns the construction status of a specified image with the specified
-     * width and height that is being created.
-     * 
-     * @param image
-     *            the image to be checked.
-     * @param width
-     *            the width of scaled image which status is being checked, or
-     *            -1.
-     * @param height
-     *            the height of scaled image which status is being checked, or
-     *            -1.
-     * @param observer
-     *            the ImageObserver object to be notified while the image is
-     *            being prepared.
-     * @return the ImageObserver flags of the current state of the image data.
-     */
-    public int checkImage(Image image, int width, int height, ImageObserver observer) {
-        toolkit.lockAWT();
-        try {
-            return toolkit.checkImage(image, width, height, observer);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Returns the construction status of a specified image that is being
-     * created.
-     * 
-     * @param image
-     *            the image to be checked.
-     * @param observer
-     *            the ImageObserver object to be notified while the image is
-     *            being prepared.
-     * @return the ImageObserver flags of the current state of the image data.
-     */
-    public int checkImage(Image image, ImageObserver observer) {
-        toolkit.lockAWT();
-        try {
-            return toolkit.checkImage(image, -1, -1, observer);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Coalesces the existed event with new event.
-     * 
-     * @param existingEvent
-     *            the existing event in the EventQueue.
-     * @param newEvent
-     *            the new event to be posted to the EventQueue.
-     * @return the coalesced AWTEvent, or null if there is no coalescing done.
-     */
-    protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent) {
-        toolkit.lockAWT();
-        try {
-            // Nothing to do:
-            // 1. Mouse events coalesced at WTK level
-            // 2. Paint events handled by RedrawManager
-            // This method is for overriding only
-            return null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks if this Component is a coalescer.
-     * 
-     * @return true, if is coalescer.
-     */
-    boolean isCoalescer() {
-        return coalescer;
-    }
-
-    /**
-     * Gets the relative event.
-     * 
-     * @param id
-     *            the id.
-     * @return the relative event.
-     */
-    AWTEvent getRelativeEvent(int id) {
-        Integer idWrapper = new Integer(id);
-        eventsList = eventsTable.get(idWrapper);
-        if (eventsList == null) {
-            eventsList = new LinkedList<AWTEvent>();
-            eventsTable.put(idWrapper, eventsList);
-            return null;
-        }
-        if (eventsList.isEmpty()) {
-            return null;
-        }
-        return eventsList.getLast();
-    }
-
-    /**
-     * Adds the new event.
-     * 
-     * @param event
-     *            the event.
-     */
-    void addNewEvent(AWTEvent event) {
-        eventsList.addLast(event);
-    }
-
-    /**
-     * Removes the relative event.
-     */
-    void removeRelativeEvent() {
-        eventsList.removeLast();
-    }
-
-    /**
-     * Removes the next event.
-     * 
-     * @param id
-     *            the id.
-     */
-    void removeNextEvent(int id) {
-        eventsTable.get(new Integer(id)).removeFirst();
-    }
-
-    /**
-     * Creates the image with the specified ImageProducer.
-     * 
-     * @param producer
-     *            the ImageProducer to be used for image creation.
-     * @return the image with the specified ImageProducer.
-     */
-    public Image createImage(ImageProducer producer) {
-        toolkit.lockAWT();
-        try {
-            return toolkit.createImage(producer);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Creates an off-screen drawable image to be used for double buffering.
-     * 
-     * @param width
-     *            the width of the image.
-     * @param height
-     *            the height of the image.
-     * @return the off-screen drawable image or null if the component is not
-     *         displayable or GraphicsEnvironment.isHeadless() method returns
-     *         true.
-     */
-    public Image createImage(int width, int height) {
-        toolkit.lockAWT();
-        try {
-            if (!isDisplayable()) {
-                return null;
-            }
-            GraphicsConfiguration gc = getGraphicsConfiguration();
-            if (gc == null) {
-                return null;
-            }
-            ColorModel cm = gc.getColorModel(Transparency.OPAQUE);
-            WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
-            Image image = new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
-            fillImageBackground(image, width, height);
-            return image;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Creates an off-screen drawable image with the specified width, height and
-     * ImageCapabilities.
-     * 
-     * @param width
-     *            the width.
-     * @param height
-     *            the height.
-     * @param caps
-     *            the ImageCapabilities.
-     * @return the volatile image.
-     * @throws AWTException
-     *             if an image with the specified capabilities cannot be
-     *             created.
-     */
-    public VolatileImage createVolatileImage(int width, int height, ImageCapabilities caps)
-            throws AWTException {
-        toolkit.lockAWT();
-        try {
-            if (!isDisplayable()) {
-                return null;
-            }
-            GraphicsConfiguration gc = getGraphicsConfiguration();
-            if (gc == null) {
-                return null;
-            }
-            VolatileImage image = gc.createCompatibleVolatileImage(width, height, caps);
-            fillImageBackground(image, width, height);
-            return image;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Creates a volatile off-screen drawable image which is used for double
-     * buffering.
-     * 
-     * @param width
-     *            the width of image.
-     * @param height
-     *            the height of image.
-     * @return the volatile image a volatile off-screen drawable image which is
-     *         used for double buffering or null if the component is not
-     *         displayable, or GraphicsEnvironment.isHeadless() method returns
-     *         true.
-     */
-    public VolatileImage createVolatileImage(int width, int height) {
-        toolkit.lockAWT();
-        try {
-            if (!isDisplayable()) {
-                return null;
-            }
-            GraphicsConfiguration gc = getGraphicsConfiguration();
-            if (gc == null) {
-                return null;
-            }
-            VolatileImage image = gc.createCompatibleVolatileImage(width, height);
-            fillImageBackground(image, width, height);
-            return image;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Fill the image being created by createImage() or createVolatileImage()
-     * with the component's background color to prepare it for double-buffered
-     * painting.
-     * 
-     * @param image
-     *            the image.
-     * @param width
-     *            the width.
-     * @param height
-     *            the height.
-     */
-    private void fillImageBackground(Image image, int width, int height) {
-        Graphics gr = image.getGraphics();
-        gr.setColor(getBackground());
-        gr.fillRect(0, 0, width, height);
-        gr.dispose();
-    }
-
-    /**
-     * Delivers event.
-     * 
-     * @param evt
-     *            the event.
-     * @deprecated Replaced by dispatchEvent(AWTEvent e) method.
-     */
-    @Deprecated
-    public void deliverEvent(Event evt) {
-        postEvent(evt);
-    }
-
-    /**
-     * Prompts the layout manager to lay out this component.
-     */
-    public void doLayout() {
-        toolkit.lockAWT();
-        try {
-            layout();
-        } finally {
-            toolkit.unlockAWT();
-        }
-        // Implemented in Container
-    }
-
-    /**
-     * Fire property change impl.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param oldValue
-     *            the old value.
-     * @param newValue
-     *            the new value.
-     */
-    private void firePropertyChangeImpl(String propertyName, Object oldValue, Object newValue) {
-        PropertyChangeSupport pcs;
-        synchronized (componentLock) {
-            if (propertyChangeSupport == null) {
-                return;
-            }
-            pcs = propertyChangeSupport;
-        }
-        pcs.firePropertyChange(propertyName, oldValue, newValue);
-    }
-
-    /**
-     * Reports a bound property changes for int properties.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param oldValue
-     *            the old property's value.
-     * @param newValue
-     *            the new property's value.
-     */
-    protected void firePropertyChange(String propertyName, int oldValue, int newValue) {
-        firePropertyChangeImpl(propertyName, new Integer(oldValue), new Integer(newValue));
-    }
-
-    /**
-     * Report a bound property change for a boolean-valued property.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param oldValue
-     *            the property's old value.
-     * @param newValue
-     *            the property's new value.
-     */
-    protected void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
-        firePropertyChangeImpl(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
-    }
-
-    /**
-     * Reports a bound property change for an Object-valued property.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param oldValue
-     *            the property's old value.
-     * @param newValue
-     *            the property's new value.
-     */
-    protected void firePropertyChange(final String propertyName, final Object oldValue,
-            final Object newValue) {
-        firePropertyChangeImpl(propertyName, oldValue, newValue);
-    }
-
-    /**
-     * Report a bound property change for a byte-valued property.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param oldValue
-     *            the property's old value.
-     * @param newValue
-     *            the property's new value.
-     */
-    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
-        firePropertyChangeImpl(propertyName, new Byte(oldValue), new Byte(newValue));
-    }
-
-    /**
-     * Report a bound property change for a char-valued property.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param oldValue
-     *            the old property's value.
-     * @param newValue
-     *            the new property's value.
-     */
-    public void firePropertyChange(String propertyName, char oldValue, char newValue) {
-        firePropertyChangeImpl(propertyName, new Character(oldValue), new Character(newValue));
-    }
-
-    /**
-     * Report a bound property change for a short-valued property.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param oldValue
-     *            the old property's value.
-     * @param newValue
-     *            the new property's value.
-     */
-    public void firePropertyChange(String propertyName, short oldValue, short newValue) {
-        firePropertyChangeImpl(propertyName, new Short(oldValue), new Short(newValue));
-    }
-
-    /**
-     * Report a bound property change for a long-valued property.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param oldValue
-     *            the old property's value.
-     * @param newValue
-     *            the new property's value.
-     */
-    public void firePropertyChange(String propertyName, long oldValue, long newValue) {
-        firePropertyChangeImpl(propertyName, new Long(oldValue), new Long(newValue));
-    }
-
-    /**
-     * Report a bound property change for a float-valued property.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param oldValue
-     *            the old property's value.
-     * @param newValue
-     *            the new property's value.
-     */
-    public void firePropertyChange(String propertyName, float oldValue, float newValue) {
-        firePropertyChangeImpl(propertyName, new Float(oldValue), new Float(newValue));
-    }
-
-    /**
-     * Report a bound property change for a double-valued property.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param oldValue
-     *            the old property's value.
-     * @param newValue
-     *            the new property's value.
-     */
-    public void firePropertyChange(String propertyName, double oldValue, double newValue) {
-        firePropertyChangeImpl(propertyName, new Double(oldValue), new Double(newValue));
-    }
-
-    /**
-     * Gets the alignment along the x axis.
-     * 
-     * @return the alignment along the x axis.
-     */
-    public float getAlignmentX() {
-        toolkit.lockAWT();
-        try {
-            return CENTER_ALIGNMENT;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the alignment along the y axis.
-     * 
-     * @return the alignment along y axis.
-     */
-    public float getAlignmentY() {
-        toolkit.lockAWT();
-        try {
-            return CENTER_ALIGNMENT;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the background color for this component.
-     * 
-     * @return the background color for this component.
-     */
-    public Color getBackground() {
-        toolkit.lockAWT();
-        try {
-            // ???AWT
-            /*
-             * if ((backColor == null) && (parent != null)) { return
-             * parent.getBackground(); }
-             */
-            return backColor;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the bounding rectangle of this component.
-     * 
-     * @return the bounding rectangle of this component.
-     */
-    public Rectangle getBounds() {
-        toolkit.lockAWT();
-        try {
-            return bounds();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Writes the data of the bounding rectangle to the specified Rectangle
-     * object.
-     * 
-     * @param rv
-     *            the Rectangle object where the bounding rectangle's data is
-     *            stored.
-     * @return the bounding rectangle.
-     */
-    public Rectangle getBounds(Rectangle rv) {
-        toolkit.lockAWT();
-        try {
-            if (rv == null) {
-                rv = new Rectangle();
-            }
-            rv.setBounds(x, y, w, h);
-            return rv;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the color model of the Component.
-     * 
-     * @return the color model of the Component.
-     */
-    public ColorModel getColorModel() {
-        toolkit.lockAWT();
-        try {
-            return getToolkit().getColorModel();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the Component which contains the specified Point.
-     * 
-     * @param p
-     *            the Point.
-     * @return the Component which contains the specified Point.
-     */
-    public Component getComponentAt(Point p) {
-        toolkit.lockAWT();
-        try {
-            return getComponentAt(p.x, p.y);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the Component which contains the point with the specified
-     * coordinates.
-     * 
-     * @param x
-     *            the x coordinate of the point.
-     * @param y
-     *            the y coordinate of the point.
-     * @return the Component which contains the point with the specified
-     *         coordinates.
-     */
-    public Component getComponentAt(int x, int y) {
-        toolkit.lockAWT();
-        try {
-            return locate(x, y);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the component's orientation.
-     * 
-     * @return the component's orientation.
-     */
-    public ComponentOrientation getComponentOrientation() {
-        toolkit.lockAWT();
-        try {
-            return orientation;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the cursor of the Component.
-     * 
-     * @return the Cursor.
-     */
-    public Cursor getCursor() {
-        toolkit.lockAWT();
-        try {
-            if (cursor != null) {
-                return cursor;
-                // ???AWT
-                /*
-                 * } else if (parent != null) { return parent.getCursor();
-                 */
-            }
-            return Cursor.getDefaultCursor();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    // ???AWT
-    /*
-     * public DropTarget getDropTarget() { toolkit.lockAWT(); try { return
-     * dropTarget; } finally { toolkit.unlockAWT(); } } public Container
-     * getFocusCycleRootAncestor() { toolkit.lockAWT(); try { for (Container c =
-     * parent; c != null; c = c.getParent()) { if (c.isFocusCycleRoot()) {
-     * return c; } } return null; } finally { toolkit.unlockAWT(); } }
-     * @SuppressWarnings("unchecked") public Set<AWTKeyStroke>
-     * getFocusTraversalKeys(int id) { toolkit.lockAWT(); try { Integer kId =
-     * new Integer(id); KeyboardFocusManager.checkTraversalKeysID(traversalKeys,
-     * kId); Set<? extends AWTKeyStroke> keys = traversalKeys.get(kId); if (keys
-     * == null && parent != null) { keys = parent.getFocusTraversalKeys(id); }
-     * if (keys == null) { keys =
-     * KeyboardFocusManager.getCurrentKeyboardFocusManager()
-     * .getDefaultFocusTraversalKeys(id); } return (Set<AWTKeyStroke>) keys; }
-     * finally { toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * Checks if the the focus traversal keys are enabled for this component.
-     * 
-     * @return true, if the the focus traversal keys are enabled for this
-     *         component, false otherwise.
-     */
-    public boolean getFocusTraversalKeysEnabled() {
-        toolkit.lockAWT();
-        try {
-            return focusTraversalKeysEnabled;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the font metrics of the specified Font.
-     * 
-     * @param f
-     *            the Font.
-     * @return the FontMetrics of the specified Font.
-     */
-    @SuppressWarnings("deprecation")
-    public FontMetrics getFontMetrics(Font f) {
-        return toolkit.getFontMetrics(f);
-    }
-
-    /**
-     * Gets the foreground color of the Component.
-     * 
-     * @return the foreground color of the Component.
-     */
-    public Color getForeground() {
-        toolkit.lockAWT();
-        try {
-            // ???AWT
-            /*
-             * if (foreColor == null && parent != null) { return
-             * parent.getForeground(); }
-             */
-            return foreColor;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the Graphics of the Component or null if this Component is not
-     * displayable.
-     * 
-     * @return the Graphics of the Component or null if this Component is not
-     *         displayable.
-     */
-    public Graphics getGraphics() {
-        toolkit.lockAWT();
-        try {
-            if (!isDisplayable()) {
-                return null;
-            }
-            Graphics g = behaviour.getGraphics(0, 0, w, h);
-            g.setColor(foreColor);
-            g.setFont(font);
-            return g;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the GraphicsConfiguration associated with this Component.
-     * 
-     * @return the GraphicsConfiguration associated with this Component.
-     */
-    public GraphicsConfiguration getGraphicsConfiguration() {
-        // ???AWT
-        /*
-         * toolkit.lockAWT(); try { Window win = getWindowAncestor(); if (win ==
-         * null) { return null; } return win.getGraphicsConfiguration(); }
-         * finally { toolkit.unlockAWT(); }
-         */
-        return null;
-    }
-
-    /**
-     * Gets the height of the Component.
-     * 
-     * @return the height of the Component.
-     */
-    public int getHeight() {
-        toolkit.lockAWT();
-        try {
-            return h;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Returns true if paint messages received from the operating system should
-     * be ignored.
-     * 
-     * @return true if paint messages received from the operating system should
-     *         be ignored, false otherwise.
-     */
-    public boolean getIgnoreRepaint() {
-        toolkit.lockAWT();
-        try {
-            return ignoreRepaint;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the input context of this component for handling the communication
-     * with input methods when text is entered in this component.
-     * 
-     * @return the InputContext used by this Component or null if no context is
-     *         specifined.
-     */
-    public InputContext getInputContext() {
-        toolkit.lockAWT();
-        try {
-            // ???AWT
-            /*
-             * Container parent = getParent(); if (parent != null) { return
-             * parent.getInputContext(); }
-             */
-            return null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the input method request handler which supports requests from input
-     * methods for this component, or null for default.
-     * 
-     * @return the input method request handler which supports requests from
-     *         input methods for this component, or null for default.
-     */
-    public InputMethodRequests getInputMethodRequests() {
-        return null;
-    }
-
-    /**
-     * Gets the locale of this Component.
-     * 
-     * @return the locale of this Component.
-     */
-    public Locale getLocale() {
-        toolkit.lockAWT();
-        try {
-            // ???AWT
-            /*
-             * if (locale == null) { if (parent == null) { if (this instanceof
-             * Window) { return Locale.getDefault(); } // awt.150=no parent
-             * throw new
-             * IllegalComponentStateException(Messages.getString("awt.150"));
-             * //$NON-NLS-1$ } return getParent().getLocale(); }
-             */
-            return locale;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the location of this component in the form of a point specifying the
-     * component's top-left corner in the screen's coordinate space.
-     * 
-     * @return the Point giving the component's location in the screen's
-     *         coordinate space.
-     * @throws IllegalComponentStateException
-     *             if the component is not shown on the screen.
-     */
-    public Point getLocationOnScreen() throws IllegalComponentStateException {
-        toolkit.lockAWT();
-        try {
-            Point p = new Point();
-            if (isShowing()) {
-                // ???AWT
-                /*
-                 * Component comp; for (comp = this; comp != null && !(comp
-                 * instanceof Window); comp = comp .getParent()) {
-                 * p.translate(comp.getX(), comp.getY()); } if (comp instanceof
-                 * Window) { p.translate(comp.getX(), comp.getY()); }
-                 */
-                return p;
-            }
-            // awt.151=component must be showing on the screen to determine its
-            // location
-            throw new IllegalComponentStateException(Messages.getString("awt.151")); //$NON-NLS-1$
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the peer. This method should not be called directly by user
-     * applications.
-     * 
-     * @return the ComponentPeer.
-     * @deprecated Replaced by isDisplayable().
-     */
-    @Deprecated
-    public ComponentPeer getPeer() {
-        toolkit.lockAWT();
-        try {
-            if (behaviour.isDisplayable()) {
-                return peer;
-            }
-            return null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets an array of the property change listeners registered to this
-     * Component.
-     * 
-     * @return an array of the PropertyChangeListeners registered to this
-     *         Component.
-     */
-    public PropertyChangeListener[] getPropertyChangeListeners() {
-        return getPropertyChangeSupport().getPropertyChangeListeners();
-    }
-
-    /**
-     * Gets an array of PropertyChangeListener objects registered to this
-     * Component for the specified property.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @return an array of PropertyChangeListener objects registered to this
-     *         Component for the specified property.
-     */
-    public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
-        return getPropertyChangeSupport().getPropertyChangeListeners(propertyName);
-    }
-
-    /**
-     * Gets the width of the Component.
-     * 
-     * @return the width of the Component.
-     */
-    public int getWidth() {
-        toolkit.lockAWT();
-        try {
-            return w;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the x coordinate of the component's top-left corner.
-     * 
-     * @return the x coordinate of the component's top-left corner.
-     */
-    public int getX() {
-        toolkit.lockAWT();
-        try {
-            return x;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the y coordinate of the component's top-left corner.
-     * 
-     * @return the y coordinate of the component's top-left corner.
-     */
-    public int getY() {
-        toolkit.lockAWT();
-        try {
-            return y;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Got the focus.
-     * 
-     * @param evt
-     *            the Event.
-     * @param what
-     *            the Object.
-     * @return true, if successful.
-     * @deprecated Replaced by processFocusEvent(FocusEvent) method.
-     */
-    @Deprecated
-    public boolean gotFocus(Event evt, Object what) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Handles event.
-     * 
-     * @param evt
-     *            the Event.
-     * @return true, if successful.
-     * @deprecated Replaced by processEvent(AWTEvent) method.
-     */
-    @Deprecated
-    public boolean handleEvent(Event evt) {
-        switch (evt.id) {
-            case Event.ACTION_EVENT:
-                return action(evt, evt.arg);
-            case Event.GOT_FOCUS:
-                return gotFocus(evt, null);
-            case Event.LOST_FOCUS:
-                return lostFocus(evt, null);
-            case Event.MOUSE_DOWN:
-                return mouseDown(evt, evt.x, evt.y);
-            case Event.MOUSE_DRAG:
-                return mouseDrag(evt, evt.x, evt.y);
-            case Event.MOUSE_ENTER:
-                return mouseEnter(evt, evt.x, evt.y);
-            case Event.MOUSE_EXIT:
-                return mouseExit(evt, evt.x, evt.y);
-            case Event.MOUSE_MOVE:
-                return mouseMove(evt, evt.x, evt.y);
-            case Event.MOUSE_UP:
-                return mouseUp(evt, evt.x, evt.y);
-            case Event.KEY_ACTION:
-            case Event.KEY_PRESS:
-                return keyDown(evt, evt.key);
-            case Event.KEY_ACTION_RELEASE:
-            case Event.KEY_RELEASE:
-                return keyUp(evt, evt.key);
-        }
-        return false;// event not handled
-    }
-
-    /**
-     * Checks whether the Component is the focus owner or not.
-     * 
-     * @return true, if the Component is the focus owner, false otherwise.
-     */
-    public boolean hasFocus() {
-        toolkit.lockAWT();
-        try {
-            // ???AWT: return isFocusOwner();
-            return false;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Hides the Component.
-     * 
-     * @deprecated Replaced by setVisible(boolean) method.
-     */
-    @Deprecated
-    public void hide() {
-        toolkit.lockAWT();
-        try {
-            if (!visible) {
-                return;
-            }
-            prepare4HierarchyChange();
-            visible = false;
-            moveFocusOnHide();
-            behaviour.setVisible(false);
-            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_HIDDEN));
-            // ???AWT: finishHierarchyChange(this, parent, 0);
-            notifyInputMethod(null);
-            // ???AWT: invalidateRealParent();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not the point with the specified coordinates belongs to
-     * the Commponent.
-     * 
-     * @param x
-     *            the x coordinate of the Point.
-     * @param y
-     *            the y coordinate of the Point.
-     * @return true, if the point with the specified coordinates belongs to the
-     *         Commponent, false otherwise.
-     * @deprecated Replaced by contains(int, int) method.
-     */
-    @Deprecated
-    public boolean inside(int x, int y) {
-        toolkit.lockAWT();
-        try {
-            return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Invalidates the component, this component and all parents above it are
-     * marked as needing to be laid out.
-     */
-    public void invalidate() {
-        toolkit.lockAWT();
-        try {
-            valid = false;
-            resetDefaultSize();
-            // ???AWT: invalidateRealParent();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not the background color is set to this Component.
-     * 
-     * @return true, if the background color is set to this Component, false
-     *         otherwise.
-     */
-    public boolean isBackgroundSet() {
-        toolkit.lockAWT();
-        try {
-            return backColor != null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not a cursor is set for the Component.
-     * 
-     * @return true, if a cursor is set for the Component, false otherwise.
-     */
-    public boolean isCursorSet() {
-        toolkit.lockAWT();
-        try {
-            return cursor != null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not this Component is displayable.
-     * 
-     * @return true, if this Component is displayable, false otherwise.
-     */
-    public boolean isDisplayable() {
-        toolkit.lockAWT();
-        try {
-            return behaviour.isDisplayable();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not this component is painted to an buffer which is
-     * copied to the screen later.
-     * 
-     * @return true, if this component is painted to an buffer which is copied
-     *         to the screen later, false otherwise.
-     */
-    public boolean isDoubleBuffered() {
-        toolkit.lockAWT();
-        try {
-            // false by default
-            return false;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not this Component is enabled.
-     * 
-     * @return true, if this Component is enabled, false otherwise.
-     */
-    public boolean isEnabled() {
-        toolkit.lockAWT();
-        try {
-            return enabled;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * "Recursive" isEnabled().
-     * 
-     * @return true if not only component itself is enabled but its heavyweight
-     *         parent is also "indirectly" enabled.
-     */
-    boolean isIndirectlyEnabled() {
-        Component comp = this;
-        while (comp != null) {
-            if (!comp.isLightweight() && !comp.isEnabled()) {
-                return false;
-            }
-            // ???AWT: comp = comp.getRealParent();
-        }
-        return true;
-    }
-
-    /**
-     * Checks if the component is key enabled.
-     * 
-     * @return true, if the component is enabled and indirectly enabled.
-     */
-    boolean isKeyEnabled() {
-        if (!isEnabled()) {
-            return false;
-        }
-        return isIndirectlyEnabled();
-    }
-
-    /**
-     * Gets only parent of a child component, but not owner of a window.
-     * 
-     * @return parent of child component, null if component is a top-level
-     *         (Window instance).
-     */
-    // ???AWT
-    /*
-     * Container getRealParent() { return (!(this instanceof Window) ?
-     * getParent() : null); } public boolean isFocusCycleRoot(Container
-     * container) { toolkit.lockAWT(); try { return getFocusCycleRootAncestor()
-     * == container; } finally { toolkit.unlockAWT(); } } public boolean
-     * isFocusOwner() { toolkit.lockAWT(); try { return
-     * KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() ==
-     * this; } finally { toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * Checks whether or not this Component can be focusable.
-     * 
-     * @return true, if this Component can be focusable, false otherwise.
-     * @deprecated Replaced by isFocusable().
-     */
-    @Deprecated
-    public boolean isFocusTraversable() {
-        toolkit.lockAWT();
-        try {
-            overridenIsFocusable = false;
-            return focusable; // a Component must either be both focusable and
-            // focus traversable, or neither
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks if this Component can be focusable or not.
-     * 
-     * @return true, if this Component can be focusable, false otherwise.
-     */
-    public boolean isFocusable() {
-        toolkit.lockAWT();
-        try {
-            return isFocusTraversable();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks if the Font is set for this Component or not.
-     * 
-     * @return true, if the Font is set, false otherwise.
-     */
-    public boolean isFontSet() {
-        toolkit.lockAWT();
-        try {
-            return font != null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks if foreground color is set for the Component or not.
-     * 
-     * @return true, if is foreground color is set for the Component, false
-     *         otherwise.
-     */
-    public boolean isForegroundSet() {
-        toolkit.lockAWT();
-        try {
-            return foreColor != null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Returns true if this component has a lightweight peer.
-     * 
-     * @return true, if this component has a lightweight peer, false if it has a
-     *         native peer or no peer.
-     */
-    public boolean isLightweight() {
-        toolkit.lockAWT();
-        try {
-            return behaviour.isLightweight();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not this Component is shown.
-     * 
-     * @return true, if this Component is shown, false otherwise.
-     */
-    public boolean isShowing() {
-        // ???AWT
-        /*
-         * toolkit.lockAWT(); try { return (isVisible() && isDisplayable() &&
-         * (parent != null) && parent.isShowing()); } finally {
-         * toolkit.unlockAWT(); }
-         */
-        return false;
-    }
-
-    /**
-     * Checks whether or not this Component is visible.
-     * 
-     * @return true, if the Component is visible, false otherwise.
-     */
-    public boolean isVisible() {
-        toolkit.lockAWT();
-        try {
-            return visible;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Deprecated: replaced by processKeyEvent(KeyEvent) method.
-     * 
-     * @param evt
-     *            the Event.
-     * @param key
-     *            the key code.
-     * @return true, if successful.
-     * @deprecated Replaced by replaced by processKeyEvent(KeyEvent) method.
-     */
-    @Deprecated
-    public boolean keyDown(Event evt, int key) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Deprecated: replaced by processKeyEvent(KeyEvent) method.
-     * 
-     * @param evt
-     *            the Event.
-     * @param key
-     *            the key code.
-     * @return true, if successful.
-     * @deprecated Replaced by processKeyEvent(KeyEvent) method.
-     */
-    @Deprecated
-    public boolean keyUp(Event evt, int key) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Deprecated: Replaced by doLayout() method.
-     * 
-     * @deprecated Replaced by doLayout() method.
-     */
-    @Deprecated
-    public void layout() {
-        toolkit.lockAWT();
-        try {
-            // Implemented in Container
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Deprecated: replaced by getComponentAt(int, int) method.
-     * 
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @return The component.
-     * @deprecated Replaced by getComponentAt(int, int) method.
-     */
-    @Deprecated
-    public Component locate(int x, int y) {
-        toolkit.lockAWT();
-        try {
-            if (contains(x, y)) {
-                return this;
-            }
-            return null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Deprecated: replaced by processFocusEvent(FocusEvent).
-     * 
-     * @param evt
-     *            the Event.
-     * @param what
-     *            the Object.
-     * @return true, if successful.
-     * @deprecated Replaced by processFocusEvent(FocusEvent).
-     */
-    @Deprecated
-    public boolean lostFocus(Event evt, Object what) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Deprecated: replaced by processMouseEvent(MouseEvent) method.
-     * 
-     * @param evt
-     *            the MouseEvent.
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @return true, if successful.
-     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
-     */
-    @Deprecated
-    public boolean mouseDown(Event evt, int x, int y) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Deprecated: replaced by getMinimumSize() method.
-     * 
-     * @param evt
-     *            the Event.
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @return true, if successful.
-     * @deprecated Replaced by getMinimumSize() method.
-     */
-    @Deprecated
-    public boolean mouseDrag(Event evt, int x, int y) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Replaced by processMouseEvent(MouseEvent) method.
-     * 
-     * @param evt
-     *            the Event.
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @return true, if successful.
-     * @deprecated replaced by processMouseEvent(MouseEvent) method.
-     */
-    @Deprecated
-    public boolean mouseEnter(Event evt, int x, int y) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Replaced by processMouseEvent(MouseEvent) method.
-     * 
-     * @param evt
-     *            the Event.
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @return true, if successful.
-     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
-     */
-    @Deprecated
-    public boolean mouseExit(Event evt, int x, int y) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Replaced by processMouseEvent(MouseEvent) method.
-     * 
-     * @param evt
-     *            the Event.
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
-     * @return true, if successful.
-     */
-    @Deprecated
-    public boolean mouseMove(Event evt, int x, int y) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Replaced by processMouseEvent(MouseEvent) method.
-     * 
-     * @param evt
-     *            the Event.
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @return true, if successful.
-     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
-     */
-    @Deprecated
-    public boolean mouseUp(Event evt, int x, int y) {
-        // to be overridden: do nothing,
-        // just return false to propagate event up to the parent container
-        return false;
-    }
-
-    /**
-     * Deprecated: replaced by setLocation(int, int) method.
-     * 
-     * @param x
-     *            the x coordinates.
-     * @param y
-     *            the y coordinates.
-     * @deprecated Replaced by setLocation(int, int) method.
-     */
-    @Deprecated
-    public void move(int x, int y) {
-        toolkit.lockAWT();
-        try {
-            boundsMaskParam = NativeWindow.BOUNDS_NOSIZE;
-            setBounds(x, y, w, h);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    // ???AWT
-    /*
-     * @Deprecated public void nextFocus() { toolkit.lockAWT(); try {
-     * transferFocus(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); } finally {
-     * toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * Returns a string representation of the component's state.
-     * 
-     * @return the string representation of the component's state.
-     */
-    protected String paramString() {
-        /*
-         * The format is based on 1.5 release behavior which can be revealed by
-         * the following code: Component c = new Component(){};
-         * c.setVisible(false); System.out.println(c);
-         */
-        toolkit.lockAWT();
-        try {
-            return getName() + "," + getX() + "," + getY() + "," + getWidth() + "x" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-                    + getHeight() + (!isVisible() ? ",hidden" : ""); //$NON-NLS-1$ //$NON-NLS-2$
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    @Deprecated
-    @SuppressWarnings("deprecation")
-    public boolean postEvent(Event evt) {
-        boolean handled = handleEvent(evt);
-        if (handled) {
-            return true;
-        }
-        // ???AWT
-        /*
-         * // propagate non-handled events up to parent Component par = parent;
-         * // try to call postEvent only on components which // override any of
-         * deprecated method handlers // while (par != null &&
-         * !par.deprecatedEventHandler) { // par = par.parent; // } // translate
-         * event coordinates before posting it to parent if (par != null) {
-         * evt.translate(x, y); par.postEvent(evt); }
-         */
-        return false;
-    }
-
-    /**
-     * Prepares an image for rendering on the Component.
-     * 
-     * @param image
-     *            the Image to be prepared.
-     * @param observer
-     *            the ImageObserver object to be notified as soon as the image
-     *            is prepared.
-     * @return true if the image has been fully prepared, false otherwise.
-     */
-    public boolean prepareImage(Image image, ImageObserver observer) {
-        toolkit.lockAWT();
-        try {
-            return toolkit.prepareImage(image, -1, -1, observer);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Prepares an image for rendering on the Component with the specified
-     * width, height, and ImageObserver.
-     * 
-     * @param image
-     *            the Image to be prepared.
-     * @param width
-     *            the width of scaled image.
-     * @param height
-     *            the height of scaled height.
-     * @param observer
-     *            the ImageObserver object to be notified as soon as the image
-     *            is prepared.
-     * @return true if the image is been fully prepared, false otherwise.
-     */
-    public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
-        toolkit.lockAWT();
-        try {
-            return toolkit.prepareImage(image, width, height, observer);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Makes this Component undisplayable.
-     */
-    public void removeNotify() {
-        toolkit.lockAWT();
-        try {
-            // ???AWT
-            /*
-             * if (dropTarget != null) { dropTarget.removeNotify(peer); }
-             */
-            prepare4HierarchyChange();
-            // /???AWT: moveFocus();
-            behaviour.removeNotify();
-            // ???AWT: finishHierarchyChange(this, parent, 0);
-            removeNotifyInputContext();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Calls InputContext.removeNotify.
-     */
-    private void removeNotifyInputContext() {
-        if (!inputMethodsEnabled) {
-            return;
-        }
-        InputContext ic = getInputContext();
-        if (ic != null) {
-            // ???AWT: ic.removeNotify(this);
-        }
-    }
-
-    /**
-     * This method is called when some property of a component changes, making
-     * it unfocusable, e. g. hide(), removeNotify(), setEnabled(false),
-     * setFocusable(false) is called, and therefore automatic forward focus
-     * traversal is necessary
-     */
-    // ???AWT
-    /*
-     * void moveFocus() { // don't use transferFocus(), but query focus
-     * traversal policy directly // and if it returns null, transfer focus up
-     * cycle // and find next focusable component there KeyboardFocusManager kfm
-     * = KeyboardFocusManager.getCurrentKeyboardFocusManager(); Container root =
-     * kfm.getCurrentFocusCycleRoot(); Component nextComp = this; boolean
-     * success = !isFocusOwner(); while (!success) { if (root !=
-     * nextComp.getFocusCycleRootAncestor()) { // component was probably removed
-     * from container // so focus will be lost in some time return; } nextComp =
-     * root.getFocusTraversalPolicy().getComponentAfter(root, nextComp); if
-     * (nextComp == this) { nextComp = null; // avoid looping } if (nextComp !=
-     * null) { success = nextComp.requestFocusInWindow(); } else { nextComp =
-     * root; root = root.getFocusCycleRootAncestor(); // if no acceptable
-     * component is found at all - clear global // focus owner if (root == null)
-     * { if (nextComp instanceof Window) { Window wnd = (Window) nextComp;
-     * wnd.setFocusOwner(null); wnd.setRequestedFocus(null); }
-     * kfm.clearGlobalFocusOwner(); return; } } } }
-     */
-
-    /**
-     * For Container there's a difference between moving focus when being made
-     * invisible or made unfocusable in some other way, because when container
-     * is made invisible, component still remains visible, i. e. its hide() or
-     * setVisible() is not called.
-     */
-    void moveFocusOnHide() {
-        // ???AWT: moveFocus();
-    }
-
-    /**
-     * Removes the property change listener registered for this component.
-     * 
-     * @param listener
-     *            the PropertyChangeListener.
-     */
-    public void removePropertyChangeListener(PropertyChangeListener listener) {
-        getPropertyChangeSupport().removePropertyChangeListener(listener);
-    }
-
-    /**
-     * Removes the property change listener registered fot this component for
-     * the specified propertyy.
-     * 
-     * @param propertyName
-     *            the property name.
-     * @param listener
-     *            the PropertyChangeListener.
-     */
-    public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
-        getPropertyChangeSupport().removePropertyChangeListener(propertyName, listener);
-    }
-
-    /**
-     * Repaints the specified rectangle of this component within tm
-     * milliseconds.
-     * 
-     * @param tm
-     *            the time in milliseconds before updating.
-     * @param x
-     *            the x coordinate of Rectangle.
-     * @param y
-     *            the y coordinate of Rectangle.
-     * @param width
-     *            the width of Rectangle.
-     * @param height
-     *            the height of Rectangle.
-     */
-    public void repaint(long tm, int x, int y, int width, int height) {
-        // ???AWT
-        /*
-         * toolkit.lockAWT(); try { if (width <= 0 || height <= 0 ||
-         * (redrawManager == null) || !isShowing()) { return; } if (behaviour
-         * instanceof LWBehavior) { if (parent == null || !parent.visible ||
-         * !parent.behaviour.isDisplayable()) { return; } if (repaintRegion ==
-         * null) { repaintRegion = new MultiRectArea(new Rectangle(x, y, width,
-         * height)); } repaintRegion.intersect(new Rectangle(0, 0, this.w,
-         * this.h)); repaintRegion.translate(this.x, this.y);
-         * parent.repaintRegion = repaintRegion; repaintRegion = null;
-         * parent.repaint(tm, x + this.x, y + this.y, width, height); } else {
-         * if (repaintRegion != null) { redrawManager.addUpdateRegion(this,
-         * repaintRegion); repaintRegion = null; } else {
-         * redrawManager.addUpdateRegion(this, new Rectangle(x, y, width,
-         * height)); }
-         * toolkit.getSystemEventQueueCore().notifyEventMonitor(toolkit); } }
-         * finally { toolkit.unlockAWT(); }
-         */
-    }
-
-    /**
-     * Post event.
-     * 
-     * @param e
-     *            the e.
-     */
-    void postEvent(AWTEvent e) {
-        getToolkit().getSystemEventQueueImpl().postEvent(e);
-    }
-
-    /**
-     * Repaints the specified Rectangle of this Component.
-     * 
-     * @param x
-     *            the x coordinate of Rectangle.
-     * @param y
-     *            the y coordinate of Rectangle.
-     * @param width
-     *            the width of Rectangle.
-     * @param height
-     *            the height of Rectangle.
-     */
-    public void repaint(int x, int y, int width, int height) {
-        toolkit.lockAWT();
-        try {
-            repaint(0, x, y, width, height);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Repaints this component.
-     */
-    public void repaint() {
-        toolkit.lockAWT();
-        try {
-            if (w > 0 && h > 0) {
-                repaint(0, 0, 0, w, h);
-            }
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Repaints the component within tm milliseconds.
-     * 
-     * @param tm
-     *            the time in milliseconds before updating.
-     */
-    public void repaint(long tm) {
-        toolkit.lockAWT();
-        try {
-            repaint(tm, 0, 0, w, h);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Requests that this Component get the input focus temporarily. This
-     * component must be displayable, visible, and focusable.
-     * 
-     * @param temporary
-     *            this parameter is true if the focus change is temporary, when
-     *            the window loses the focus.
-     * @return true if the focus change request is succeeded, false otherwise.
-     */
-    protected boolean requestFocus(boolean temporary) {
-        toolkit.lockAWT();
-        try {
-            // ???AWT: return requestFocusImpl(temporary, true, false);
-        } finally {
-            toolkit.unlockAWT();
-        }
-        // ???AWT
-        return false;
-    }
-
-    /**
-     * Requests that this Component get the input focus. This component must be
-     * displayable, visible, and focusable.
-     */
-    public void requestFocus() {
-        toolkit.lockAWT();
-        try {
-            requestFocus(false);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    // ???AWT
-    /*
-     * protected boolean requestFocusInWindow(boolean temporary) {
-     * toolkit.lockAWT(); try { Window wnd = getWindowAncestor(); if ((wnd ==
-     * null) || !wnd.isFocused()) { return false; } return
-     * requestFocusImpl(temporary, false, false); } finally {
-     * toolkit.unlockAWT(); } } boolean requestFocusImpl(boolean temporary,
-     * boolean crossWindow, boolean rejectionRecovery) { if (!rejectionRecovery
-     * && isFocusOwner()) { return true; } Window wnd = getWindowAncestor();
-     * Container par = getRealParent(); if ((par != null) && par.isRemoved) {
-     * return false; } if (!isShowing() || !isFocusable() ||
-     * !wnd.isFocusableWindow()) { return false; } return
-     * KeyboardFocusManager.getCurrentKeyboardFocusManager().requestFocus(this,
-     * temporary, crossWindow, true); } public boolean requestFocusInWindow() {
-     * toolkit.lockAWT(); try { return requestFocusInWindow(false); } finally {
-     * toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * Deprecated: replaced by setBounds(int, int, int, int) method.
-     * 
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @param w
-     *            the width.
-     * @param h
-     *            the height.
-     * @deprecated Replaced by setBounds(int, int, int, int) method.
-     */
-    @Deprecated
-    public void reshape(int x, int y, int w, int h) {
-        toolkit.lockAWT();
-        try {
-            setBounds(x, y, w, h, boundsMaskParam, true);
-            boundsMaskParam = 0;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets rectangle for this Component to be the rectangle with the specified
-     * x,y coordinates of the top-left corner and the width and height.
-     * 
-     * @param x
-     *            the x coordinate of the rectangle's top-left corner.
-     * @param y
-     *            the y coordinate of the rectangle's top-left corner.
-     * @param w
-     *            the width of rectangle.
-     * @param h
-     *            the height of rectangle.
-     */
-    public void setBounds(int x, int y, int w, int h) {
-        toolkit.lockAWT();
-        try {
-            reshape(x, y, w, h);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets rectangle for this Component to be the rectangle with the specified
-     * x,y coordinates of the top-left corner and the width and height and posts
-     * the appropriate events.
-     * 
-     * @param x
-     *            the x coordinate of the rectangle's top-left corner.
-     * @param y
-     *            the y coordinate of the rectangle's top-left corner.
-     * @param w
-     *            the width of rectangle.
-     * @param h
-     *            the height of rectangle.
-     * @param bMask
-     *            the bitmask of bounds options.
-     * @param updateBehavior
-     *            the whether to update the behavoir's bounds as well.
-     */
-    void setBounds(int x, int y, int w, int h, int bMask, boolean updateBehavior) {
-        int oldX = this.x;
-        int oldY = this.y;
-        int oldW = this.w;
-        int oldH = this.h;
-        setBoundsFields(x, y, w, h, bMask);
-        // Moved
-        if ((oldX != this.x) || (oldY != this.y)) {
-            // ???AWT: invalidateRealParent();
-            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_MOVED));
-            spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_MOVED);
-        }
-        // Resized
-        if ((oldW != this.w) || (oldH != this.h)) {
-            invalidate();
-            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
-            spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_RESIZED);
-        }
-        if (updateBehavior) {
-            behaviour.setBounds(this.x, this.y, this.w, this.h, bMask);
-        }
-        notifyInputMethod(new Rectangle(x, y, w, h));
-    }
-
-    /**
-     * Calls InputContextImpl.notifyClientWindowChanged.
-     * 
-     * @param bounds
-     *            the bounds.
-     */
-    void notifyInputMethod(Rectangle bounds) {
-        // only Window actually notifies IM of bounds change
-    }
-
-    /**
-     * Sets the bounds fields.
-     * 
-     * @param x
-     *            the x.
-     * @param y
-     *            the y.
-     * @param w
-     *            the w.
-     * @param h
-     *            the h.
-     * @param bMask
-     *            the b mask.
-     */
-    private void setBoundsFields(int x, int y, int w, int h, int bMask) {
-        if ((bMask & NativeWindow.BOUNDS_NOSIZE) == 0) {
-            this.w = w;
-            this.h = h;
-        }
-        if ((bMask & NativeWindow.BOUNDS_NOMOVE) == 0) {
-            this.x = x;
-            this.y = y;
-        }
-    }
-
-    /**
-     * Gets the native insets.
-     * 
-     * @return the native insets.
-     */
-    Insets getNativeInsets() {
-        return new Insets(0, 0, 0, 0);
-    }
-
-    /**
-     * Gets the insets.
-     * 
-     * @return the insets.
-     */
-    Insets getInsets() {
-        return new Insets(0, 0, 0, 0);
-    }
-
-    /**
-     * Checks if is mouse exited expected.
-     * 
-     * @return true, if is mouse exited expected.
-     */
-    boolean isMouseExitedExpected() {
-        return mouseExitedExpected;
-    }
-
-    /**
-     * Sets the mouse exited expected.
-     * 
-     * @param expected
-     *            the new mouse exited expected.
-     */
-    void setMouseExitedExpected(boolean expected) {
-        mouseExitedExpected = expected;
-    }
-
-    /**
-     * Sets the new bounding rectangle for this Component.
-     * 
-     * @param r
-     *            the new bounding rectangle.
-     */
-    public void setBounds(Rectangle r) {
-        toolkit.lockAWT();
-        try {
-            setBounds(r.x, r.y, r.width, r.height);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the component orientation which affects the component's elements and
-     * text within this component.
-     * 
-     * @param o
-     *            the ComponentOrientation object.
-     */
-    public void setComponentOrientation(ComponentOrientation o) {
-        ComponentOrientation oldOrientation;
-        toolkit.lockAWT();
-        try {
-            oldOrientation = orientation;
-            orientation = o;
-        } finally {
-            toolkit.unlockAWT();
-        }
-        firePropertyChange("componentOrientation", oldOrientation, orientation); //$NON-NLS-1$
-        invalidate();
-    }
-
-    /**
-     * Sets the specified cursor for this Component.
-     * 
-     * @param cursor
-     *            the new Cursor.
-     */
-    public void setCursor(Cursor cursor) {
-        toolkit.lockAWT();
-        try {
-            this.cursor = cursor;
-            setCursor();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Set current cursor shape to Component's Cursor.
-     */
-    void setCursor() {
-        if (isDisplayable() && isShowing()) {
-            Rectangle absRect = new Rectangle(getLocationOnScreen(), getSize());
-            Point absPointerPos = toolkit.dispatcher.mouseDispatcher.getPointerPos();
-            // ???AWT
-            /*
-             * if (absRect.contains(absPointerPos)) { // set Cursor only on
-             * top-level Windows(on X11) Window topLevelWnd =
-             * getWindowAncestor(); if (topLevelWnd != null) { Point pointerPos
-             * = MouseDispatcher.convertPoint(null, absPointerPos, topLevelWnd);
-             * Component compUnderCursor =
-             * topLevelWnd.findComponentAt(pointerPos); // if (compUnderCursor
-             * == this || // compUnderCursor.getCursorAncestor() == this) {
-             * NativeWindow wnd = topLevelWnd.getNativeWindow(); if
-             * (compUnderCursor != null && wnd != null) {
-             * compUnderCursor.getRealCursor().getNativeCursor()
-             * .setCursor(wnd.getId()); } // } } }
-             */
-        }
-    }
-
-    /**
-     * Gets the ancestor Cursor if Component is disabled (directly or via an
-     * ancestor) even if Cursor is explicitly set.
-     * 
-     * @param value
-     *            the value.
-     * @return the actual Cursor to be displayed.
-     */
-    // ???AWT
-    /*
-     * Cursor getRealCursor() { Component cursorAncestor = getCursorAncestor();
-     * return cursorAncestor != null ? cursorAncestor.getCursor() :
-     * Cursor.getDefaultCursor(); }
-     */
-
-    /**
-     * Gets the ancestor(or component itself) whose cursor is set when pointer
-     * is inside component
-     * 
-     * @return the actual Cursor to be displayed.
-     */
-    // ???AWT
-    /*
-     * Component getCursorAncestor() { Component comp; for (comp = this; comp !=
-     * null; comp = comp.getParent()) { if (comp instanceof Window ||
-     * comp.isCursorSet() && comp.isKeyEnabled()) { return comp; } } return
-     * null; } public void setDropTarget(DropTarget dt) { toolkit.lockAWT(); try
-     * { if (dropTarget == dt) { return; } DropTarget oldDropTarget =
-     * dropTarget; dropTarget = dt; if (oldDropTarget != null) { if
-     * (behaviour.isDisplayable()) { oldDropTarget.removeNotify(peer); }
-     * oldDropTarget.setComponent(null); } if (dt != null) {
-     * dt.setComponent(this); if (behaviour.isDisplayable()) {
-     * dt.addNotify(peer); } } } finally { toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * Sets this component to the "enabled" or "disabled" state depending on the
-     * specified boolean parameter.
-     * 
-     * @param value
-     *            true if this component should be enabled; false if this
-     *            component should be disabled.
-     */
-    public void setEnabled(boolean value) {
-        toolkit.lockAWT();
-        try {
-            enable(value);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the enabled impl.
-     * 
-     * @param value
-     *            the new enabled impl.
-     */
-    void setEnabledImpl(boolean value) {
-        if (enabled != value) {
-            enabled = value;
-            setCursor();
-            if (!enabled) {
-                moveFocusOnHide();
-            }
-            behaviour.setEnabled(value);
-        }
-    }
-
-    // ???AWT
-    /*
-     * private void fireAccessibleStateChange(AccessibleState state, boolean
-     * value) { if (behaviour.isLightweight()) { return; } AccessibleContext ac
-     * = getAccessibleContext(); if (ac != null) { AccessibleState oldValue =
-     * null; AccessibleState newValue = null; if (value) { newValue = state; }
-     * else { oldValue = state; }
-     * ac.firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
-     * oldValue, newValue); } }
-     */
-
-    // ???AWT
-    /*
-     * public void setFocusTraversalKeys(int id, Set<? extends AWTKeyStroke>
-     * keystrokes) { Set<? extends AWTKeyStroke> oldTraversalKeys; String
-     * propName = "FocusTraversalKeys"; //$NON-NLS-1$ toolkit.lockAWT(); try {
-     * Integer kId = new Integer(id);
-     * KeyboardFocusManager.checkTraversalKeysID(traversalKeys, kId);
-     * Map<Integer, Set<? extends AWTKeyStroke>> keys = new HashMap<Integer,
-     * Set<? extends AWTKeyStroke>>(); for (int kid : traversalIDs) { Integer
-     * key = new Integer(kid); keys.put(key, getFocusTraversalKeys(kid)); }
-     * KeyboardFocusManager.checkKeyStrokes(traversalIDs, keys, kId,
-     * keystrokes); oldTraversalKeys = traversalKeys.get(new Integer(id)); //
-     * put a copy of keystrokes object into map: Set<? extends AWTKeyStroke>
-     * newKeys = keystrokes; if (keystrokes != null) { newKeys = new
-     * HashSet<AWTKeyStroke>(keystrokes); } traversalKeys.put(kId, newKeys);
-     * String direction = ""; //$NON-NLS-1$ switch (id) { case
-     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS: direction = "forward";
-     * //$NON-NLS-1$ break; case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
-     * direction = "backward"; //$NON-NLS-1$ break; case
-     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS: direction = "upCycle";
-     * //$NON-NLS-1$ break; case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
-     * direction = "downCycle"; //$NON-NLS-1$ break; } propName = direction +
-     * propName; } finally { toolkit.unlockAWT(); } firePropertyChange(propName,
-     * oldTraversalKeys, keystrokes); }
-     */
-
-    /**
-     * Sets the focus traversal keys state for this component.
-     * 
-     * @param value
-     *            true if the focus traversal keys state is enabled, false if
-     *            the focus traversal keys state is disabled.
-     */
-    public void setFocusTraversalKeysEnabled(boolean value) {
-        boolean oldFocusTraversalKeysEnabled;
-        toolkit.lockAWT();
-        try {
-            oldFocusTraversalKeysEnabled = focusTraversalKeysEnabled;
-            focusTraversalKeysEnabled = value;
-        } finally {
-            toolkit.unlockAWT();
-        }
-        firePropertyChange("focusTraversalKeysEnabled", oldFocusTraversalKeysEnabled, //$NON-NLS-1$
-                focusTraversalKeysEnabled);
-    }
-
-    // ???AWT
-    /*
-     * public void setFocusable(boolean focusable) { boolean oldFocusable;
-     * toolkit.lockAWT(); try { calledSetFocusable = true; oldFocusable =
-     * this.focusable; this.focusable = focusable; if (!focusable) {
-     * moveFocus(); } } finally { toolkit.unlockAWT(); }
-     * firePropertyChange("focusable", oldFocusable, focusable); //$NON-NLS-1$ }
-     * public Font getFont() { toolkit.lockAWT(); try { return (font == null) &&
-     * (parent != null) ? parent.getFont() : font; } finally {
-     * toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * Sets the font for this Component.
-     * 
-     * @param f
-     *            the new font of the Component.
-     */
-    public void setFont(Font f) {
-        Font oldFont;
-        toolkit.lockAWT();
-        try {
-            oldFont = font;
-            setFontImpl(f);
-        } finally {
-            toolkit.unlockAWT();
-        }
-        firePropertyChange("font", oldFont, font); //$NON-NLS-1$
-    }
-
-    /**
-     * Sets the font impl.
-     * 
-     * @param f
-     *            the new font impl.
-     */
-    void setFontImpl(Font f) {
-        font = f;
-        invalidate();
-        if (isShowing()) {
-            repaint();
-        }
-    }
-
-    /**
-     * Invalidate the component if it inherits the font from the parent. This
-     * method is overridden in Container.
-     * 
-     * @return true if the component was invalidated, false otherwise.
-     */
-    boolean propagateFont() {
-        if (font == null) {
-            invalidate();
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Sets the foreground color for this Component.
-     * 
-     * @param c
-     *            the new foreground color.
-     */
-    public void setForeground(Color c) {
-        Color oldFgColor;
-        toolkit.lockAWT();
-        try {
-            oldFgColor = foreColor;
-            foreColor = c;
-        } finally {
-            toolkit.unlockAWT();
-        }
-        firePropertyChange("foreground", oldFgColor, foreColor); //$NON-NLS-1$
-        repaint();
-    }
-
-    /**
-     * Sets the background color for the Component.
-     * 
-     * @param c
-     *            the new background color for this component.
-     */
-    public void setBackground(Color c) {
-        Color oldBkColor;
-        toolkit.lockAWT();
-        try {
-            oldBkColor = backColor;
-            backColor = c;
-        } finally {
-            toolkit.unlockAWT();
-        }
-        firePropertyChange("background", oldBkColor, backColor); //$NON-NLS-1$
-        repaint();
-    }
-
-    /**
-     * Sets the flag for whether paint messages received from the operating
-     * system should be ignored or not.
-     * 
-     * @param value
-     *            true if paint messages received from the operating system
-     *            should be ignored, false otherwise.
-     */
-    public void setIgnoreRepaint(boolean value) {
-        toolkit.lockAWT();
-        try {
-            ignoreRepaint = value;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the locale of the component.
-     * 
-     * @param locale
-     *            the new Locale.
-     */
-    public void setLocale(Locale locale) {
-        Locale oldLocale;
-        toolkit.lockAWT();
-        try {
-            oldLocale = this.locale;
-            this.locale = locale;
-        } finally {
-            toolkit.unlockAWT();
-        }
-        firePropertyChange("locale", oldLocale, locale); //$NON-NLS-1$
-    }
-
-    /**
-     * Sets the location of the Component to the specified point.
-     * 
-     * @param p
-     *            the new location of the Component.
-     */
-    public void setLocation(Point p) {
-        toolkit.lockAWT();
-        try {
-            setLocation(p.x, p.y);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the location of the Component to the specified x, y coordinates.
-     * 
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     */
-    public void setLocation(int x, int y) {
-        toolkit.lockAWT();
-        try {
-            move(x, y);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the visibility state of the component.
-     * 
-     * @param b
-     *            true if the component is visible, false if the component is
-     *            not shown.
-     */
-    public void setVisible(boolean b) {
-        // show() & hide() are not deprecated for Window,
-        // so have to call them from setVisible()
-        show(b);
-    }
-
-    /**
-     * Deprecated: replaced by setVisible(boolean) method.
-     * 
-     * @deprecated Replaced by setVisible(boolean) method.
-     */
-    @Deprecated
-    public void show() {
-        toolkit.lockAWT();
-        try {
-            if (visible) {
-                return;
-            }
-            prepare4HierarchyChange();
-            mapToDisplay(true);
-            validate();
-            visible = true;
-            behaviour.setVisible(true);
-            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_SHOWN));
-            // ???AWT: finishHierarchyChange(this, parent, 0);
-            notifyInputMethod(new Rectangle(x, y, w, h));
-            // ???AWT: invalidateRealParent();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Deprecated: replaced by setVisible(boolean) method.
-     * 
-     * @param b
-     *            the visibility's state.
-     * @deprecated Replaced by setVisible(boolean) method.
-     */
-    @Deprecated
-    public void show(boolean b) {
-        if (b) {
-            show();
-        } else {
-            hide();
-        }
-    }
-
-    // ???AWT
-    /*
-     * void transferFocus(int dir) { Container root = null; if (this instanceof
-     * Container) { Container cont = (Container) this; if
-     * (cont.isFocusCycleRoot()) { root = cont.getFocusTraversalRoot(); } } if
-     * (root == null) { root = getFocusCycleRootAncestor(); } // transfer focus
-     * up cycle if root is unreachable Component comp = this; while ((root !=
-     * null) && !(root.isFocusCycleRoot() && root.isShowing() &&
-     * root.isEnabled() && root .isFocusable())) { comp = root; root =
-     * root.getFocusCycleRootAncestor(); } if (root == null) { return; }
-     * FocusTraversalPolicy policy = root.getFocusTraversalPolicy(); Component
-     * nextComp = null; switch (dir) { case
-     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS: nextComp =
-     * policy.getComponentAfter(root, comp); break; case
-     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS: nextComp =
-     * policy.getComponentBefore(root, comp); break; } if (nextComp != null) {
-     * nextComp.requestFocus(false); } } public void transferFocus() {
-     * toolkit.lockAWT(); try { nextFocus(); } finally { toolkit.unlockAWT(); }
-     * } public void transferFocusBackward() { toolkit.lockAWT(); try {
-     * transferFocus(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); } finally {
-     * toolkit.unlockAWT(); } } public void transferFocusUpCycle() {
-     * toolkit.lockAWT(); try { KeyboardFocusManager kfm =
-     * KeyboardFocusManager.getCurrentKeyboardFocusManager(); Container root =
-     * kfm.getCurrentFocusCycleRoot(); if(root == null) { return; } boolean
-     * success = false; Component nextComp = null; Container newRoot = root; do
-     * { nextComp = newRoot instanceof Window ?
-     * newRoot.getFocusTraversalPolicy() .getDefaultComponent(newRoot) :
-     * newRoot; newRoot = newRoot.getFocusCycleRootAncestor(); if (nextComp ==
-     * null) { break; } success = nextComp.requestFocusInWindow(); if (newRoot
-     * == null) { break; } kfm.setGlobalCurrentFocusCycleRoot(newRoot); } while
-     * (!success); if (!success && root != newRoot) {
-     * kfm.setGlobalCurrentFocusCycleRoot(root); } } finally {
-     * toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * Validates that this component has a valid layout.
-     */
-    public void validate() {
-        toolkit.lockAWT();
-        try {
-            if (!behaviour.isDisplayable()) {
-                return;
-            }
-            validateImpl();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Validate impl.
-     */
-    void validateImpl() {
-        valid = true;
-    }
-
-    /**
-     * Gets the native window.
-     * 
-     * @return the native window.
-     */
-    NativeWindow getNativeWindow() {
-        return behaviour.getNativeWindow();
-    }
-
-    /**
-     * Checks whether or not a maximum size is set for the Component.
-     * 
-     * @return true, if the maximum size is set for the Component, false
-     *         otherwise.
-     */
-    public boolean isMaximumSizeSet() {
-        toolkit.lockAWT();
-        try {
-            return maximumSize != null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not the minimum size is set for the component.
-     * 
-     * @return true, if the minimum size is set for the component, false
-     *         otherwise.
-     */
-    public boolean isMinimumSizeSet() {
-        toolkit.lockAWT();
-        try {
-            return minimumSize != null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks whether or not the preferred size is set for the Component.
-     * 
-     * @return true, if the preferred size is set for the Component, false
-     *         otherwise.
-     */
-    public boolean isPreferredSizeSet() {
-        toolkit.lockAWT();
-        try {
-            return preferredSize != null;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the maximum size of the Component.
-     * 
-     * @return the maximum size of the Component.
-     */
-    public Dimension getMaximumSize() {
-        toolkit.lockAWT();
-        try {
-            return isMaximumSizeSet() ? new Dimension(maximumSize) : new Dimension(Short.MAX_VALUE,
-                    Short.MAX_VALUE);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the minimum size of the Component.
-     * 
-     * @return the minimum size of the Component.
-     */
-    public Dimension getMinimumSize() {
-        toolkit.lockAWT();
-        try {
-            return minimumSize();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Deprecated: replaced by getMinimumSize() method.
-     * 
-     * @return the Dimension.
-     * @deprecated Replaced by getMinimumSize() method.
-     */
-    @Deprecated
-    public Dimension minimumSize() {
-        toolkit.lockAWT();
-        try {
-            if (isMinimumSizeSet()) {
-                return (Dimension)minimumSize.clone();
-            }
-            Dimension defSize = getDefaultMinimumSize();
-            if (defSize != null) {
-                return (Dimension)defSize.clone();
-            }
-            return isDisplayable() ? new Dimension(1, 1) : new Dimension(w, h);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the preferred size of the Component.
-     * 
-     * @return the preferred size of the Component.
-     */
-    public Dimension getPreferredSize() {
-        toolkit.lockAWT();
-        try {
-            return preferredSize();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Deprecated: replaced by getPreferredSize() method.
-     * 
-     * @return the Dimension.
-     * @deprecated Replaced by getPreferredSize() method.
-     */
-    @Deprecated
-    public Dimension preferredSize() {
-        toolkit.lockAWT();
-        try {
-            if (isPreferredSizeSet()) {
-                return new Dimension(preferredSize);
-            }
-            Dimension defSize = getDefaultPreferredSize();
-            if (defSize != null) {
-                return new Dimension(defSize);
-            }
-            return new Dimension(getMinimumSize());
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the maximum size of the Component.
-     * 
-     * @param maximumSize
-     *            the new maximum size of the Component.
-     */
-    public void setMaximumSize(Dimension maximumSize) {
-        Dimension oldMaximumSize;
-        toolkit.lockAWT();
-        try {
-            oldMaximumSize = this.maximumSize;
-            if (oldMaximumSize != null) {
-                oldMaximumSize = oldMaximumSize.getSize();
-            }
-            if (this.maximumSize == null) {
-                if (maximumSize != null) {
-                    this.maximumSize = new Dimension(maximumSize);
-                }
-            } else {
-                if (maximumSize != null) {
-                    this.maximumSize.setSize(maximumSize);
-                } else {
-                    this.maximumSize = null;
-                }
-            }
-        } finally {
-            toolkit.unlockAWT();
-        }
-        firePropertyChange("maximumSize", oldMaximumSize, this.maximumSize); //$NON-NLS-1$
-        toolkit.lockAWT();
-        try {
-            // ???AWT: invalidateRealParent();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the minimum size of the Component.
-     * 
-     * @param minimumSize
-     *            the new minimum size of the Component.
-     */
-    public void setMinimumSize(Dimension minimumSize) {
-        Dimension oldMinimumSize;
-        toolkit.lockAWT();
-        try {
-            oldMinimumSize = this.minimumSize;
-            if (oldMinimumSize != null) {
-                oldMinimumSize = oldMinimumSize.getSize();
-            }
-            if (this.minimumSize == null) {
-                if (minimumSize != null) {
-                    this.minimumSize = new Dimension(minimumSize);
-                }
-            } else {
-                if (minimumSize != null) {
-                    this.minimumSize.setSize(minimumSize);
-                } else {
-                    this.minimumSize = null;
-                }
-            }
-        } finally {
-            toolkit.unlockAWT();
-        }
-        firePropertyChange("minimumSize", oldMinimumSize, this.minimumSize); //$NON-NLS-1$
-        toolkit.lockAWT();
-        try {
-            // ???AWT: invalidateRealParent();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the preferred size of the Component.
-     * 
-     * @param preferredSize
-     *            the new preferred size of the Component.
-     */
-    public void setPreferredSize(Dimension preferredSize) {
-        Dimension oldPreferredSize;
-        toolkit.lockAWT();
-        try {
-            oldPreferredSize = this.preferredSize;
-            if (oldPreferredSize != null) {
-                oldPreferredSize = oldPreferredSize.getSize();
-            }
-            if (this.preferredSize == null) {
-                if (preferredSize != null) {
-                    this.preferredSize = new Dimension(preferredSize);
-                }
-            } else {
-                if (preferredSize != null) {
-                    this.preferredSize.setSize(preferredSize);
-                } else {
-                    this.preferredSize = null;
-                }
-            }
-        } finally {
-            toolkit.unlockAWT();
-        }
-        firePropertyChange("preferredSize", oldPreferredSize, this.preferredSize); //$NON-NLS-1$
-        toolkit.lockAWT();
-        try {
-            // ???AWT: invalidateRealParent();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    // ???AWT
-    /*
-     * RedrawManager getRedrawManager() { if (parent == null) { return null; }
-     * return parent.getRedrawManager(); }
-     */
-
-    /**
-     * Checks if is focusability explicitly set.
-     * 
-     * @return true if component has a focusable peer.
-     */
-    // ???AWT
-    /*
-     * boolean isPeerFocusable() { // The recommendations for Windows and Unix
-     * are that // Canvases, Labels, Panels, Scrollbars, ScrollPanes, Windows,
-     * // and lightweight Components have non-focusable peers, // and all other
-     * Components have focusable peers. if (this instanceof Canvas || this
-     * instanceof Label || this instanceof Panel || this instanceof Scrollbar ||
-     * this instanceof ScrollPane || this instanceof Window || isLightweight())
-     * { return false; } return true; }
-     */
-
-    /**
-     * @return true if focusability was explicitly set via a call to
-     *         setFocusable() or via overriding isFocusable() or
-     *         isFocusTraversable().
-     */
-    boolean isFocusabilityExplicitlySet() {
-        return calledSetFocusable || overridenIsFocusable;
-    }
-
-    /**
-     * Paints the component and all of its subcomponents.
-     * 
-     * @param g
-     *            the Graphics to be used for painting.
-     */
-    public void paintAll(Graphics g) {
-        toolkit.lockAWT();
-        try {
-            paint(g);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Updates this Component.
-     * 
-     * @param g
-     *            the Graphics to be used for updating.
-     */
-    public void update(Graphics g) {
-        toolkit.lockAWT();
-        try {
-            if (!isLightweight() && !isPrepainter()) {
-                g.setColor(getBackground());
-                g.fillRect(0, 0, w, h);
-                g.setColor(getForeground());
-            }
-            paint(g);
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Paints this component.
-     * 
-     * @param g
-     *            the Graphics to be used for painting.
-     */
-    public void paint(Graphics g) {
-        toolkit.lockAWT();
-        try {
-            // Just to nothing
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Prepares the component to be painted.
-     * 
-     * @param g
-     *            the Graphics to be used for painting.
-     */
-    void prepaint(Graphics g) {
-        // Just to nothing. For overriding.
-    }
-
-    /**
-     * Checks if is prepainter.
-     * 
-     * @return true, if is prepainter.
-     */
-    boolean isPrepainter() {
-        return false;
-    }
-
-    /**
-     * Prepare4 hierarchy change.
-     */
-    void prepare4HierarchyChange() {
-        if (hierarchyChangingCounter++ == 0) {
-            wasShowing = isShowing();
-            wasDisplayable = isDisplayable();
-            prepareChildren4HierarchyChange();
-        }
-    }
-
-    /**
-     * Prepare children4 hierarchy change.
-     */
-    void prepareChildren4HierarchyChange() {
-        // To be inherited by Container
-    }
-
-    // ???AWT
-    /*
-     * void finishHierarchyChange(Component changed, Container changedParent,
-     * int ancestorFlags) { if (--hierarchyChangingCounter == 0) { int
-     * changeFlags = ancestorFlags; if (wasShowing != isShowing()) { changeFlags
-     * |= HierarchyEvent.SHOWING_CHANGED; } if (wasDisplayable !=
-     * isDisplayable()) { changeFlags |= HierarchyEvent.DISPLAYABILITY_CHANGED;
-     * } if (changeFlags > 0) { postEvent(new HierarchyEvent(this,
-     * HierarchyEvent.HIERARCHY_CHANGED, changed, changedParent, changeFlags));
-     * } finishChildrenHierarchyChange(changed, changedParent, ancestorFlags); }
-     * } void finishChildrenHierarchyChange(Component changed, Container
-     * changedParent, int ancestorFlags) { // To be inherited by Container }
-     * void postHierarchyBoundsEvents(Component changed, int id) { postEvent(new
-     * HierarchyEvent(this, id, changed, null, 0)); }
-     */
-
-    /**
-     * Spread hierarchy bounds events.
-     * 
-     * @param changed
-     *            the changed.
-     * @param id
-     *            the id.
-     */
-    void spreadHierarchyBoundsEvents(Component changed, int id) {
-        // To be inherited by Container
-    }
-
-    /**
-     * Dispatches an event to this component.
-     * 
-     * @param e
-     *            the Event.
-     */
-    public final void dispatchEvent(AWTEvent e) {
-        // ???AWT
-        /*
-         * if (e.isConsumed()) { return; } if (e instanceof PaintEvent) {
-         * toolkit.dispatchAWTEvent(e); processPaintEvent((PaintEvent) e);
-         * return; } KeyboardFocusManager kfm =
-         * KeyboardFocusManager.getCurrentKeyboardFocusManager(); if
-         * (!e.dispatchedByKFM && kfm.dispatchEvent(e)) { return; } if (e
-         * instanceof KeyEvent) { KeyEvent ke = (KeyEvent) e; // consumes
-         * KeyEvent which represents a focus traversal key if
-         * (getFocusTraversalKeysEnabled()) { kfm.processKeyEvent(this, ke); if
-         * (ke.isConsumed()) { return; } } } if (inputMethodsEnabled &&
-         * dispatchToIM && e.isPosted && dispatchEventToIM(e)) { return; } if
-         * (e.getID() == WindowEvent.WINDOW_ICONIFIED) {
-         * notifyInputMethod(null); } AWTEvent.EventDescriptor descriptor =
-         * toolkit.eventTypeLookup.getEventDescriptor(e);
-         * toolkit.dispatchAWTEvent(e); if (descriptor != null) { if
-         * (isEventEnabled(descriptor.eventMask) ||
-         * (getListeners(descriptor.listenerType).length > 0)) {
-         * processEvent(e); } // input events can be consumed by user listeners:
-         * if (!e.isConsumed() && ((enabledAWTEvents & descriptor.eventMask) !=
-         * 0)) { postprocessEvent(e, descriptor.eventMask); } }
-         * postDeprecatedEvent(e);
-         */
-    }
-
-    /**
-     * Post deprecated event.
-     * 
-     * @param e
-     *            the e.
-     */
-    private void postDeprecatedEvent(AWTEvent e) {
-        if (deprecatedEventHandler) {
-            Event evt = e.getEvent();
-            if (evt != null) {
-                postEvent(evt);
-            }
-        }
-    }
-
-    /**
-     * Postprocess event.
-     * 
-     * @param e
-     *            the e.
-     * @param eventMask
-     *            the event mask.
-     */
-    void postprocessEvent(AWTEvent e, long eventMask) {
-        toolkit.lockAWT();
-        try {
-            // call system listeners under AWT lock
-            if (eventMask == AWTEvent.FOCUS_EVENT_MASK) {
-                preprocessFocusEvent((FocusEvent)e);
-            } else if (eventMask == AWTEvent.KEY_EVENT_MASK) {
-                preprocessKeyEvent((KeyEvent)e);
-            } else if (eventMask == AWTEvent.MOUSE_EVENT_MASK) {
-                preprocessMouseEvent((MouseEvent)e);
-            } else if (eventMask == AWTEvent.MOUSE_MOTION_EVENT_MASK) {
-                preprocessMouseMotionEvent((MouseEvent)e);
-            } else if (eventMask == AWTEvent.COMPONENT_EVENT_MASK) {
-                preprocessComponentEvent((ComponentEvent)e);
-            } else if (eventMask == AWTEvent.MOUSE_WHEEL_EVENT_MASK) {
-                preprocessMouseWheelEvent((MouseWheelEvent)e);
-            } else if (eventMask == AWTEvent.INPUT_METHOD_EVENT_MASK) {
-                preprocessInputMethodEvent((InputMethodEvent)e);
-            }
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Preprocess input method event.
-     * 
-     * @param e
-     *            the e.
-     */
-    private void preprocessInputMethodEvent(InputMethodEvent e) {
-        processInputMethodEventImpl(e, inputMethodListeners.getSystemListeners());
-    }
-
-    /**
-     * Preprocess mouse wheel event.
-     * 
-     * @param e
-     *            the e.
-     */
-    private void preprocessMouseWheelEvent(MouseWheelEvent e) {
-        processMouseWheelEventImpl(e, mouseWheelListeners.getSystemListeners());
-    }
-
-    /**
-     * Process mouse wheel event impl.
-     * 
-     * @param e
-     *            the e.
-     * @param c
-     *            the c.
-     */
-    private void processMouseWheelEventImpl(MouseWheelEvent e, Collection<MouseWheelListener> c) {
-        for (MouseWheelListener listener : c) {
-            switch (e.getID()) {
-                case MouseEvent.MOUSE_WHEEL:
-                    listener.mouseWheelMoved(e);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Preprocess component event.
-     * 
-     * @param e
-     *            the e.
-     */
-    private void preprocessComponentEvent(ComponentEvent e) {
-        processComponentEventImpl(e, componentListeners.getSystemListeners());
-    }
-
-    /**
-     * Preprocess mouse motion event.
-     * 
-     * @param e
-     *            the e.
-     */
-    void preprocessMouseMotionEvent(MouseEvent e) {
-        processMouseMotionEventImpl(e, mouseMotionListeners.getSystemListeners());
-    }
-
-    /**
-     * Preprocess mouse event.
-     * 
-     * @param e
-     *            the e
-     */
-    void preprocessMouseEvent(MouseEvent e) {
-        processMouseEventImpl(e, mouseListeners.getSystemListeners());
-    }
-
-    /**
-     * Preprocess key event.
-     * 
-     * @param e
-     *            the e.
-     */
-    void preprocessKeyEvent(KeyEvent e) {
-        processKeyEventImpl(e, keyListeners.getSystemListeners());
-    }
-
-    /**
-     * Preprocess focus event.
-     * 
-     * @param e
-     *            the e.
-     */
-    void preprocessFocusEvent(FocusEvent e) {
-        processFocusEventImpl(e, focusListeners.getSystemListeners());
-    }
-
-    /**
-     * Processes AWTEvent occurred on this component.
-     * 
-     * @param e
-     *            the AWTEvent.
-     */
-    protected void processEvent(AWTEvent e) {
-        long eventMask = toolkit.eventTypeLookup.getEventMask(e);
-        if (eventMask == AWTEvent.COMPONENT_EVENT_MASK) {
-            processComponentEvent((ComponentEvent)e);
-        } else if (eventMask == AWTEvent.FOCUS_EVENT_MASK) {
-            processFocusEvent((FocusEvent)e);
-        } else if (eventMask == AWTEvent.KEY_EVENT_MASK) {
-            processKeyEvent((KeyEvent)e);
-        } else if (eventMask == AWTEvent.MOUSE_EVENT_MASK) {
-            processMouseEvent((MouseEvent)e);
-        } else if (eventMask == AWTEvent.MOUSE_WHEEL_EVENT_MASK) {
-            processMouseWheelEvent((MouseWheelEvent)e);
-        } else if (eventMask == AWTEvent.MOUSE_MOTION_EVENT_MASK) {
-            processMouseMotionEvent((MouseEvent)e);
-        } else if (eventMask == AWTEvent.HIERARCHY_EVENT_MASK) {
-            processHierarchyEvent((HierarchyEvent)e);
-        } else if (eventMask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) {
-            processHierarchyBoundsEvent((HierarchyEvent)e);
-        } else if (eventMask == AWTEvent.INPUT_METHOD_EVENT_MASK) {
-            processInputMethodEvent((InputMethodEvent)e);
-        }
-    }
-
-    /**
-     * Gets an array of all listener's objects based on the specified listener
-     * type and registered to this Component.
-     * 
-     * @param listenerType
-     *            the listener type.
-     * @return an array of all listener's objects based on the specified
-     *         listener type and registered to this Component.
-     */
-    @SuppressWarnings("unchecked")
-    public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
-        if (ComponentListener.class.isAssignableFrom(listenerType)) {
-            return (T[])getComponentListeners();
-        } else if (FocusListener.class.isAssignableFrom(listenerType)) {
-            return (T[])getFocusListeners();
-        } else if (HierarchyBoundsListener.class.isAssignableFrom(listenerType)) {
-            return (T[])getHierarchyBoundsListeners();
-        } else if (HierarchyListener.class.isAssignableFrom(listenerType)) {
-            return (T[])getHierarchyListeners();
-        } else if (InputMethodListener.class.isAssignableFrom(listenerType)) {
-            return (T[])getInputMethodListeners();
-        } else if (KeyListener.class.isAssignableFrom(listenerType)) {
-            return (T[])getKeyListeners();
-        } else if (MouseWheelListener.class.isAssignableFrom(listenerType)) {
-            return (T[])getMouseWheelListeners();
-        } else if (MouseMotionListener.class.isAssignableFrom(listenerType)) {
-            return (T[])getMouseMotionListeners();
-        } else if (MouseListener.class.isAssignableFrom(listenerType)) {
-            return (T[])getMouseListeners();
-        } else if (PropertyChangeListener.class.isAssignableFrom(listenerType)) {
-            return (T[])getPropertyChangeListeners();
-        }
-        return (T[])Array.newInstance(listenerType, 0);
-    }
-
-    /**
-     * Process paint event.
-     * 
-     * @param event
-     *            the event.
-     */
-    private void processPaintEvent(PaintEvent event) {
-        if (redrawManager == null) {
-            return;
-        }
-        Rectangle clipRect = event.getUpdateRect();
-        if ((clipRect.width <= 0) || (clipRect.height <= 0)) {
-            return;
-        }
-        Graphics g = getGraphics();
-        if (g == null) {
-            return;
-        }
-        initGraphics(g, event);
-        if (!getIgnoreRepaint()) {
-            if (event.getID() == PaintEvent.PAINT) {
-                paint(g);
-            } else {
-                update(g);
-            }
-        }
-        g.dispose();
-    }
-
-    /**
-     * Inits the graphics.
-     * 
-     * @param g
-     *            the g.
-     * @param e
-     *            the e.
-     */
-    void initGraphics(Graphics g, PaintEvent e) {
-        Rectangle clip = e.getUpdateRect();
-        if (clip instanceof ClipRegion) {
-            g.setClip(((ClipRegion)clip).getClip());
-        } else {
-            g.setClip(clip);
-        }
-        if (isPrepainter()) {
-            prepaint(g);
-        } else if (!isLightweight() && (e.getID() == PaintEvent.PAINT)) {
-            g.setColor(getBackground());
-            g.fillRect(0, 0, w, h);
-        }
-        g.setFont(getFont());
-        g.setColor(getForeground());
-    }
-
-    /**
-     * Enables the events with the specified event mask to be delivered to this
-     * component.
-     * 
-     * @param eventsToEnable
-     *            the events mask which specifies the types of events to enable.
-     */
-    protected final void enableEvents(long eventsToEnable) {
-        toolkit.lockAWT();
-        try {
-            enabledEvents |= eventsToEnable;
-            deprecatedEventHandler = false;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Enable awt events.
-     * 
-     * @param eventsToEnable
-     *            the events to enable.
-     */
-    private void enableAWTEvents(long eventsToEnable) {
-        enabledAWTEvents |= eventsToEnable;
-    }
-
-    /**
-     * Disables the events with types specified by the specified event mask from
-     * being delivered to this component.
-     * 
-     * @param eventsToDisable
-     *            the event mask specifying the event types.
-     */
-    protected final void disableEvents(long eventsToDisable) {
-        toolkit.lockAWT();
-        try {
-            enabledEvents &= ~eventsToDisable;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /*
-     * For use in MouseDispatcher only. Really it checks not only mouse events.
-     */
-    /**
-     * Checks if is mouse event enabled.
-     * 
-     * @param eventMask
-     *            the event mask.
-     * @return true, if is mouse event enabled.
-     */
-    boolean isMouseEventEnabled(long eventMask) {
-        return (isEventEnabled(eventMask) || (enabledAWTEvents & eventMask) != 0);
-    }
-
-    /**
-     * Checks if is event enabled.
-     * 
-     * @param eventMask
-     *            the event mask.
-     * @return true, if is event enabled.
-     */
-    boolean isEventEnabled(long eventMask) {
-        return ((enabledEvents & eventMask) != 0);
-    }
-
-    /**
-     * Enables or disables input method support for this component.
-     * 
-     * @param enable
-     *            true to enable input method support, false to disable it.
-     */
-    public void enableInputMethods(boolean enable) {
-        toolkit.lockAWT();
-        try {
-            if (!enable) {
-                removeNotifyInputContext();
-            }
-            inputMethodsEnabled = enable;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets an array of all component's listeners registered for this component.
-     * 
-     * @return an array of all component's listeners registered for this
-     *         component.
-     */
-    public ComponentListener[] getComponentListeners() {
-        return componentListeners.getUserListeners(new ComponentListener[0]);
-    }
-
-    /**
-     * Adds the specified component listener to the Component for receiving
-     * component's event.
-     * 
-     * @param l
-     *            the ComponentListener.
-     */
-    public void addComponentListener(ComponentListener l) {
-        componentListeners.addUserListener(l);
-    }
-
-    /**
-     * Removes the component listener registered for this Component.
-     * 
-     * @param l
-     *            the ComponentListener.
-     */
-    public void removeComponentListener(ComponentListener l) {
-        componentListeners.removeUserListener(l);
-    }
-
-    /**
-     * Processes a component event that has occurred on this component by
-     * dispatching them to any registered ComponentListener objects.
-     * 
-     * @param e
-     *            the ComponentEvent.
-     */
-    protected void processComponentEvent(ComponentEvent e) {
-        processComponentEventImpl(e, componentListeners.getUserListeners());
-    }
-
-    /**
-     * Process component event impl.
-     * 
-     * @param e
-     *            the e.
-     * @param c
-     *            the c.
-     */
-    private void processComponentEventImpl(ComponentEvent e, Collection<ComponentListener> c) {
-        for (ComponentListener listener : c) {
-            switch (e.getID()) {
-                case ComponentEvent.COMPONENT_HIDDEN:
-                    listener.componentHidden(e);
-                    break;
-                case ComponentEvent.COMPONENT_MOVED:
-                    listener.componentMoved(e);
-                    break;
-                case ComponentEvent.COMPONENT_RESIZED:
-                    listener.componentResized(e);
-                    break;
-                case ComponentEvent.COMPONENT_SHOWN:
-                    listener.componentShown(e);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Gets an array of focus listeners registered for this Component.
-     * 
-     * @return the array of focus listeners registered for this Component.
-     */
-    public FocusListener[] getFocusListeners() {
-        return focusListeners.getUserListeners(new FocusListener[0]);
-    }
-
-    /**
-     * Adds the specified focus listener to the Component for receiving focus
-     * events.
-     * 
-     * @param l
-     *            the FocusListener.
-     */
-    public void addFocusListener(FocusListener l) {
-        focusListeners.addUserListener(l);
-    }
-
-    /**
-     * Adds the awt focus listener.
-     * 
-     * @param l
-     *            the l.
-     */
-    void addAWTFocusListener(FocusListener l) {
-        enableAWTEvents(AWTEvent.FOCUS_EVENT_MASK);
-        focusListeners.addSystemListener(l);
-    }
-
-    /**
-     * Removes the focus listener registered for this Component.
-     * 
-     * @param l
-     *            the FocusListener.
-     */
-    public void removeFocusListener(FocusListener l) {
-        focusListeners.removeUserListener(l);
-    }
-
-    /**
-     * Processes a FocusEvent that has occurred on this component by dispatching
-     * it to the registered listeners.
-     * 
-     * @param e
-     *            the FocusEvent.
-     */
-    protected void processFocusEvent(FocusEvent e) {
-        processFocusEventImpl(e, focusListeners.getUserListeners());
-    }
-
-    /**
-     * Process focus event impl.
-     * 
-     * @param e
-     *            the e.
-     * @param c
-     *            the c.
-     */
-    private void processFocusEventImpl(FocusEvent e, Collection<FocusListener> c) {
-        for (FocusListener listener : c) {
-            switch (e.getID()) {
-                case FocusEvent.FOCUS_GAINED:
-                    listener.focusGained(e);
-                    break;
-                case FocusEvent.FOCUS_LOST:
-                    listener.focusLost(e);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Gets an array of registered HierarchyListeners for this Component.
-     * 
-     * @return an array of registered HierarchyListeners for this Component.
-     */
-    public HierarchyListener[] getHierarchyListeners() {
-        return hierarchyListeners.getUserListeners(new HierarchyListener[0]);
-    }
-
-    /**
-     * Adds the specified hierarchy listener.
-     * 
-     * @param l
-     *            the HierarchyListener.
-     */
-    public void addHierarchyListener(HierarchyListener l) {
-        hierarchyListeners.addUserListener(l);
-    }
-
-    /**
-     * Removes the hierarchy listener registered for this component.
-     * 
-     * @param l
-     *            the HierarchyListener.
-     */
-    public void removeHierarchyListener(HierarchyListener l) {
-        hierarchyListeners.removeUserListener(l);
-    }
-
-    /**
-     * Processes a hierarchy event that has occurred on this component by
-     * dispatching it to the registered listeners.
-     * 
-     * @param e
-     *            the HierarchyEvent.
-     */
-    protected void processHierarchyEvent(HierarchyEvent e) {
-        for (HierarchyListener listener : hierarchyListeners.getUserListeners()) {
-            switch (e.getID()) {
-                case HierarchyEvent.HIERARCHY_CHANGED:
-                    listener.hierarchyChanged(e);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Gets an array of HierarchyBoundsListener objects registered to this
-     * Component.
-     * 
-     * @return an array of HierarchyBoundsListener objects.
-     */
-    public HierarchyBoundsListener[] getHierarchyBoundsListeners() {
-        return hierarchyBoundsListeners.getUserListeners(new HierarchyBoundsListener[0]);
-    }
-
-    /**
-     * Adds the specified hierarchy bounds listener.
-     * 
-     * @param l
-     *            the HierarchyBoundsListener.
-     */
-    public void addHierarchyBoundsListener(HierarchyBoundsListener l) {
-        hierarchyBoundsListeners.addUserListener(l);
-    }
-
-    /**
-     * Removes the hierarchy bounds listener registered for this Component.
-     * 
-     * @param l
-     *            the HierarchyBoundsListener.
-     */
-    public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {
-        hierarchyBoundsListeners.removeUserListener(l);
-    }
-
-    /**
-     * Processes a hierarchy bounds event that has occurred on this component by
-     * dispatching it to the registered listeners.
-     * 
-     * @param e
-     *            the HierarchyBoundsEvent.
-     */
-    protected void processHierarchyBoundsEvent(HierarchyEvent e) {
-        for (HierarchyBoundsListener listener : hierarchyBoundsListeners.getUserListeners()) {
-            switch (e.getID()) {
-                case HierarchyEvent.ANCESTOR_MOVED:
-                    listener.ancestorMoved(e);
-                    break;
-                case HierarchyEvent.ANCESTOR_RESIZED:
-                    listener.ancestorResized(e);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Gets an array of the key listeners registered to the Component.
-     * 
-     * @return an array of the key listeners registered to the Component.
-     */
-    public KeyListener[] getKeyListeners() {
-        return keyListeners.getUserListeners(new KeyListener[0]);
-    }
-
-    /**
-     * Adds the specified key listener.
-     * 
-     * @param l
-     *            the KeyListener.
-     */
-    public void addKeyListener(KeyListener l) {
-        keyListeners.addUserListener(l);
-    }
-
-    /**
-     * Adds the awt key listener.
-     * 
-     * @param l
-     *            the l.
-     */
-    void addAWTKeyListener(KeyListener l) {
-        enableAWTEvents(AWTEvent.KEY_EVENT_MASK);
-        keyListeners.addSystemListener(l);
-    }
-
-    /**
-     * Removes the key listener registered for this Component.
-     * 
-     * @param l
-     *            the KeyListener.
-     */
-    public void removeKeyListener(KeyListener l) {
-        keyListeners.removeUserListener(l);
-    }
-
-    /**
-     * Processes a key event that has occurred on this component by dispatching
-     * it to the registered listeners.
-     * 
-     * @param e
-     *            the KeyEvent.
-     */
-    protected void processKeyEvent(KeyEvent e) {
-        processKeyEventImpl(e, keyListeners.getUserListeners());
-    }
-
-    /**
-     * Process key event impl.
-     * 
-     * @param e
-     *            the e.
-     * @param c
-     *            the c.
-     */
-    private void processKeyEventImpl(KeyEvent e, Collection<KeyListener> c) {
-        for (KeyListener listener : c) {
-            switch (e.getID()) {
-                case KeyEvent.KEY_PRESSED:
-                    listener.keyPressed(e);
-                    break;
-                case KeyEvent.KEY_RELEASED:
-                    listener.keyReleased(e);
-                    break;
-                case KeyEvent.KEY_TYPED:
-                    listener.keyTyped(e);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Gets an array of the mouse listeners registered to the Component.
-     * 
-     * @return an array of the mouse listeners registered to the Component.
-     */
-    public MouseListener[] getMouseListeners() {
-        return mouseListeners.getUserListeners(new MouseListener[0]);
-    }
-
-    /**
-     * Adds the specified mouse listener.
-     * 
-     * @param l
-     *            the MouseListener.
-     */
-    public void addMouseListener(MouseListener l) {
-        mouseListeners.addUserListener(l);
-    }
-
-    /**
-     * Adds the awt mouse listener.
-     * 
-     * @param l
-     *            the l.
-     */
-    void addAWTMouseListener(MouseListener l) {
-        enableAWTEvents(AWTEvent.MOUSE_EVENT_MASK);
-        mouseListeners.addSystemListener(l);
-    }
-
-    /**
-     * Adds the awt mouse motion listener.
-     * 
-     * @param l
-     *            the l.
-     */
-    void addAWTMouseMotionListener(MouseMotionListener l) {
-        enableAWTEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
-        mouseMotionListeners.addSystemListener(l);
-    }
-
-    /**
-     * Adds the awt component listener.
-     * 
-     * @param l
-     *            the l.
-     */
-    void addAWTComponentListener(ComponentListener l) {
-        enableAWTEvents(AWTEvent.COMPONENT_EVENT_MASK);
-        componentListeners.addSystemListener(l);
-    }
-
-    /**
-     * Adds the awt input method listener.
-     * 
-     * @param l
-     *            the l.
-     */
-    void addAWTInputMethodListener(InputMethodListener l) {
-        enableAWTEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
-        inputMethodListeners.addSystemListener(l);
-    }
-
-    /**
-     * Adds the awt mouse wheel listener.
-     * 
-     * @param l
-     *            the l.
-     */
-    void addAWTMouseWheelListener(MouseWheelListener l) {
-        enableAWTEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
-        mouseWheelListeners.addSystemListener(l);
-    }
-
-    /**
-     * Removes the mouse listener registered for this Component.
-     * 
-     * @param l
-     *            the MouseListener.
-     */
-    public void removeMouseListener(MouseListener l) {
-        mouseListeners.removeUserListener(l);
-    }
-
-    /**
-     * Processes a mouse event that has occurred on this component by
-     * dispatching it to the registered listeners.
-     * 
-     * @param e
-     *            the MouseEvent.
-     */
-    protected void processMouseEvent(MouseEvent e) {
-        processMouseEventImpl(e, mouseListeners.getUserListeners());
-    }
-
-    /**
-     * Process mouse event impl.
-     * 
-     * @param e
-     *            the e.
-     * @param c
-     *            the c.
-     */
-    private void processMouseEventImpl(MouseEvent e, Collection<MouseListener> c) {
-        for (MouseListener listener : c) {
-            switch (e.getID()) {
-                case MouseEvent.MOUSE_CLICKED:
-                    listener.mouseClicked(e);
-                    break;
-                case MouseEvent.MOUSE_ENTERED:
-                    listener.mouseEntered(e);
-                    break;
-                case MouseEvent.MOUSE_EXITED:
-                    listener.mouseExited(e);
-                    break;
-                case MouseEvent.MOUSE_PRESSED:
-                    listener.mousePressed(e);
-                    break;
-                case MouseEvent.MOUSE_RELEASED:
-                    listener.mouseReleased(e);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Process mouse motion event impl.
-     * 
-     * @param e
-     *            the e.
-     * @param c
-     *            the c.
-     */
-    private void processMouseMotionEventImpl(MouseEvent e, Collection<MouseMotionListener> c) {
-        for (MouseMotionListener listener : c) {
-            switch (e.getID()) {
-                case MouseEvent.MOUSE_DRAGGED:
-                    listener.mouseDragged(e);
-                    break;
-                case MouseEvent.MOUSE_MOVED:
-                    listener.mouseMoved(e);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Gets an array of the mouse motion listeners registered to the Component.
-     * 
-     * @return an array of the MouseMotionListeners registered to the Component.
-     */
-    public MouseMotionListener[] getMouseMotionListeners() {
-        return mouseMotionListeners.getUserListeners(new MouseMotionListener[0]);
-    }
-
-    /**
-     * Adds the specified mouse motion listener.
-     * 
-     * @param l
-     *            the MouseMotionListener.
-     */
-    public void addMouseMotionListener(MouseMotionListener l) {
-        mouseMotionListeners.addUserListener(l);
-    }
-
-    /**
-     * Removes the mouse motion listener registered for this component.
-     * 
-     * @param l
-     *            the MouseMotionListener.
-     */
-    public void removeMouseMotionListener(MouseMotionListener l) {
-        mouseMotionListeners.removeUserListener(l);
-    }
-
-    /**
-     * Processes a mouse motion event that has occurred on this component by
-     * dispatching it to the registered listeners.
-     * 
-     * @param e
-     *            the MouseEvent.
-     */
-    protected void processMouseMotionEvent(MouseEvent e) {
-        processMouseMotionEventImpl(e, mouseMotionListeners.getUserListeners());
-    }
-
-    /**
-     * Gets an array of the mouse wheel listeners registered to the Component.
-     * 
-     * @return an array of the MouseWheelListeners registered to the Component.
-     */
-    public MouseWheelListener[] getMouseWheelListeners() {
-        return mouseWheelListeners.getUserListeners(new MouseWheelListener[0]);
-    }
-
-    /**
-     * Adds the specified mouse wheel listener.
-     * 
-     * @param l
-     *            the MouseWheelListener.
-     */
-    public void addMouseWheelListener(MouseWheelListener l) {
-        mouseWheelListeners.addUserListener(l);
-    }
-
-    /**
-     * Removes the mouse wheel listener registered for this component.
-     * 
-     * @param l
-     *            the MouseWheelListener.
-     */
-    public void removeMouseWheelListener(MouseWheelListener l) {
-        mouseWheelListeners.removeUserListener(l);
-    }
-
-    /**
-     * Processes a mouse wheel event that has occurred on this component by
-     * dispatching it to the registered listeners.
-     * 
-     * @param e
-     *            the MouseWheelEvent.
-     */
-    protected void processMouseWheelEvent(MouseWheelEvent e) {
-        processMouseWheelEventImpl(e, mouseWheelListeners.getUserListeners());
-    }
-
-    /**
-     * Gets an array of the InputMethodListener listeners registered to the
-     * Component.
-     * 
-     * @return an array of the InputMethodListener listeners registered to the
-     *         Component.
-     */
-    public InputMethodListener[] getInputMethodListeners() {
-        return inputMethodListeners.getUserListeners(new InputMethodListener[0]);
-    }
-
-    /**
-     * Adds the specified input method listener.
-     * 
-     * @param l
-     *            the InputMethodListener.
-     */
-    public void addInputMethodListener(InputMethodListener l) {
-        inputMethodListeners.addUserListener(l);
-    }
-
-    /**
-     * Removes the input method listener registered for this component.
-     * 
-     * @param l
-     *            the InputMethodListener.
-     */
-    public void removeInputMethodListener(InputMethodListener l) {
-        inputMethodListeners.removeUserListener(l);
-    }
-
-    /**
-     * Processes an input method event that has occurred on this component by
-     * dispatching it to the registered listeners.
-     * 
-     * @param e
-     *            the InputMethodEvent.
-     */
-    protected void processInputMethodEvent(InputMethodEvent e) {
-        processInputMethodEventImpl(e, inputMethodListeners.getUserListeners());
-    }
-
-    /**
-     * Process input method event impl.
-     * 
-     * @param e
-     *            the e.
-     * @param c
-     *            the c.
-     */
-    private void processInputMethodEventImpl(InputMethodEvent e, Collection<InputMethodListener> c) {
-        for (InputMethodListener listener : c) {
-            switch (e.getID()) {
-                case InputMethodEvent.CARET_POSITION_CHANGED:
-                    listener.caretPositionChanged(e);
-                    break;
-                case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
-                    listener.inputMethodTextChanged(e);
-                    break;
-            }
-        }
-    }
-
-    // ???AWT
-    /*
-     * public Point getMousePosition() throws HeadlessException { Point
-     * absPointerPos = MouseInfo.getPointerInfo().getLocation(); Window
-     * winUnderPtr =
-     * toolkit.dispatcher.mouseDispatcher.findWindowAt(absPointerPos); Point
-     * pointerPos = MouseDispatcher.convertPoint(null, absPointerPos,
-     * winUnderPtr); boolean isUnderPointer = false; if (winUnderPtr == null) {
-     * return null; } isUnderPointer = winUnderPtr.isComponentAt(this,
-     * pointerPos); if (isUnderPointer) { return
-     * MouseDispatcher.convertPoint(null, absPointerPos, this); } return null; }
-     */
-
-    /**
-     * Set native caret at the given position <br>
-     * Note: this method takes AWT lock inside because it walks through the
-     * component hierarchy.
-     * 
-     * @param x
-     *            the x.
-     * @param y
-     *            the y.
-     */
-    void setCaretPos(final int x, final int y) {
-        Runnable r = new Runnable() {
-            public void run() {
-                toolkit.lockAWT();
-                try {
-                    setCaretPosImpl(x, y);
-                } finally {
-                    toolkit.unlockAWT();
-                }
-            }
-        };
-        if (Thread.currentThread() instanceof EventDispatchThread) {
-            r.run();
-        } else {
-            toolkit.getSystemEventQueueImpl().postEvent(new InvocationEvent(this, r));
-        }
-    }
-
-    /**
-     * This method should be called only at event dispatch thread.
-     * 
-     * @param x
-     *            the x.
-     * @param y
-     *            the y.
-     */
-    void setCaretPosImpl(int x, int y) {
-        Component c = this;
-        while ((c != null) && c.behaviour.isLightweight()) {
-            x += c.x;
-            y += c.y;
-            // ???AWT: c = c.getParent();
-        }
-        if (c == null) {
-            return;
-        }
-        // ???AWT
-        /*
-         * if (c instanceof Window) { Insets insets = c.getNativeInsets(); x -=
-         * insets.left; y -= insets.top; }
-         * toolkit.getWindowFactory().setCaretPosition(x, y);
-         */
-    }
-
-    // to be overridden in standard components such as Button and List
-    /**
-     * Gets the default minimum size.
-     * 
-     * @return the default minimum size.
-     */
-    Dimension getDefaultMinimumSize() {
-        return null;
-    }
-
-    // to be overridden in standard components such as Button and List
-    /**
-     * Gets the default preferred size.
-     * 
-     * @return the default preferred size.
-     */
-    Dimension getDefaultPreferredSize() {
-        return null;
-    }
-
-    // to be overridden in standard components such as Button and List
-    /**
-     * Reset default size.
-     */
-    void resetDefaultSize() {
-    }
-
-    // ???AWT
-    /*
-     * ComponentBehavior createBehavior() { return new LWBehavior(this); }
-     */
-
-    /**
-     * Gets the default background.
-     * 
-     * @return the default background.
-     */
-    Color getDefaultBackground() {
-        // ???AWT: return getWindowAncestor().getDefaultBackground();
-        return getBackground();
-    }
-
-    /**
-     * Gets the default foreground.
-     * 
-     * @return the default foreground.
-     */
-    Color getDefaultForeground() {
-        // ???AWT return getWindowAncestor().getDefaultForeground();
-        return getForeground();
-    }
-
-    /**
-     * Called when native resource for this component is created (for
-     * heavyweights only).
-     * 
-     * @param win
-     *            the win.
-     */
-    void nativeWindowCreated(NativeWindow win) {
-        // to be overridden
-    }
-
-    /**
-     * Determine the component's area hidden behind the windows that have higher
-     * Z-order, including windows of other applications.
-     * 
-     * @param image
-     *            the image.
-     * @param destLocation
-     *            the dest location.
-     * @param destSize
-     *            the dest size.
-     * @param source
-     *            the source.
-     * @return the calculated region, or null if it cannot be determined.
-     */
-    // ???AWT
-    /*
-     * MultiRectArea getObscuredRegion(Rectangle part) { if (!visible || parent
-     * == null || !parent.visible) { return null; } Rectangle r = new
-     * Rectangle(0, 0, w, h); if (part != null) { r = r.intersection(part); } if
-     * (r.isEmpty()) { return null; } r.translate(x, y); MultiRectArea ret =
-     * parent.getObscuredRegion(r); if (ret != null) {
-     * parent.addObscuredRegions(ret, this); ret.translate(-x, -y);
-     * ret.intersect(new Rectangle(0, 0, w, h)); } return ret; }
-     */
-
-    // ???AWT
-    /*
-     * private void readObject(ObjectInputStream stream) throws IOException,
-     * ClassNotFoundException { stream.defaultReadObject(); FieldsAccessor
-     * accessor = new FieldsAccessor(Component.class, this);
-     * accessor.set("toolkit", Toolkit.getDefaultToolkit()); //$NON-NLS-1$
-     * accessor.set("behaviour", createBehavior()); //$NON-NLS-1$
-     * accessor.set("componentLock", new Object()); // $NON-LOCK-1$
-     * //$NON-NLS-1$ }
-     */
-
-    final void onDrawImage(Image image, Point destLocation, Dimension destSize, Rectangle source) {
-        ImageParameters imageParams;
-        if (updatedImages == null) {
-            updatedImages = new HashMap<Image, ImageParameters>();
-        }
-        imageParams = updatedImages.get(image);
-        if (imageParams == null) {
-            imageParams = new ImageParameters();
-            updatedImages.put(image, imageParams);
-        }
-        imageParams.addDrawing(destLocation, destSize, source);
-    }
-
-    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
-        toolkit.lockAWT();
-        try {
-            boolean done = false;
-            if ((infoflags & (ALLBITS | FRAMEBITS)) != 0) {
-                done = true;
-            } else if ((infoflags & SOMEBITS) != 0 && incrementalImageUpdate) {
-                done = true;
-            }
-            if (done) {
-                repaint();
-            }
-            return (infoflags & (ABORT | ALLBITS)) == 0;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    // ???AWT
-    /*
-     * private void invalidateRealParent() { Container realParent =
-     * getRealParent(); if ((realParent != null) && realParent.isValid()) {
-     * realParent.invalidate(); } }
-     */
-
-    /**
-     * The Class ImageParameters.
-     */
-    private class ImageParameters {
-
-        /**
-         * The drawing params.
-         */
-        private final LinkedList<DrawingParameters> drawingParams = new LinkedList<DrawingParameters>();
-
-        /**
-         * The size.
-         */
-        Dimension size = new Dimension(Component.this.w, Component.this.h);
-
-        /**
-         * Adds the drawing.
-         * 
-         * @param destLocation
-         *            the dest location.
-         * @param destSize
-         *            the dest size.
-         * @param source
-         *            the source.
-         */
-        void addDrawing(Point destLocation, Dimension destSize, Rectangle source) {
-            drawingParams.add(new DrawingParameters(destLocation, destSize, source));
-        }
-
-        /**
-         * Drawing parameters iterator.
-         * 
-         * @return the iterator< drawing parameters>.
-         */
-        Iterator<DrawingParameters> drawingParametersIterator() {
-            return drawingParams.iterator();
-        }
-
-        /**
-         * The Class DrawingParameters.
-         */
-        class DrawingParameters {
-
-            /**
-             * The dest location.
-             */
-            Point destLocation;
-
-            /**
-             * The dest size.
-             */
-            Dimension destSize;
-
-            /**
-             * The source.
-             */
-            Rectangle source;
-
-            /**
-             * Instantiates a new drawing parameters.
-             * 
-             * @param destLocation
-             *            the dest location.
-             * @param destSize
-             *            the dest size.
-             * @param source
-             *            the source.
-             */
-            DrawingParameters(Point destLocation, Dimension destSize, Rectangle source) {
-                this.destLocation = new Point(destLocation);
-                if (destSize != null) {
-                    this.destSize = new Dimension(destSize);
-                } else {
-                    this.destSize = null;
-                }
-                if (source != null) {
-                    this.source = new Rectangle(source);
-                } else {
-                    this.source = null;
-                }
-            }
-        }
-    }
-
-    /**
-     * TextComponent support.
-     * 
-     * @param e
-     *            the e.
-     * @return true, if dispatch event to im.
-     */
-    // ???AWT
-    /*
-     * private TextKit textKit = null; TextKit getTextKit() { return textKit; }
-     * void setTextKit(TextKit kit) { textKit = kit; }
-     */
-
-    /**
-     * TextField support.
-     */
-    // ???AWT
-    /*
-     * private TextFieldKit textFieldKit = null; TextFieldKit getTextFieldKit()
-     * { return textFieldKit; } void setTextFieldKit(TextFieldKit kit) {
-     * textFieldKit = kit; }
-     */
-
-    /**
-     * Dispatches input & focus events to input method context.
-     * 
-     * @param e
-     *            event to pass to InputContext.dispatchEvent().
-     * @return true if event was consumed by IM, false otherwise.
-     */
-    private boolean dispatchEventToIM(AWTEvent e) {
-        InputContext ic = getInputContext();
-        if (ic == null) {
-            return false;
-        }
-        int id = e.getID();
-        boolean isInputEvent = ((id >= KeyEvent.KEY_FIRST) && (id <= KeyEvent.KEY_LAST))
-                || ((id >= MouseEvent.MOUSE_FIRST) && (id <= MouseEvent.MOUSE_LAST));
-        if (((id >= FocusEvent.FOCUS_FIRST) && (id <= FocusEvent.FOCUS_LAST)) || isInputEvent) {
-            ic.dispatchEvent(e);
-        }
-        return e.isConsumed();
-    }
-}
diff --git a/awt/java/awt/ComponentBehavior.java b/awt/java/awt/ComponentBehavior.java
deleted file mode 100644
index f4e8ffb..0000000
--- a/awt/java/awt/ComponentBehavior.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package java.awt;
-
-import org.apache.harmony.awt.wtk.NativeWindow;
-
-/**
- * The interface of the helper object that encapsulates the difference
- * between lightweight and heavyweight components.
- */
-interface ComponentBehavior {
-
-    void addNotify();
-
-    void setBounds(int x, int y, int w, int h, int bMask);
-
-    void setVisible(boolean b);
-
-    Graphics getGraphics(int translationX, int translationY, int width, int height);
-
-    NativeWindow getNativeWindow();
-
-    boolean isLightweight();
-
-    void onMove(int x, int y);
-
-    boolean isOpaque();
-
-    boolean isDisplayable();
-
-    void setEnabled(boolean value);
-
-    void removeNotify();
-
-    void setZOrder(int newIndex, int oldIndex);
-
-    boolean setFocus(boolean focus, Component opposite);
-}
diff --git a/awt/java/awt/ComponentOrientation.java b/awt/java/awt/ComponentOrientation.java
deleted file mode 100644
index 5acc11a3..0000000
--- a/awt/java/awt/ComponentOrientation.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov, Dmitry A. Durnev
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.io.Serializable;
-import java.util.*;
-
-/**
- * The ComponentOrientation class specifies the language-sensitive orientation
- * of component's elements or text. It is used to reflect the differences in
- * this ordering between different writing systems. The ComponentOrientation
- * class indicates the orientation of the elements/text in the horizontal
- * direction ("left to right" or "right to left") and in the vertical direction
- * ("top to bottom" or "bottom to top").
- * 
- * @since Android 1.0
- */
-public final class ComponentOrientation implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -4113291392143563828L;
-
-    /**
-     * The Constant LEFT_TO_RIGHT indicates that items run left to right.
-     */
-    public static final ComponentOrientation LEFT_TO_RIGHT = new ComponentOrientation(true, true);
-
-    /**
-     * The Constant RIGHT_TO_LEFT indicates that items run right to left.
-     */
-    public static final ComponentOrientation RIGHT_TO_LEFT = new ComponentOrientation(true, false);
-
-    /**
-     * The Constant UNKNOWN indicates that a component's orientation is not set.
-     */
-    public static final ComponentOrientation UNKNOWN = new ComponentOrientation(true, true);
-
-    /**
-     * The Constant rlLangs.
-     */
-    private static final Set<String> rlLangs = new HashSet<String>(); // RIGHT_TO_LEFT
-
-    // languages
-
-    /**
-     * The horizontal.
-     */
-    private final boolean horizontal;
-
-    /**
-     * The left2right.
-     */
-    private final boolean left2right;
-
-    static {
-        rlLangs.add("ar"); //$NON-NLS-1$
-        rlLangs.add("fa"); //$NON-NLS-1$
-        rlLangs.add("iw"); //$NON-NLS-1$
-        rlLangs.add("ur"); //$NON-NLS-1$
-    }
-
-    /**
-     * Gets the orientation for the given ResourceBundle's localization.
-     * 
-     * @param bdl
-     *            the ResourceBundle.
-     * @return the ComponentOrientation.
-     * @deprecated Use getOrientation(java.util.Locale) method.
-     */
-    @Deprecated
-    public static ComponentOrientation getOrientation(ResourceBundle bdl) {
-        Object obj = null;
-        try {
-            obj = bdl.getObject("Orientation"); //$NON-NLS-1$
-        } catch (MissingResourceException mre) {
-            obj = null;
-        }
-        if (obj instanceof ComponentOrientation) {
-            return (ComponentOrientation)obj;
-        }
-        Locale locale = bdl.getLocale();
-        if (locale == null) {
-            locale = Locale.getDefault();
-        }
-        return getOrientation(locale);
-    }
-
-    /**
-     * Gets the orientation for the specified locale.
-     * 
-     * @param locale
-     *            the specified Locale.
-     * @return the ComponentOrientation.
-     */
-    public static ComponentOrientation getOrientation(Locale locale) {
-        String lang = locale.getLanguage();
-        return rlLangs.contains(lang) ? RIGHT_TO_LEFT : LEFT_TO_RIGHT;
-    }
-
-    /**
-     * Instantiates a new component orientation.
-     * 
-     * @param hor
-     *            whether the items should be arranged horizontally.
-     * @param l2r
-     *            whether this orientation specifies a left-to-right flow.
-     */
-    private ComponentOrientation(boolean hor, boolean l2r) {
-        horizontal = hor;
-        left2right = l2r;
-    }
-
-    /**
-     * Returns true if the text of the of writing systems arranged horizontally.
-     * 
-     * @return true, if the text is written horizontally, false for a vertical
-     *         arrangement.
-     */
-    public boolean isHorizontal() {
-        return horizontal;
-    }
-
-    /**
-     * Returns true if the text is arranged from left to right.
-     * 
-     * @return true, for writing systems written from left to right; false for
-     *         right-to-left.
-     */
-    public boolean isLeftToRight() {
-        return left2right;
-    }
-
-}
diff --git a/awt/java/awt/Composite.java b/awt/java/awt/Composite.java
deleted file mode 100644
index d1730fe..0000000
--- a/awt/java/awt/Composite.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.image.ColorModel;
-
-/**
- * The Composite interface allows the methods to compose a draw primitive on the
- * graphics area. The classes implementing this interface provides the rules and
- * a method to create the context for a particular operation.
- * 
- * @since Android 1.0
- */
-public interface Composite {
-
-    /**
-     * Creates a CompositeContext which defines the encapsulated and optimized
-     * environment for a compositing operation. Several contexts can exist for a
-     * single Composite object.
-     * 
-     * @param srcColorModel
-     *            the source's ColorModel.
-     * @param dstColorModel
-     *            the destination's ColorModel.
-     * @param hints
-     *            the RenderingHints.
-     * @return the CompositeContext object.
-     */
-    public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel,
-            RenderingHints hints);
-
-}
diff --git a/awt/java/awt/CompositeContext.java b/awt/java/awt/CompositeContext.java
deleted file mode 100644
index 795640d..0000000
--- a/awt/java/awt/CompositeContext.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-
-/**
- * The CompositeContext interface specifies the encapsulated and optimized
- * environment for a compositing operation.
- * 
- * @since Android 1.0
- */
-public interface CompositeContext {
-
-    /**
-     * Composes the two source Raster objects and places the result in the
-     * destination WritableRaster.
-     * 
-     * @param src
-     *            the source Raster.
-     * @param dstIn
-     *            the destination Raster.
-     * @param dstOut
-     *            the WritableRaster object where the result of composing
-     *            operation is stored.
-     */
-    public void compose(Raster src, Raster dstIn, WritableRaster dstOut);
-
-    /**
-     * Releases resources allocated for a context.
-     */
-    public void dispose();
-
-}
diff --git a/awt/java/awt/Cursor.java b/awt/java/awt/Cursor.java
deleted file mode 100644
index 0a0cc84..0000000
--- a/awt/java/awt/Cursor.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.awt.wtk.NativeCursor;
-
-/**
- * The Cursor class represents the bitmap of the mouse cursor.
- * 
- * @since Android 1.0
- */
-public class Cursor implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 8028237497568985504L;
-
-    /**
-     * The Constant DEFAULT_CURSOR indicates the default cursor type.
-     */
-    public static final int DEFAULT_CURSOR = 0;
-
-    /**
-     * The Constant CROSSHAIR_CURSOR cursor type.
-     */
-    public static final int CROSSHAIR_CURSOR = 1;
-
-    /**
-     * The Constant TEXT_CURSOR cursor type.
-     */
-    public static final int TEXT_CURSOR = 2;
-
-    /**
-     * The Constant WAIT_CURSOR cursor type.
-     */
-    public static final int WAIT_CURSOR = 3;
-
-    /**
-     * The Constant SW_RESIZE_CURSOR cursor type.
-     */
-    public static final int SW_RESIZE_CURSOR = 4;
-
-    /**
-     * The Constant SE_RESIZE_CURSOR cursor type.
-     */
-    public static final int SE_RESIZE_CURSOR = 5;
-
-    /**
-     * The Constant NW_RESIZE_CURSOR cursor type.
-     */
-    public static final int NW_RESIZE_CURSOR = 6;
-
-    /**
-     * The Constant NE_RESIZE_CURSOR cursor type.
-     */
-    public static final int NE_RESIZE_CURSOR = 7;
-
-    /**
-     * The Constant N_RESIZE_CURSOR cursor type.
-     */
-    public static final int N_RESIZE_CURSOR = 8;
-
-    /**
-     * The Constant S_RESIZE_CURSOR cursor type.
-     */
-    public static final int S_RESIZE_CURSOR = 9;
-
-    /**
-     * The Constant W_RESIZE_CURSOR cursor type.
-     */
-    public static final int W_RESIZE_CURSOR = 10;
-
-    /**
-     * The Constant E_RESIZE_CURSOR cursor type.
-     */
-    public static final int E_RESIZE_CURSOR = 11;
-
-    /**
-     * The Constant HAND_CURSOR cursor type.
-     */
-    public static final int HAND_CURSOR = 12;
-
-    /**
-     * The Constant MOVE_CURSOR cursor type.
-     */
-    public static final int MOVE_CURSOR = 13;
-
-    /**
-     * A mapping from names to system custom cursors.
-     */
-    static Map<String, Cursor> systemCustomCursors;
-
-    /**
-     * The cursor props.
-     */
-    static Properties cursorProps;
-
-    /**
-     * The Constant predefinedNames.
-     */
-    static final String[] predefinedNames = {
-            "Default", "Crosshair", "Text", "Wait", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-            "Southwest Resize", "Southeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
-            "Northwest Resize", "Northeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
-            "North Resize", "South Resize", "West Resize", "East Resize", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-            "Hand", "Move" //$NON-NLS-1$ //$NON-NLS-2$
-
-    };
-
-    /**
-     * The predefined set of cursors.
-     */
-    protected static Cursor[] predefined = {
-            new Cursor(DEFAULT_CURSOR), null, null, null, null, null, null, null, null, null, null,
-            null, null, null
-    };
-
-    /**
-     * The Constant CUSTOM_CURSOR is associated with all custom cursor types.
-     * (Those which are not predefined)
-     */
-    public static final int CUSTOM_CURSOR = -1;
-
-    /**
-     * The name of the cursor.
-     */
-    protected String name;
-
-    /**
-     * The type of the cursor, chosen from the list of cursor type constants.
-     */
-    private final int type;
-
-    /**
-     * The native cursor.
-     */
-    private transient NativeCursor nativeCursor;
-
-    /**
-     * The exact point on the cursor image that indicates which point the cursor
-     * is selecting (pointing to). The coordinates are given with respect the
-     * origin of the Image (its upper left corner).
-     */
-    private Point hotSpot;
-
-    /**
-     * The image to draw on the screen representing the cursor.
-     */
-    private Image image;
-
-    /**
-     * Instantiates a new cursor with the specified name.
-     * 
-     * @param name
-     *            the name of cursor.
-     */
-    protected Cursor(String name) {
-        this(name, null, new Point());
-    }
-
-    /**
-     * Instantiates a new cursor of the specified type.
-     * 
-     * @param type
-     *            the type of cursor.
-     */
-    public Cursor(int type) {
-        checkType(type);
-        this.type = type;
-        if ((type >= 0) && (type < predefinedNames.length)) {
-            name = predefinedNames[type] + " Cursor"; //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Instantiates a new cursor.
-     * 
-     * @param name
-     *            the name.
-     * @param img
-     *            the img.
-     * @param hotSpot
-     *            the hot spot.
-     */
-    Cursor(String name, Image img, Point hotSpot) {
-        this.name = name;
-        type = CUSTOM_CURSOR;
-        this.hotSpot = hotSpot;
-        image = img;
-    }
-
-    /**
-     * Finalize method overrides the finalize method from Object class.
-     * 
-     * @throws Throwable
-     *             if the native cursor is not null and throws a Throwable when
-     *             destroyed.
-     */
-    @Override
-    protected void finalize() throws Throwable {
-        if (nativeCursor != null) {
-            nativeCursor.destroyCursor();
-        }
-    }
-
-    /**
-     * Gets the name of the cursor.
-     * 
-     * @return the name of the cursor.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Returns the String representation of the cursor.
-     * 
-     * @return the String representation of the cursor.
-     */
-    @Override
-    public String toString() {
-        return getClass().getName() + "[" + name + "]"; //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    /**
-     * Gets the cursor type.
-     * 
-     * @return the cursor type.
-     */
-    public int getType() {
-        return type;
-    }
-
-    /**
-     * Gets the predefined cursor with the specified type.
-     * 
-     * @param type
-     *            the type of cursor.
-     * @return the predefined cursor with the specified type.
-     */
-    public static Cursor getPredefinedCursor(int type) {
-        checkType(type);
-        Cursor cursor = predefined[type];
-        if (cursor == null) {
-            cursor = new Cursor(type);
-            predefined[type] = cursor;
-        }
-        return cursor;
-    }
-
-    /**
-     * Gets the default cursor.
-     * 
-     * @return the default cursor.
-     */
-    public static Cursor getDefaultCursor() {
-        return getPredefinedCursor(DEFAULT_CURSOR);
-    }
-
-    /**
-     * Gets the specified system custom cursor.
-     * 
-     * @param name
-     *            the name of the desired system cursor.
-     * @return the specific system cursor with the specified name.
-     * @throws AWTException
-     *             if the desired cursor has malformed data such as an
-     *             incorrectly defined hot spot.
-     * @throws HeadlessException
-     *             if the isHeadless method of the GraphicsEnvironment returns
-     *             true.
-     */
-    public static Cursor getSystemCustomCursor(String name) throws AWTException, HeadlessException {
-        Toolkit.checkHeadless();
-        return getSystemCustomCursorFromMap(name);
-    }
-
-    /**
-     * Gets the specified system custom cursor from the map of system custom
-     * cursors.
-     * 
-     * @param name
-     *            the name of the desired cursor.
-     * @return the desired system custom cursor from the map of system custom
-     *         cursors.
-     * @throws AWTException
-     *             the AWT exception.
-     */
-    private static Cursor getSystemCustomCursorFromMap(String name) throws AWTException {
-        loadCursorProps();
-        if (systemCustomCursors == null) {
-            systemCustomCursors = new HashMap<String, Cursor>();
-        }
-        Cursor cursor = systemCustomCursors.get(name);
-        if (cursor != null) {
-            return cursor;
-        }
-        // awt.141=failed to parse hotspot property for cursor:
-        String exMsg = Messages.getString("awt.141") + name; //$NON-NLS-1$
-        String nm = "Cursor." + name; //$NON-NLS-1$
-        String nameStr = cursorProps.getProperty(nm + ".Name"); //$NON-NLS-1$
-        String hotSpotStr = cursorProps.getProperty(nm + ".HotSpot"); //$NON-NLS-1$
-        String fileStr = cursorProps.getProperty(nm + ".File"); //$NON-NLS-1$
-        int idx = hotSpotStr.indexOf(',');
-        if (idx < 0) {
-            throw new AWTException(exMsg);
-        }
-        int x, y;
-        try {
-            x = new Integer(hotSpotStr.substring(0, idx)).intValue();
-            y = new Integer(hotSpotStr.substring(idx + 1, hotSpotStr.length())).intValue();
-        } catch (NumberFormatException nfe) {
-            throw new AWTException(exMsg);
-        }
-        Image img = Toolkit.getDefaultToolkit().createImage(fileStr);
-        cursor = new Cursor(nameStr, img, new Point(x, y));
-        systemCustomCursors.put(name, cursor);
-
-        return cursor;
-    }
-
-    /**
-     * Load cursor props.
-     * 
-     * @throws AWTException
-     *             the AWT exception.
-     */
-    private static void loadCursorProps() throws AWTException {
-        if (cursorProps != null) {
-            return;
-        }
-        String sep = File.separator;
-        String cursorsDir = "lib" + sep + "images" + sep + "cursors"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        String cursorsAbsDir = System.getProperty("java.home") + sep + //$NON-NLS-1$
-                cursorsDir;
-        String cursorPropsFileName = "cursors.properties"; //$NON-NLS-1$
-        String cursorPropsFullFileName = (cursorsAbsDir + sep + cursorPropsFileName);
-        cursorProps = new Properties();
-        try {
-            cursorProps.load(new FileInputStream(new File(cursorPropsFullFileName)));
-        } catch (FileNotFoundException e) {
-            // awt.142=Exception: class {0} {1} occurred while loading: {2}
-            throw new AWTException(Messages.getString("awt.142",//$NON-NLS-1$
-                    new Object[] {
-                            e.getClass(), e.getMessage(), cursorPropsFullFileName
-                    }));
-        } catch (IOException e) {
-            throw new AWTException(e.getMessage());
-        }
-
-    }
-
-    /**
-     * Check type.
-     * 
-     * @param type
-     *            the type.
-     */
-    static void checkType(int type) {
-        // can't use predefined array here because it may not have been
-        // initialized yet
-        if ((type < 0) || (type >= predefinedNames.length)) {
-            // awt.143=illegal cursor type
-            throw new IllegalArgumentException(Messages.getString("awt.143")); //$NON-NLS-1$
-        }
-    }
-
-    // "lazily" create native cursors:
-    /**
-     * Gets the native cursor.
-     * 
-     * @return the native cursor.
-     */
-    NativeCursor getNativeCursor() {
-        if (nativeCursor != null) {
-            return nativeCursor;
-        }
-        Toolkit toolkit = Toolkit.getDefaultToolkit();
-        if (type != CUSTOM_CURSOR) {
-            nativeCursor = toolkit.createNativeCursor(type);
-        } else {
-            nativeCursor = toolkit.createCustomNativeCursor(image, hotSpot, name);
-        }
-        return nativeCursor;
-    }
-
-    /**
-     * Sets the native cursor.
-     * 
-     * @param nativeCursor
-     *            the new native cursor.
-     */
-    void setNativeCursor(NativeCursor nativeCursor) {
-        this.nativeCursor = nativeCursor;
-    }
-}
diff --git a/awt/java/awt/Dimension.java b/awt/java/awt/Dimension.java
deleted file mode 100644
index 6777962..0000000
--- a/awt/java/awt/Dimension.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.geom.Dimension2D;
-import java.io.Serializable;
-
-import org.apache.harmony.misc.HashCode;
-
-/**
- * The Dimension represents the size (width and height) of a component. The
- * width and height values can be negative, but in that case the behavior of
- * some methods is unexpected.
- * 
- * @since Android 1.0
- */
-public class Dimension extends Dimension2D implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 4723952579491349524L;
-
-    /**
-     * The width dimension.
-     */
-    public int width;
-
-    /**
-     * The height dimension.
-     */
-    public int height;
-
-    /**
-     * Instantiates a new Dimension with the same data as the specified
-     * Dimension.
-     * 
-     * @param d
-     *            the Dimension to copy the data from when creating the new
-     *            Dimension object.
-     */
-    public Dimension(Dimension d) {
-        this(d.width, d.height);
-    }
-
-    /**
-     * Instantiates a new Dimension with zero width and height.
-     */
-    public Dimension() {
-        this(0, 0);
-    }
-
-    /**
-     * Instantiates a new Dimension with the specified width and height.
-     * 
-     * @param width
-     *            the width of the new Dimension.
-     * @param height
-     *            the height of the new Dimension.
-     */
-    public Dimension(int width, int height) {
-        setSize(width, height);
-    }
-
-    /**
-     * Returns the hash code of the Dimension.
-     * 
-     * @return the hash code of the Dimension.
-     */
-    @Override
-    public int hashCode() {
-        HashCode hash = new HashCode();
-        hash.append(width);
-        hash.append(height);
-        return hash.hashCode();
-    }
-
-    /**
-     * Compares this Dimension object with the specified object.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if the specified Object is a Dimension with the same width
-     *         and height data as this Dimension.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (obj instanceof Dimension) {
-            Dimension d = (Dimension)obj;
-            return (d.width == width && d.height == height);
-        }
-        return false;
-    }
-
-    /**
-     * Returns the String associated to this Dimension object.
-     * 
-     * @return the String associated to this Dimension object.
-     */
-    @Override
-    public String toString() {
-        // The output format based on 1.5 release behaviour. It could be
-        // obtained in the following way
-        // System.out.println(new Dimension().toString())
-        return getClass().getName() + "[width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    }
-
-    /**
-     * Sets the size of this Dimension object with the specified width and
-     * height.
-     * 
-     * @param width
-     *            the width of the Dimension.
-     * @param height
-     *            the height of the Dimension.
-     */
-    public void setSize(int width, int height) {
-        this.width = width;
-        this.height = height;
-    }
-
-    /**
-     * Sets the size of this Dimension object by copying the data from the
-     * specified Dimension object.
-     * 
-     * @param d
-     *            the Dimension that gives the new size values.
-     */
-    public void setSize(Dimension d) {
-        setSize(d.width, d.height);
-    }
-
-    /**
-     * Sets the size of this Dimension object with the specified double width
-     * and height.
-     * 
-     * @param width
-     *            the width of the Dimension.
-     * @param height
-     *            the height of the Dimension.
-     * @see java.awt.geom.Dimension2D#setSize(double, double)
-     */
-    @Override
-    public void setSize(double width, double height) {
-        setSize((int)Math.ceil(width), (int)Math.ceil(height));
-    }
-
-    /**
-     * Gets the size of the Dimension.
-     * 
-     * @return the size of the Dimension.
-     */
-    public Dimension getSize() {
-        return new Dimension(width, height);
-    }
-
-    /**
-     * Gets the height of the Dimension.
-     * 
-     * @return the height of the Dimension.
-     * @see java.awt.geom.Dimension2D#getHeight()
-     */
-    @Override
-    public double getHeight() {
-        return height;
-    }
-
-    /**
-     * Gets the width of the Dimension.
-     * 
-     * @return the width of the Dimension.
-     * @see java.awt.geom.Dimension2D#getWidth()
-     */
-    @Override
-    public double getWidth() {
-        return width;
-    }
-
-}
diff --git a/awt/java/awt/Dispatcher.java b/awt/java/awt/Dispatcher.java
deleted file mode 100644
index d457af4..0000000
--- a/awt/java/awt/Dispatcher.java
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov, Dmitry A. Durnev
- * @version $Revision$
- */
-package java.awt;
-
-import java.awt.event.ComponentEvent;
-import java.awt.event.FocusEvent;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.PaintEvent;
-import java.awt.event.WindowEvent;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.awt.wtk.NativeEvent;
-import org.apache.harmony.awt.wtk.NativeWindow;
-
-
-/**
- * Helper package-private class for managing lightweight components &
- * dispatching events from heavyweight source
- */
-class Dispatcher {
-
-    //???AWT: final PopupDispatcher popupDispatcher = new PopupDispatcher();
-
-    //???AWT: final FocusDispatcher focusDispatcher;
-
-    final MouseGrabManager mouseGrabManager = new MouseGrabManager();
-
-    final MouseDispatcher mouseDispatcher;
-
-    private final ComponentDispatcher componentDispatcher = new ComponentDispatcher();
-
-    private final KeyDispatcher keyDispatcher = new KeyDispatcher();
-
-    private final Toolkit toolkit;
-
-    int clickInterval = 250;
-
-    /**
-     * @param toolkit - AWT toolkit
-     */
-    Dispatcher(Toolkit toolkit) {
-        this.toolkit = toolkit;
-
-        //???AWT: focusDispatcher = new FocusDispatcher(toolkit);
-        mouseDispatcher = new MouseDispatcher(mouseGrabManager, toolkit);
-    }
-
-    /**
-     * Dispatch native event: produce appropriate AWT events, 
-     * update component's fields when needed
-     * @param event - native event to dispatch
-     * @return - true means default processing by OS is not needed
-     */
-    public boolean onEvent(NativeEvent event) {
-        int eventId = event.getEventId();
-
-        if (eventId == NativeEvent.ID_CREATED) {
-            return toolkit.onWindowCreated(event.getWindowId());
-        } else if (eventId == NativeEvent.ID_MOUSE_GRAB_CANCELED) {
-            return mouseGrabManager.onGrabCanceled();
-        //???AWT
-//        } else if (popupDispatcher.onEvent(event)) {
-//            return false;
-        } else {
-            Component src = toolkit.getComponentById(event.getWindowId());
-
-            if (src != null) {
-                if (((eventId >= ComponentEvent.COMPONENT_FIRST) && (eventId <= ComponentEvent.COMPONENT_LAST))
-                        || ((eventId >= WindowEvent.WINDOW_FIRST) && (eventId <= WindowEvent.WINDOW_LAST))
-                        || (eventId == NativeEvent.ID_INSETS_CHANGED)
-                        || (eventId == NativeEvent.ID_BOUNDS_CHANGED)
-                        || (eventId == NativeEvent.ID_THEME_CHANGED)) {
-                    return componentDispatcher.dispatch(src, event);
-                } else if ((eventId >= MouseEvent.MOUSE_FIRST)
-                        && (eventId <= MouseEvent.MOUSE_LAST)) {
-                    return mouseDispatcher.dispatch(src, event);
-                } else if (eventId == PaintEvent.PAINT) {
-                    //???AWT: src.redrawManager.addPaintRegion(src, event.getClipRects());
-                    return true;
-                }
-            }
-            if ((eventId >= FocusEvent.FOCUS_FIRST)
-                    && (eventId <= FocusEvent.FOCUS_LAST)) {
-
-                //???AWT: return focusDispatcher.dispatch(src, event);
-                return false;
-            } else if ((eventId >= KeyEvent.KEY_FIRST)
-                    && (eventId <= KeyEvent.KEY_LAST)) {
-                return keyDispatcher.dispatch(src, event);
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * The dispatcher of native events that affect 
-     * component's state or bounds
-     */
-    final class ComponentDispatcher {
-
-        /**
-         * Handle native event that affects component's state or bounds
-         * @param src - the component updated by the event
-         * @param event - the native event
-         * @return - as in Dispatcher.onEvent()
-         * @see Dispatcher#onEvent(NativeEvent)
-         */
-        boolean dispatch(Component src, NativeEvent event) {
-            int id = event.getEventId();
-
-            if ((id == NativeEvent.ID_INSETS_CHANGED)
-                    || (id == NativeEvent.ID_THEME_CHANGED)) {
-                return dispatchInsets(event, src);
-            } else if ((id >= WindowEvent.WINDOW_FIRST)
-                    && (id <= WindowEvent.WINDOW_LAST)) {
-                return dispatchWindow(event, src);
-            } else {
-                return dispatchPureComponent(event, src);
-            }
-        }
-
-        /**
-         * Handle the change of top-level window's native decorations 
-         * @param event - the native event
-         * @param src - the component updated by the event
-         * @return - as in Dispatcher.onEvent()
-         * @see Dispatcher#onEvent(NativeEvent)
-         */
-        boolean dispatchInsets(NativeEvent event, Component src) {
-            //???AWT
-            /*
-            if (src instanceof Window) {
-                ((Window) src).setNativeInsets(event.getInsets());
-            }
-            */
-            return false;
-        }
-
-        /**
-         * Handle the change of top-level window's state
-         * @param event - the native event
-         * @param src - the component updated by the event
-         * @return - as in Dispatcher.onEvent()
-         * @see Dispatcher#onEvent(NativeEvent)
-         */
-        boolean dispatchWindow(NativeEvent event, Component src) {
-            //???AWT
-            /*
-            Window window = (Window) src;
-            int id = event.getEventId();
-
-            if (id == WindowEvent.WINDOW_CLOSING) {
-                toolkit.getSystemEventQueueImpl().postEvent(
-                          new WindowEvent(window, WindowEvent.WINDOW_CLOSING));
-
-                return true;
-            } else if (id == WindowEvent.WINDOW_STATE_CHANGED) {
-                if (window instanceof Frame) {
-                    ((Frame) window)
-                            .updateExtendedState(event.getWindowState());
-                }
-            }
-            */
-
-            return false;
-        }
-
-        /**
-         * Handle the change of component's size and/or position
-         * @param event - the native event
-         * @param src - the component updated by the event
-         * @return - as in Dispatcher.onEvent()
-         * @see Dispatcher#onEvent(NativeEvent)
-         */
-        private boolean dispatchPureComponent(NativeEvent event, Component src) {
-            Rectangle rect = event.getWindowRect();
-            Point loc = rect.getLocation();
-            int mask;
-
-            switch (event.getEventId()) {
-            case NativeEvent.ID_BOUNDS_CHANGED:
-                mask = 0;
-                break;
-            case ComponentEvent.COMPONENT_MOVED:
-                mask = NativeWindow.BOUNDS_NOSIZE;
-                break;
-            case ComponentEvent.COMPONENT_RESIZED:
-                mask = NativeWindow.BOUNDS_NOMOVE;
-                break;
-            default:
-                // awt.12E=Unknown component event id.
-                throw new RuntimeException(Messages.getString("awt.12E")); //$NON-NLS-1$
-            }
-
-            //???AWT
-            /*
-            if (!(src instanceof Window)) {
-                Component compTo = src.getParent();
-                Component compFrom = src.getHWAncestor();
-
-                if ((compTo != null) && (compFrom != null)) {
-                    loc = MouseDispatcher.convertPoint(compFrom, loc, compTo);
-                }
-            } else {
-                int windowState = event.getWindowState();
-
-                if ((windowState >= 0) && (src instanceof Frame)) {
-                    ((Frame) src).updateExtendedState(windowState);
-                }
-            }
-            src.setBounds(loc.x, loc.y, rect.width, rect.height, mask, false);
-            */
-            
-            return false;
-        }
-
-    }
-
-    /**
-     * The dispatcher of the keyboard events
-     */
-    final class KeyDispatcher {
-
-        /**
-         * Handle the keyboard event using the KeyboardFocusManager
-         * @param src - the component receiving the event
-         * @param event - the native event
-         * @return - as in Dispatcher.onEvent()
-         * @see Dispatcher#onEvent(NativeEvent)
-         */
-        boolean dispatch(Component src, NativeEvent event) {
-            int id = event.getEventId();
-            int modifiers = event.getInputModifiers();
-            int location = event.getKeyLocation();
-            int code = event.getVKey();
-            StringBuffer chars = event.getKeyChars();
-            int charsLength = chars.length();
-            long time = event.getTime();
-            char keyChar = event.getLastChar();
-
-            //???AWT
-            /*
-            if (src == null) {
-                //retarget focus proxy key events to focusOwner:
-                Window focusProxyOwner = toolkit.getFocusProxyOwnerById(event
-                        .getWindowId());
-                if (focusProxyOwner == null) {
-                    return false;
-                }
-                src = KeyboardFocusManager.actualFocusOwner;
-            }
-            */
-
-            EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
-            
-            if (src != null) {
-                eventQueue.postEvent(new KeyEvent(src, id, time, modifiers,
-                        code, keyChar, location));
-                // KEY_TYPED goes after KEY_PRESSED
-                if (id == KeyEvent.KEY_PRESSED) {
-                    for (int i = 0; i < charsLength; i++) {
-                        keyChar = chars.charAt(i);
-                        if (keyChar != KeyEvent.CHAR_UNDEFINED) {
-                            eventQueue.postEvent(new KeyEvent(src,
-                                    KeyEvent.KEY_TYPED, time, modifiers,
-                                    KeyEvent.VK_UNDEFINED, keyChar,
-                                    KeyEvent.KEY_LOCATION_UNKNOWN));
-                        }
-                    }
-                }
-            }
-
-            return false;
-        }
-
-    }
-
-    /**
-     * Retargets the mouse events to the grab owner when mouse is grabbed,
-     * grab and ungrab mouse when mouse buttons are pressed and released
-     */
-
-    static final class MouseGrabManager {
-
-        /** 
-         * The top-level window holding the mouse grab 
-         * that was explicitly started by startGrab() method
-         */
-        //???AWT: private Window nativeGrabOwner = null;
-        /** 
-         * The component that owns the synthetic 
-         * mouse grab while at least one of the
-         * mouse buttons is pressed
-         */
-        private Component syntheticGrabOwner = null;
-
-        /**
-         * Previous value of syntheticGrabOwner
-         */
-        private Component lastSyntheticGrabOwner = null;
-
-        /**
-         * Number of mouse buttons currently pressed
-         */
-        private int syntheticGrabDepth = 0;
-
-        /**
-         * The callback to be called when the explicit mouse grab ends
-         */
-        private Runnable whenCanceled;
-
-        /**
-         * Explicitly start the mouse grab
-         * @param grabWindow - the window that will own the grab
-         * @param whenCanceled - the callback to call when the grab ends. 
-         * This parameter can be null
-         */
-        //???AWT
-        /*
-        void startGrab(Window grabWindow, Runnable whenCanceled) {
-
-            if (nativeGrabOwner != null) {
-                // awt.12F=Attempt to start nested mouse grab
-                throw new RuntimeException(Messages.getString("awt.12F")); //$NON-NLS-1$
-            }
-
-            NativeWindow win = grabWindow.getNativeWindow();
-            if (win == null) {
-                // awt.130=Attempt to grab mouse in not displayable window
-                throw new RuntimeException(Messages.getString("awt.130")); //$NON-NLS-1$
-            }
-
-            nativeGrabOwner = grabWindow;
-            this.whenCanceled = whenCanceled;
-            win.grabMouse();
-        }
-        */
-
-        /**
-         * Ends the explicit mouse grab. If the non-null callback was provided
-         * in the startGrab() method, this callback is called 
-         */
-        void endGrab() {
-            //???AWT
-            /*
-            if (nativeGrabOwner == null) {
-                return;
-            }
-
-            Window grabWindow = nativeGrabOwner;
-            nativeGrabOwner = null;
-            NativeWindow win = grabWindow.getNativeWindow();
-
-            if (win != null) {
-                win.ungrabMouse();
-                if (whenCanceled != null) {
-                    whenCanceled.run();
-                    whenCanceled = null;
-                }
-            }
-            */
-        }
-
-        /**
-         * Ends both explicit and synthetic grans 
-         * @return - always returns false
-         */
-        boolean onGrabCanceled() {
-            endGrab();
-            resetSyntheticGrab();
-
-            return false;
-        }
-
-        /**
-         * Starts the synthetic mouse grab, increases the counter 
-         * of currently pressed mouse buttons
-         * @param source - the component where mouse press event occured
-         * @return - the component that owns the synthetic grab
-         */
-        Component onMousePressed(Component source) {
-            if (syntheticGrabDepth == 0) {
-                syntheticGrabOwner = source;
-                lastSyntheticGrabOwner = source;
-            }
-            syntheticGrabDepth++;
-
-            return syntheticGrabOwner;
-        }
-
-        /**
-         * Decreases the counter of currently pressed mouse buttons,
-         * ends the synthetic mouse grab, when this counter becomes zero
-         * @param source - the component where mouse press event occured
-         * @return - the component that owns the synthetic grab, 
-         * or source parameter if mouse grab was released
-         */
-        Component onMouseReleased(Component source) {
-            Component ret = source;
-
-            //???AWT
-            /*
-            if (syntheticGrabOwner != null && nativeGrabOwner == null) {
-                ret = syntheticGrabOwner;
-            }
-            */
-            syntheticGrabDepth--;
-            if (syntheticGrabDepth <= 0) {
-                resetSyntheticGrab();
-                lastSyntheticGrabOwner = null;
-            }
-
-            return ret;
-        }
-
-        /**
-         * Update the state of synthetic ouse gram 
-         * when the mouse is moved/dragged
-         * @param event - the native event
-         */
-        void preprocessEvent(NativeEvent event) {
-            int id = event.getEventId();
-            switch (id) {
-            case MouseEvent.MOUSE_MOVED:
-                if (syntheticGrabOwner != null) {
-                    syntheticGrabOwner = null;
-                    syntheticGrabDepth = 0;
-                }
-                if (lastSyntheticGrabOwner != null) {
-                    lastSyntheticGrabOwner = null;
-                }
-            case MouseEvent.MOUSE_DRAGGED:
-                if (syntheticGrabOwner == null
-                        && lastSyntheticGrabOwner != null) {
-                    syntheticGrabOwner = lastSyntheticGrabOwner;
-                    syntheticGrabDepth = 0;
-                    int mask = event.getInputModifiers();
-                    syntheticGrabDepth += (mask & InputEvent.BUTTON1_DOWN_MASK) != 0 ? 1
-                            : 0;
-                    syntheticGrabDepth += (mask & InputEvent.BUTTON2_DOWN_MASK) != 0 ? 1
-                            : 0;
-                    syntheticGrabDepth += (mask & InputEvent.BUTTON3_DOWN_MASK) != 0 ? 1
-                            : 0;
-                }
-            }
-        }
-
-        /**
-         * @return the component that currently owns the synthetic grab 
-         */
-        Component getSyntheticGrabOwner() {
-            return syntheticGrabOwner;
-        }
-
-        /**
-         * ends synthetic grab
-         */
-        private void resetSyntheticGrab() {
-            syntheticGrabOwner = null;
-            syntheticGrabDepth = 0;
-        }
-
-    }
-    
-    /**
-     * Dispatches native events related to the pop-up boxes 
-     * (the non-component windows such as menus and drop lists)
-     */
-//    final class PopupDispatcher {
-//
-//        private PopupBox activePopup;
-//
-//        private PopupBox underCursor;
-//
-//        private final MouseGrab grab = new MouseGrab();
-//
-//        /**
-//         * Handles the mouse grab for pop-up boxes
-//         */
-//        private final class MouseGrab {
-//            private int depth;
-//
-//            private PopupBox owner;
-//
-//            private final Point start = new Point();
-//
-//            /**
-//             * Starts the grab when mouse is pressed
-//             * @param src - the pop-up box where mouse event has occured
-//             * @param where - the mouse pointer location
-//             * @return - the grab owner
-//             */
-//            PopupBox mousePressed(PopupBox src, Point where) {
-//                if (depth == 0) {
-//                    owner = src;
-//                    start.setLocation(where);
-//                }
-//                depth++;
-//                return owner;
-//            }
-//
-//            /**
-//             * Ends the grab when all mousebuttons are released
-//             * @param src - the pop-up box where mouse event has occured
-//             * @param where - the mouse pointer location
-//             * @return - the grab owner, or src parameter if the grab has ended
-//             */
-//            PopupBox mouseReleased(PopupBox src, Point where) {
-//                PopupBox ret = (owner != null) ? owner : src;
-//                if (depth == 0) {
-//                    return ret;
-//                }
-//                depth--;
-//                if (depth == 0) {
-//                    PopupBox tgt = owner;
-//                    owner = null;
-//                    if (tgt != null && src == null) {
-//                        Point a = new Point(start);
-//                        Point b = new Point(where);
-//                        Point pos = tgt.getScreenLocation();
-//                        a.translate(-pos.x, -pos.y);
-//                        b.translate(-pos.x, -pos.y);
-//                        if (tgt.closeOnUngrab(a, b)) {
-//                            return null;
-//                        }
-//                    }
-//                }
-//                return ret;
-//            }
-//
-//            /**
-//             * Set the grab owner to null
-//             */
-//            void reset() {
-//                depth = 0;
-//                owner = null;
-//                start.setLocation(0, 0);
-//            }
-//
-//            /**
-//             * @return - the pop-up box currently owning the grab
-//             */
-//            public PopupBox getOwner() {
-//                return owner;
-//            }
-//        }
-//
-//        /**
-//         * Call the mouse event handler of the pop-up box
-//         * @param src - the pop-up box where the mouse event occured
-//         * @param eventId - the event ID, one of MouseEvent.MOUSE_* constants
-//         * @param where - the mouse pointer location
-//         * @param event - native event
-//         */
-//        private void mouseEvent(PopupBox src, int eventId, Point where,
-//                NativeEvent event) {
-//            Point pos = src.getScreenLocation();
-//            pos.setLocation(where.x - pos.x, where.y - pos.y);
-//
-//            src.onMouseEvent(eventId, pos, event.getMouseButton(), event
-//                    .getTime(), event.getInputModifiers(), event
-//                    .getWheelRotation());
-//        }
-//
-//        /**
-//         * Handle the native event targeted by a pop-up box. This could be 
-//         * paint event, mouse or keyboard event.
-//         * @param event - the native event
-//         * @return - false if the event was handled and doesn't 
-//         * need the further processing; true when the further 
-//         * processing is needed
-//         */
-//        boolean onEvent(NativeEvent event) {
-//            PopupBox src = toolkit.getPopupBoxById(event.getWindowId());
-//            int id = event.getEventId();
-//
-//            if ((id == PaintEvent.PAINT)) {
-//                if (src != null) {
-//                    src.paint(event.getClipRects());
-//                    return true;
-//                }
-//                Component c = toolkit.getComponentById(event.getWindowId());
-//                if ((c != null) && (c instanceof Frame)) {
-//                    ((Frame) c).paintMenuBar(event.getClipRects());
-//                }
-//                return false;
-//            }
-//
-//            if ((id >= MouseEvent.MOUSE_FIRST) && (id <= MouseEvent.MOUSE_LAST)) {
-//                Point where = event.getScreenPos();
-//
-//                if (src != underCursor) {
-//                    if (underCursor != null) {
-//                        mouseEvent(underCursor, MouseEvent.MOUSE_EXITED, where,
-//                                event);
-//                    }
-//                    underCursor = src;
-//                    if (underCursor != null) {
-//                        mouseEvent(underCursor, MouseEvent.MOUSE_ENTERED,
-//                                where, event);
-//                        underCursor.setDefaultCursor();
-//                    }
-//                }
-//                if (id == MouseEvent.MOUSE_EXITED) {
-//                    underCursor = null;
-//                }
-//
-//                if ((activePopup == null) && (src == null || !src.isMenuBar())) {
-//                    return false;
-//                }
-//
-//                if (id == MouseEvent.MOUSE_PRESSED) {
-//                    src = grab.mousePressed(src, where);
-//                } else if (id == MouseEvent.MOUSE_RELEASED) {
-//                    src = grab.mouseReleased(src, where);
-//                } else if (src == null) {
-//                    src = grab.getOwner();
-//                }
-//
-//                PopupBox wasActive = activePopup;
-//
-//                if (src != null) {
-//                    mouseEvent(src, id, where, event);
-//                    return src.isMenu() || src.contains(where);
-//                }
-//
-//                if (wasActive != null && activePopup == null) {
-//                    return wasActive.isMenu();
-//                }
-//
-//                if ((id == MouseEvent.MOUSE_PRESSED)
-//                        || (id == MouseEvent.MOUSE_RELEASED)) {
-//                    boolean isMenu = activePopup.isMenu();
-//                    deactivateAll();
-//                    return !isMenu;
-//                }
-//                return true;
-//            }
-//
-//            if (activePopup == null) {
-//                return false;
-//            }
-//
-//            if ((id >= KeyEvent.KEY_FIRST) && (id <= KeyEvent.KEY_LAST)) {
-//                boolean isMenu = activePopup.isMenu();
-//                activePopup.dispatchKeyEvent(id, event.getVKey(), event
-//                        .getTime(), event.getInputModifiers());
-//
-//                return isMenu;
-//            }
-//
-//            return false;
-//        }
-//
-//        /**
-//         * Remember the pop-up as active and grab the mouse on it
-//         * @param popup - the pop-up box to activate
-//         */
-//        void activate(final PopupBox popup) {
-//            if (activePopup == null) {
-//
-//                activePopup = popup;
-//                mouseGrabManager.startGrab(popup.getOwner(), new Runnable() {
-//                    public void run() {
-//                        deactivate(popup);
-//                    }
-//                });
-//            }
-//        }
-//
-//        /**
-//         * Deactivate the currently active pop-up box
-//         */
-//        void deactivateAll() {
-//            deactivate(activePopup);
-//        }
-//
-//        /**
-//         * Deactivate the pop-up box, end the mouse grab
-//         */
-//        void deactivate(PopupBox popup) {
-//            grab.reset();
-//
-//            if (activePopup != null && activePopup == popup) {
-//                activePopup = null;
-//                mouseGrabManager.endGrab();
-//                popup.hide();
-//                underCursor = null;
-//            }
-//        }
-//
-//        /**
-//         * Check that the pop-up box is currently active
-//         * @param popup - the pop-up box to check
-//         * @return - true if active
-//         */
-//        boolean isActive(PopupBox popup) {
-//            return (popup == activePopup) && (popup != null);
-//        }
-//    }
-
-}
\ No newline at end of file
diff --git a/awt/java/awt/DisplayMode.java b/awt/java/awt/DisplayMode.java
deleted file mode 100644
index 8021010..0000000
--- a/awt/java/awt/DisplayMode.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * The DisplayMode class contains the bit depth, height, width and refresh rate
- * of a GraphicsDevice.
- * 
- * @since Android 1.0
- */
-public final class DisplayMode {
-
-    /**
-     * The width.
-     */
-    private final int width;
-
-    /**
-     * The height.
-     */
-    private final int height;
-
-    /**
-     * The bit depth.
-     */
-    private final int bitDepth;
-
-    /**
-     * The refresh rate.
-     */
-    private final int refreshRate;
-
-    /**
-     * The Constant Value BIT_DEPTH_MULTI indicates the bit depth
-     */
-
-    public static final int BIT_DEPTH_MULTI = -1;
-
-    /**
-     * The Constant REFRESH_RATE_UNKNOWN indicates the refresh rate.
-     */
-    public static final int REFRESH_RATE_UNKNOWN = 0;
-
-    /**
-     * Creates a new DisplayMode object with the specified parameters.
-     * 
-     * @param width
-     *            the width of the display.
-     * @param height
-     *            the height of the display.
-     * @param bitDepth
-     *            the bit depth of the display.
-     * @param refreshRate
-     *            the refresh rate of the display.
-     */
-
-    public DisplayMode(int width, int height, int bitDepth, int refreshRate) {
-        this.width = width;
-        this.height = height;
-        this.bitDepth = bitDepth;
-        this.refreshRate = refreshRate;
-    }
-
-    /**
-     * Compares if this DisplayMode is equal to the specified object or not.
-     * 
-     * @param dm
-     *            the Object to be compared.
-     * @return true, if the specified object is a DisplayMode with the same data
-     *         values as this DisplayMode, false otherwise.
-     */
-
-    @Override
-    public boolean equals(Object dm) {
-        if (dm instanceof DisplayMode) {
-            return equals((DisplayMode)dm);
-        }
-        return false;
-    }
-
-    /**
-     * Compares if this DisplayMode is equal to the specified DisplayMode object
-     * or not.
-     * 
-     * @param dm
-     *            the DisplayMode to be compared.
-     * @return true, if all of the data values of this DisplayMode are equal to
-     *         the values of the specified DisplayMode object, false otherwise.
-     */
-    public boolean equals(DisplayMode dm) {
-        if (dm == null) {
-            return false;
-        }
-        if (dm.bitDepth != bitDepth) {
-            return false;
-        }
-        if (dm.refreshRate != refreshRate) {
-            return false;
-        }
-        if (dm.width != width) {
-            return false;
-        }
-        if (dm.height != height) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Gets the bit depth of the DisplayMode, returns BIT_DEPTH_MULTI value if
-     * multiple bit depths are supported in this display mode.
-     * 
-     * @return the bit depth of the DisplayMode.
-     */
-    public int getBitDepth() {
-        return bitDepth;
-    }
-
-    /**
-     * Gets the height of the DisplayMode.
-     * 
-     * @return the height of the DisplayMode.
-     */
-    public int getHeight() {
-        return height;
-    }
-
-    /**
-     * Gets the refresh rate of the DisplayMode, returns REFRESH_RATE_UNKNOWN
-     * value if the information is not available.
-     * 
-     * @return the refresh rate of the DisplayMode.
-     */
-    public int getRefreshRate() {
-        return refreshRate;
-    }
-
-    /**
-     * Gets the width of the DisplayMode.
-     * 
-     * @return the width of the DisplayMode.
-     */
-    public int getWidth() {
-        return width;
-    }
-}
diff --git a/awt/java/awt/Event.java b/awt/java/awt/Event.java
deleted file mode 100644
index 226a61f..0000000
--- a/awt/java/awt/Event.java
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.io.Serializable;
-
-/**
- * The Event class is obsolete and has been replaced by AWTEvent class.
- * 
- * @since Android 1.0
- */
-public class Event implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 5488922509400504703L;
-
-    /**
-     * The Constant SHIFT_MASK indicates that the Shift key is down when the
-     * event occurred.
-     */
-    public static final int SHIFT_MASK = 1;
-
-    /**
-     * The Constant CTRL_MASK indicates that the Control key is down when the
-     * event occurred.
-     */
-    public static final int CTRL_MASK = 2;
-
-    /**
-     * The Constant META_MASK indicates that the Meta key is down when t he
-     * event occurred (or the right mouse button).
-     */
-    public static final int META_MASK = 4;
-
-    /**
-     * The Constant ALT_MASK indicates that the Alt key is down when the event
-     * occurred (or the middle mouse button).
-     */
-    public static final int ALT_MASK = 8;
-
-    /**
-     * The Constant HOME indicates Home key.
-     */
-    public static final int HOME = 1000;
-
-    /**
-     * The Constant END indicates End key.
-     */
-    public static final int END = 1001;
-
-    /**
-     * The Constant PGUP indicates Page Up key.
-     */
-    public static final int PGUP = 1002;
-
-    /**
-     * The Constant PGDN indicates Page Down key.
-     */
-    public static final int PGDN = 1003;
-
-    /**
-     * The Constant UP indicates Up key.
-     */
-    public static final int UP = 1004;
-
-    /**
-     * The Constant DOWN indicates Down key.
-     */
-    public static final int DOWN = 1005;
-
-    /**
-     * The Constant LEFT indicates Left key.
-     */
-    public static final int LEFT = 1006;
-
-    /**
-     * The Constant RIGHT indicates Right key.
-     */
-    public static final int RIGHT = 1007;
-
-    /**
-     * The Constant F1 indicates F1 key.
-     */
-    public static final int F1 = 1008;
-
-    /**
-     * The Constant F2 indicates F2 key.
-     */
-    public static final int F2 = 1009;
-
-    /**
-     * The Constant F3 indicates F3 key.
-     */
-    public static final int F3 = 1010;
-
-    /**
-     * The Constant F4 indicates F4 key.
-     */
-    public static final int F4 = 1011;
-
-    /**
-     * The Constant F5 indicates F5 key.
-     */
-    public static final int F5 = 1012;
-
-    /**
-     * The Constant F6 indicates F6 key.
-     */
-    public static final int F6 = 1013;
-
-    /**
-     * The Constant F7 indicates F7 key.
-     */
-    public static final int F7 = 1014;
-
-    /**
-     * The Constant F8 indicates F8 key.
-     */
-    public static final int F8 = 1015;
-
-    /**
-     * The Constant F9 indicates F9 key.
-     */
-    public static final int F9 = 1016;
-
-    /**
-     * The Constant F10 indicates F10 key.
-     */
-    public static final int F10 = 1017;
-
-    /**
-     * The Constant F11 indicates F11 key.
-     */
-    public static final int F11 = 1018;
-
-    /**
-     * The Constant F12 indicates F12 key.
-     */
-    public static final int F12 = 1019;
-
-    /**
-     * The Constant PRINT_SCREEN indicates Print Screen key.
-     */
-    public static final int PRINT_SCREEN = 1020;
-
-    /**
-     * The Constant SCROLL_LOCK indicates Scroll Lock key.
-     */
-    public static final int SCROLL_LOCK = 1021;
-
-    /**
-     * The Constant CAPS_LOCK indicates Caps Lock key.
-     */
-    public static final int CAPS_LOCK = 1022;
-
-    /**
-     * The Constant NUM_LOCK indicates Num Lock key.
-     */
-    public static final int NUM_LOCK = 1023;
-
-    /**
-     * The Constant PAUSE indicates Pause key.
-     */
-    public static final int PAUSE = 1024;
-
-    /**
-     * The Constant INSERT indicates Insert key.
-     */
-    public static final int INSERT = 1025;
-
-    /**
-     * The Constant ENTER indicates Enter key.
-     */
-    public static final int ENTER = 10;
-
-    /**
-     * The Constant BACK_SPACE indicates Back Space key.
-     */
-    public static final int BACK_SPACE = 8;
-
-    /**
-     * The Constant TAB indicates TAb key.
-     */
-    public static final int TAB = 9;
-
-    /**
-     * The Constant ESCAPE indicates Escape key.
-     */
-    public static final int ESCAPE = 27;
-
-    /**
-     * The Constant DELETE indicates Delete key.
-     */
-    public static final int DELETE = 127;
-
-    /**
-     * The Constant WINDOW_DESTROY indicates an event when the user has asked
-     * the window manager to kill the window.
-     */
-    public static final int WINDOW_DESTROY = 201;
-
-    /**
-     * The Constant WINDOW_EXPOSE indicates an event when the user has asked the
-     * window manager to expose the window.
-     */
-    public static final int WINDOW_EXPOSE = 202;
-
-    /**
-     * The Constant WINDOW_ICONIFY indicates an event when the user has asked
-     * the window manager to iconify the window.
-     */
-    public static final int WINDOW_ICONIFY = 203;
-
-    /**
-     * The Constant WINDOW_DEICONIFY indicates an event when the user has asked
-     * the window manager to deiconify the window.
-     */
-    public static final int WINDOW_DEICONIFY = 204;
-
-    /**
-     * The Constant WINDOW_MOVED indicates an event when the user has asked the
-     * window manager to move the window.
-     */
-    public static final int WINDOW_MOVED = 205;
-
-    /**
-     * The Constant KEY_PRESS indicates an event when the user presses a normal
-     * key.
-     */
-    public static final int KEY_PRESS = 401;
-
-    /**
-     * The Constant KEY_RELEASE indicates an event when the user releases a
-     * normal key.
-     */
-    public static final int KEY_RELEASE = 402;
-
-    /**
-     * The Constant KEY_ACTION indicates an event when the user pressed a
-     * non-ASCII action key.
-     */
-    public static final int KEY_ACTION = 403;
-
-    /**
-     * The Constant KEY_ACTION_RELEASE indicates an event when the user released
-     * a non-ASCII action key.
-     */
-    public static final int KEY_ACTION_RELEASE = 404;
-
-    /**
-     * The Constant MOUSE_DOWN indicates an event when the user has pressed the
-     * mouse button.
-     */
-    public static final int MOUSE_DOWN = 501;
-
-    /**
-     * The Constant MOUSE_UP indicates an event when the user has released the
-     * mouse button.
-     */
-    public static final int MOUSE_UP = 502;
-
-    /**
-     * The Constant MOUSE_MOVE indicates an event when the user has moved the
-     * mouse with no button pressed.
-     */
-    public static final int MOUSE_MOVE = 503;
-
-    /**
-     * The Constant MOUSE_ENTER indicates an event when the mouse has entered a
-     * component.
-     */
-    public static final int MOUSE_ENTER = 504;
-
-    /**
-     * The Constant MOUSE_EXIT indicates an event when the mouse has exited a
-     * component.
-     */
-    public static final int MOUSE_EXIT = 505;
-
-    /**
-     * The Constant MOUSE_DRAG indicates an event when the user has moved a
-     * mouse with the pressed button.
-     */
-    public static final int MOUSE_DRAG = 506;
-
-    /**
-     * The Constant SCROLL_LINE_UP indicates an event when the user has
-     * activated line-up area of scrollbar.
-     */
-    public static final int SCROLL_LINE_UP = 601;
-
-    /**
-     * The Constant SCROLL_LINE_DOWN indicates an event when the user has
-     * activated line-down area of scrollbar.
-     */
-    public static final int SCROLL_LINE_DOWN = 602;
-
-    /**
-     * The Constant SCROLL_PAGE_UP indicates an event when the user has
-     * activated page up area of scrollbar.
-     */
-    public static final int SCROLL_PAGE_UP = 603;
-
-    /**
-     * The Constant SCROLL_PAGE_DOWN indicates an event when the user has
-     * activated page down area of scrollbar.
-     */
-    public static final int SCROLL_PAGE_DOWN = 604;
-
-    /**
-     * The Constant SCROLL_ABSOLUTE indicates an event when the user has moved
-     * the bubble in a scroll bar.
-     */
-    public static final int SCROLL_ABSOLUTE = 605;
-
-    /**
-     * The Constant SCROLL_BEGIN indicates a scroll begin event.
-     */
-    public static final int SCROLL_BEGIN = 606;
-
-    /**
-     * The Constant SCROLL_END indicates a scroll end event.
-     */
-    public static final int SCROLL_END = 607;
-
-    /**
-     * The Constant LIST_SELECT indicates that an item in a list has been
-     * selected.
-     */
-    public static final int LIST_SELECT = 701;
-
-    /**
-     * The Constant LIST_DESELECT indicates that an item in a list has been
-     * unselected.
-     */
-    public static final int LIST_DESELECT = 702;
-
-    /**
-     * The Constant ACTION_EVENT indicates that the user wants some action to
-     * occur.
-     */
-    public static final int ACTION_EVENT = 1001;
-
-    /**
-     * The Constant LOAD_FILE indicates a file loading event.
-     */
-    public static final int LOAD_FILE = 1002;
-
-    /**
-     * The Constant SAVE_FILE indicates a file saving event.
-     */
-    public static final int SAVE_FILE = 1003;
-
-    /**
-     * The Constant GOT_FOCUS indicates that a component got the focus.
-     */
-    public static final int GOT_FOCUS = 1004;
-
-    /**
-     * The Constant LOST_FOCUS indicates that the component lost the focus.
-     */
-    public static final int LOST_FOCUS = 1005;
-
-    /**
-     * The target is the component with which the event is associated.
-     */
-    public Object target;
-
-    /**
-     * The when is timestamp when event has occured.
-     */
-    public long when;
-
-    /**
-     * The id indicates the type of the event.
-     */
-    public int id;
-
-    /**
-     * The x coordinate of event.
-     */
-    public int x;
-
-    /**
-     * The y coordinate of event.
-     */
-    public int y;
-
-    /**
-     * The key code of key event.
-     */
-    public int key;
-
-    /**
-     * The state of the modifier keys (given by a bitmask).
-     */
-    public int modifiers;
-
-    /**
-     * The click count indicates the number of consecutive clicks.
-     */
-    public int clickCount;
-
-    /**
-     * The argument of the event.
-     */
-    public Object arg;
-
-    /**
-     * The next event.
-     */
-    public Event evt;
-
-    /**
-     * Instantiates a new event with the specified target component, event type,
-     * and argument.
-     * 
-     * @param target
-     *            the target component.
-     * @param id
-     *            the event type.
-     * @param arg
-     *            the argument.
-     */
-    public Event(Object target, int id, Object arg) {
-        this(target, 0l, id, 0, 0, 0, 0, arg);
-    }
-
-    /**
-     * Instantiates a new event with the specified target component, time stamp,
-     * event type, x and y coordinates, keyboard key, state of the modifier
-     * keys, and an argument set to null.
-     * 
-     * @param target
-     *            the target component.
-     * @param when
-     *            the time stamp.
-     * @param id
-     *            the event type.
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @param key
-     *            the key.
-     * @param modifiers
-     *            the modifier keys state.
-     */
-    public Event(Object target, long when, int id, int x, int y, int key, int modifiers) {
-        this(target, when, id, x, y, key, modifiers, null);
-    }
-
-    /**
-     * Instantiates a new event with the specified target component, time stamp,
-     * event type, x and y coordinates, keyboard key, state of the modifier
-     * keys, and an argument.
-     * 
-     * @param target
-     *            the target component.
-     * @param when
-     *            the time stamp.
-     * @param id
-     *            the event type.
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @param key
-     *            the key.
-     * @param modifiers
-     *            the modifier keys state.
-     * @param arg
-     *            the specified argument.
-     */
-    public Event(Object target, long when, int id, int x, int y, int key, int modifiers, Object arg) {
-        this.target = target;
-        this.when = when;
-        this.id = id;
-        this.x = x;
-        this.y = y;
-        this.key = key;
-        this.modifiers = modifiers;
-        this.arg = arg;
-    }
-
-    /**
-     * Returns a string representation of this Event.
-     * 
-     * @return a string representation of this Event.
-     */
-    @Override
-    public String toString() {
-        /*
-         * The format is based on 1.5 release behavior which can be revealed by
-         * the following code: Event e = new Event(new Button(), 0l,
-         * Event.KEY_PRESS, 0, 0, Event.TAB, Event.SHIFT_MASK, "arg");
-         * System.out.println(e);
-         */
-
-        return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    /**
-     * Returns a string representing the state of this Event.
-     * 
-     * @return a string representing the state of this Event.
-     */
-    protected String paramString() {
-        return "id=" + id + ",x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-                (key != 0 ? ",key=" + key + getModifiersString() : "") + //$NON-NLS-1$ //$NON-NLS-2$
-                ",target=" + target + //$NON-NLS-1$
-                (arg != null ? ",arg=" + arg : ""); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    /**
-     * Gets a string representation of the modifiers.
-     * 
-     * @return a string representation of the modifiers.
-     */
-    private String getModifiersString() {
-        String strMod = ""; //$NON-NLS-1$
-        if (shiftDown()) {
-            strMod += ",shift"; //$NON-NLS-1$
-        }
-        if (controlDown()) {
-            strMod += ",control"; //$NON-NLS-1$
-        }
-        if (metaDown()) {
-            strMod += ",meta"; //$NON-NLS-1$
-        }
-        return strMod;
-    }
-
-    /**
-     * Translates x and y coordinates of his event to the x+dx and x+dy
-     * coordinates.
-     * 
-     * @param dx
-     *            the distance by which the event's x coordinate is increased.
-     * @param dy
-     *            the distance by which the event's y coordinate is increased.
-     */
-    public void translate(int dx, int dy) {
-        x += dx;
-        y += dy;
-    }
-
-    /**
-     * Checks if Control key is down or not.
-     * 
-     * @return true, if Control key is down; false otherwise.
-     */
-    public boolean controlDown() {
-        return (modifiers & CTRL_MASK) != 0;
-    }
-
-    /**
-     * Checks if Meta key is down or not.
-     * 
-     * @return true, if Meta key is down; false otherwise.
-     */
-    public boolean metaDown() {
-        return (modifiers & META_MASK) != 0;
-    }
-
-    /**
-     * Checks if Shift key is down or not.
-     * 
-     * @return true, if Shift key is down; false otherwise.
-     */
-    public boolean shiftDown() {
-        return (modifiers & SHIFT_MASK) != 0;
-    }
-
-}
diff --git a/awt/java/awt/EventDispatchThread.java b/awt/java/awt/EventDispatchThread.java
deleted file mode 100644
index 442c8a2..0000000
--- a/awt/java/awt/EventDispatchThread.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov, Pavel Dolgov
- * @version $Revision$
- */
-package java.awt;
-
-import org.apache.harmony.awt.wtk.NativeEvent;
-import org.apache.harmony.awt.wtk.NativeEventQueue;
-
-class EventDispatchThread extends Thread  {
-    
-    private static final class MarkerEvent extends AWTEvent {
-        MarkerEvent(Object source, int id) {
-            super(source, id);
-        }
-    }
-
-    final Dispatcher dispatcher;
-    final Toolkit toolkit;
-    private NativeEventQueue nativeQueue;
-
-    protected volatile boolean shutdownPending = false;
-
-    /**
-     * Initialise and run the main event loop
-     */
-    @Override
-    public void run() {
-        nativeQueue = toolkit.getNativeEventQueue();
-
-        try {
-            runModalLoop(null);
-        } finally {
-            toolkit.shutdownWatchdog.forceShutdown();
-        }
-    }
-
-    void runModalLoop(ModalContext context) {
-        long lastPaintTime = System.currentTimeMillis();
-        while (!shutdownPending && (context == null || context.isModalLoopRunning())) {
-            try {
-            EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
-
-            NativeEvent ne = nativeQueue.getNextEvent();
-            if (ne != null) {
-                dispatcher.onEvent(ne);
-                MarkerEvent marker = new MarkerEvent(this, 0);
-                eventQueue.postEvent(marker);
-                for (AWTEvent ae = eventQueue.getNextEventNoWait(); 
-                        (ae != null) && (ae != marker); 
-                        ae = eventQueue.getNextEventNoWait()) {
-                    eventQueue.dispatchEvent(ae);
-                }
-            } else {
-                toolkit.shutdownWatchdog.setNativeQueueEmpty(true);
-                AWTEvent ae = eventQueue.getNextEventNoWait();
-                if (ae != null) {
-                    eventQueue.dispatchEvent(ae);
-                    long curTime = System.currentTimeMillis();
-                    if (curTime - lastPaintTime > 10) {
-                        toolkit.onQueueEmpty();
-                        lastPaintTime = System.currentTimeMillis();
-                    }
-                } else {
-                    toolkit.shutdownWatchdog.setAwtQueueEmpty(true);
-                    toolkit.onQueueEmpty();
-                    lastPaintTime = System.currentTimeMillis();
-                    waitForAnyEvent();
-                }
-            }
-            } catch (Throwable t) {
-                // TODO: Exception handler should be implemented
-                // t.printStackTrace();
-            }
-        }
-    }
-    
-    private void waitForAnyEvent() {
-        EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
-        if (!eventQueue.isEmpty() || !nativeQueue.isEmpty()) {
-            return;
-        }
-        Object eventMonitor = nativeQueue.getEventMonitor();
-        synchronized(eventMonitor) {
-            try {
-                eventMonitor.wait();
-            } catch (InterruptedException e) {}
-        }
-    }
-
-    void shutdown() {
-        shutdownPending = true;
-    }
-
-    EventDispatchThread(Toolkit toolkit, Dispatcher dispatcher ) {
-        this.toolkit = toolkit;
-        this.dispatcher = dispatcher;
-        setName("AWT-EventDispatchThread"); //$NON-NLS-1$
-        setDaemon(true);
-    }
-
-}
diff --git a/awt/java/awt/EventQueue.java b/awt/java/awt/EventQueue.java
deleted file mode 100644
index 126a593..0000000
--- a/awt/java/awt/EventQueue.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov, Pavel Dolgov
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.event.InvocationEvent;
-import java.lang.reflect.InvocationTargetException;
-import java.util.EmptyStackException;
-
-/**
- * The EventQueue class manages events. It is a platform-independent class that
- * queues events both from the underlying peer classes and from trusted
- * application classes.
- * 
- * @since Android 1.0
- */
-public class EventQueue {
-
-    /**
-     * The core ref.
-     */
-    private final EventQueueCoreAtomicReference coreRef = new EventQueueCoreAtomicReference();
-
-    /**
-     * The Class EventQueueCoreAtomicReference.
-     */
-    private static final class EventQueueCoreAtomicReference {
-
-        /**
-         * The core.
-         */
-        private EventQueueCore core;
-
-        /* synchronized */
-        /**
-         * Gets the.
-         * 
-         * @return the event queue core.
-         */
-        EventQueueCore get() {
-            return core;
-        }
-
-        /* synchronized */
-        /**
-         * Sets the.
-         * 
-         * @param newCore
-         *            the new core.
-         */
-        void set(EventQueueCore newCore) {
-            core = newCore;
-        }
-    }
-
-    /**
-     * Returns true if the calling thread is the current AWT EventQueue's
-     * dispatch thread.
-     * 
-     * @return true, if the calling thread is the current AWT EventQueue's
-     *         dispatch thread; false otherwise.
-     */
-    public static boolean isDispatchThread() {
-        return Thread.currentThread() instanceof EventDispatchThread;
-    }
-
-    /**
-     * Posts an InvocationEvent which executes the run() method on a Runnable
-     * when dispatched by the AWT event dispatcher thread.
-     * 
-     * @param runnable
-     *            the Runnable whose run method should be executed synchronously
-     *            on the EventQueue.
-     */
-    public static void invokeLater(Runnable runnable) {
-        Toolkit toolkit = Toolkit.getDefaultToolkit();
-        InvocationEvent event = new InvocationEvent(toolkit, runnable);
-        toolkit.getSystemEventQueueImpl().postEvent(event);
-    }
-
-    /**
-     * Posts an InvocationEvent which executes the run() method on a Runnable
-     * when dispatched by the AWT event dispatcher thread and the notifyAll
-     * method is called on it immediately after run returns.
-     * 
-     * @param runnable
-     *            the Runnable whose run method should be executed synchronously
-     *            on the EventQueue.
-     * @throws InterruptedException
-     *             if another thread has interrupted this thread.
-     * @throws InvocationTargetException
-     *             if an error occurred while running the runnable.
-     */
-    public static void invokeAndWait(Runnable runnable) throws InterruptedException,
-            InvocationTargetException {
-
-        if (isDispatchThread()) {
-            throw new Error();
-        }
-
-        final Toolkit toolkit = Toolkit.getDefaultToolkit();
-        final Object notifier = new Object(); // $NON-LOCK-1$
-        InvocationEvent event = new InvocationEvent(toolkit, runnable, notifier, true);
-
-        synchronized (notifier) {
-            toolkit.getSystemEventQueueImpl().postEvent(event);
-            notifier.wait();
-        }
-
-        Exception exception = event.getException();
-
-        if (exception != null) {
-            throw new InvocationTargetException(exception);
-        }
-    }
-
-    /**
-     * Gets the system event queue.
-     * 
-     * @return the system event queue.
-     */
-    private static EventQueue getSystemEventQueue() {
-        Thread th = Thread.currentThread();
-        if (th instanceof EventDispatchThread) {
-            return ((EventDispatchThread)th).toolkit.getSystemEventQueueImpl();
-        }
-        return null;
-    }
-
-    /**
-     * Gets the most recent event's timestamp. This event was dispatched from
-     * the EventQueue associated with the calling thread.
-     * 
-     * @return the timestamp of the last Event to be dispatched, or
-     *         System.currentTimeMillis() if this method is invoked from a
-     *         thread other than an event-dispatching thread.
-     */
-    public static long getMostRecentEventTime() {
-        EventQueue eq = getSystemEventQueue();
-        return (eq != null) ? eq.getMostRecentEventTimeImpl() : System.currentTimeMillis();
-    }
-
-    /**
-     * Gets the most recent event time impl.
-     * 
-     * @return the most recent event time impl.
-     */
-    private long getMostRecentEventTimeImpl() {
-        return getCore().getMostRecentEventTime();
-    }
-
-    /**
-     * Returns the the currently dispatched event by the EventQueue associated
-     * with the calling thread.
-     * 
-     * @return the currently dispatched event or null if this method is invoked
-     *         from a thread other than an event-dispatching thread.
-     */
-    public static AWTEvent getCurrentEvent() {
-        EventQueue eq = getSystemEventQueue();
-        return (eq != null) ? eq.getCurrentEventImpl() : null;
-    }
-
-    /**
-     * Gets the current event impl.
-     * 
-     * @return the current event impl.
-     */
-    private AWTEvent getCurrentEventImpl() {
-        return getCore().getCurrentEvent();
-    }
-
-    /**
-     * Instantiates a new event queue.
-     */
-    public EventQueue() {
-        setCore(new EventQueueCore(this));
-    }
-
-    /**
-     * Instantiates a new event queue.
-     * 
-     * @param t
-     *            the t.
-     */
-    EventQueue(Toolkit t) {
-        setCore(new EventQueueCore(this, t));
-    }
-
-    /**
-     * Posts a event to the EventQueue.
-     * 
-     * @param event
-     *            AWTEvent.
-     */
-    public void postEvent(AWTEvent event) {
-        event.isPosted = true;
-        getCore().postEvent(event);
-    }
-
-    /**
-     * Returns an event from the EventQueue and removes it from this queue.
-     * 
-     * @return the next AWTEvent.
-     * @throws InterruptedException
-     *             is thrown if another thread interrupts this thread.
-     */
-    public AWTEvent getNextEvent() throws InterruptedException {
-        return getCore().getNextEvent();
-    }
-
-    /**
-     * Gets the next event no wait.
-     * 
-     * @return the next event no wait.
-     */
-    AWTEvent getNextEventNoWait() {
-        return getCore().getNextEventNoWait();
-    }
-
-    /**
-     * Returns the first event of the EventQueue (without removing it from the
-     * queue).
-     * 
-     * @return the the first AWT event of the EventQueue.
-     */
-    public AWTEvent peekEvent() {
-        return getCore().peekEvent();
-    }
-
-    /**
-     * Returns the first event of the EventQueue with the specified ID (without
-     * removing it from the queue).
-     * 
-     * @param id
-     *            the type ID of event.
-     * @return the first event of the EventQueue with the specified ID.
-     */
-    public AWTEvent peekEvent(int id) {
-        return getCore().peekEvent(id);
-    }
-
-    /**
-     * Replaces the existing EventQueue with the specified EventQueue. Any
-     * pending events are transferred to the new EventQueue.
-     * 
-     * @param newEventQueue
-     *            the new event queue.
-     */
-    public void push(EventQueue newEventQueue) {
-        getCore().push(newEventQueue);
-    }
-
-    /**
-     * Stops dispatching events using this EventQueue. Any pending events are
-     * transferred to the previous EventQueue.
-     * 
-     * @throws EmptyStackException
-     *             is thrown if no previous push was made on this EventQueue.
-     */
-    protected void pop() throws EmptyStackException {
-        getCore().pop();
-    }
-
-    /**
-     * Dispatches the specified event.
-     * 
-     * @param event
-     *            the AWTEvent.
-     */
-    protected void dispatchEvent(AWTEvent event) {
-        getCore().dispatchEventImpl(event);
-    }
-
-    /**
-     * Checks if the queue is empty.
-     * 
-     * @return true, if is empty.
-     */
-    boolean isEmpty() {
-        return getCore().isEmpty();
-    }
-
-    /**
-     * Gets the core.
-     * 
-     * @return the core.
-     */
-    EventQueueCore getCore() {
-        return coreRef.get();
-    }
-
-    /**
-     * Sets the core.
-     * 
-     * @param newCore
-     *            the new core.
-     */
-    void setCore(EventQueueCore newCore) {
-        coreRef.set((newCore != null) ? newCore : new EventQueueCore(this));
-    }
-}
diff --git a/awt/java/awt/EventQueueCore.java b/awt/java/awt/EventQueueCore.java
deleted file mode 100644
index ffc7c46..0000000
--- a/awt/java/awt/EventQueueCore.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/** 
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.InputEvent;
-import java.awt.event.InputMethodEvent;
-import java.awt.event.InvocationEvent;
-import java.awt.event.MouseEvent;
-import java.util.LinkedList;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The events storage for EventQueue
- */
-final class EventQueueCore {
-    
-    private final LinkedList<EventQueue> queueStack = new LinkedList<EventQueue>();
-    private final LinkedList<AWTEvent> events = new LinkedList<AWTEvent>();
-    
-    private Toolkit toolkit;
-    private EventQueue activeQueue;
-    private Thread dispatchThread;
-    
-    AWTEvent currentEvent;
-    long mostRecentEventTime = System.currentTimeMillis();
-    
-    EventQueueCore(EventQueue eq) {
-        synchronized (this) {
-            queueStack.addLast(eq);
-            activeQueue = eq;
-        }
-    }
-
-    EventQueueCore(EventQueue eq, Toolkit t) {
-        synchronized (this) {
-            queueStack.addLast(eq);
-            activeQueue = eq;
-            setToolkit(t);
-        }
-    }
-
-    synchronized long getMostRecentEventTime() {
-        return mostRecentEventTime;
-    }
-    
-    synchronized AWTEvent getCurrentEvent() {
-        return currentEvent;
-    }
-    
-    synchronized boolean isSystemEventQueue() {
-        return toolkit != null;
-    }
-    
-    private void setToolkit(Toolkit t) {
-        toolkit = t;
-        if (toolkit != null) {
-            toolkit.setSystemEventQueueCore(this);
-            dispatchThread = toolkit.dispatchThread;
-        }
-    }
-
-    synchronized void postEvent(AWTEvent event) {
-        //???AWT
-        /*
-        events.addLast(event);
-        if ((toolkit == null) && (dispatchThread == null)) {
-            dispatchThread = new EventQueueThread(this);
-            dispatchThread.start();
-        }
-        // TODO: add event coalescing
-        if (toolkit != null) {
-            toolkit.shutdownWatchdog.setAwtQueueEmpty(false);
-            if (!GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance()) {
-                notifyEventMonitor(toolkit);
-            }
-        }
-        notifyAll();
-        */
-    }
-    
-    void notifyEventMonitor(Toolkit t) {
-        Object em = t.getNativeEventQueue().getEventMonitor();
-        synchronized (em) {
-            em.notifyAll();
-        }
-    }
-    
-    synchronized AWTEvent getNextEvent() throws InterruptedException {
-        while (events.isEmpty()) {
-            wait();
-        }
-        AWTEvent event = events.removeFirst();
-        // TODO: add event coalescing
-        return event;
-    }    
-    
-    synchronized AWTEvent peekEvent() {
-        return events.isEmpty() ? null : events.getFirst();
-    }
-    
-    synchronized AWTEvent peekEvent(int id) {
-        for (AWTEvent event : events) {
-            if (event.getID() == id) {
-                return event;
-            }
-        }
-        return null;
-    }
-    
-    synchronized void dispatchEvent(AWTEvent event) {
-        updateCurrentEventAndTime(event);
-        try {
-            activeQueue.dispatchEvent(event);
-        } finally {
-            currentEvent = null;
-        }
-    }
-    
-    void dispatchEventImpl(AWTEvent event) {
-        if (event instanceof ActiveEvent) {
-            updateCurrentEventAndTime(event);
-            try {
-                ((ActiveEvent) event).dispatch();
-            } finally {
-                currentEvent = null;
-            }
-            return;
-        }
-
-        Object src = event.getSource();
-
-        if (src instanceof Component) {
-            if (preprocessComponentEvent(event)) {
-                ((Component) src).dispatchEvent(event);
-            }
-        } else {
-            if (toolkit != null) {
-                toolkit.dispatchAWTEvent(event);
-            }
-            if (src instanceof MenuComponent) {
-                ((MenuComponent) src).dispatchEvent(event);
-            }
-        }
-    }
-
-    private final boolean preprocessComponentEvent(AWTEvent event) {
-      if (event instanceof MouseEvent) {
-          return preprocessMouseEvent((MouseEvent)event);
-      }
-      return true;
-    }
-
-    private final boolean preprocessMouseEvent(MouseEvent event) {
-        //???AWT
-        /*
-      if (toolkit != null && toolkit.mouseEventPreprocessor != null) {
-          toolkit.lockAWT();
-          try {
-              return toolkit.mouseEventPreprocessor.preprocess(event);
-          } finally {
-              toolkit.unlockAWT();
-          }
-      }
-      return true;
-        */
-        return true;
-    }
-    
-    private void updateCurrentEventAndTime(AWTEvent event) {
-        currentEvent = event;
-        long when = 0;
-        if (event instanceof ActionEvent) {
-            when = ((ActionEvent) event).getWhen();
-        } else if (event instanceof InputEvent) {
-            when = ((InputEvent) event).getWhen();
-        } else if (event instanceof InputMethodEvent) {
-            when = ((InputMethodEvent) event).getWhen();
-        } else if (event instanceof InvocationEvent) {
-            when = ((InvocationEvent) event).getWhen();
-        }
-        if (when != 0) {
-            mostRecentEventTime = when;
-        }
-    }
-    
-    synchronized void push(EventQueue newEventQueue) {
-        // TODO: handle incorrect situations
-        if (queueStack.isEmpty()) {
-            // awt.6B=Queue stack is empty
-            throw new IllegalStateException(Messages.getString("awt.6B")); //$NON-NLS-1$
-        }
-        
-        queueStack.addLast(newEventQueue);
-        activeQueue = newEventQueue;
-        activeQueue.setCore(this);
-    }
-    
-    synchronized void pop() {
-        EventQueue removed = queueStack.removeLast();
-        if (removed != activeQueue) {
-            // awt.6C=Event queue stack is broken
-            throw new IllegalStateException(Messages.getString("awt.6C")); //$NON-NLS-1$
-        }
-        activeQueue = queueStack.getLast();
-        removed.setCore(null);
-    }
-
-    synchronized AWTEvent getNextEventNoWait() {
-        try {
-            return events.isEmpty() ? null : activeQueue.getNextEvent();
-        } catch (InterruptedException e) {
-            return null;
-        }
-    }
-
-    synchronized boolean isEmpty() {
-        return (currentEvent == null) && events.isEmpty();
-    }
-    
-    synchronized boolean isEmpty(long timeout) {
-        if (!isEmpty()) {
-            return false;
-        }
-        try {
-            wait(timeout);
-        } catch (InterruptedException e) {}
-        return isEmpty();
-    }
-    
-    synchronized EventQueue getActiveEventQueue() {
-        return activeQueue;
-    }
-}
diff --git a/awt/java/awt/Font.java b/awt/java/awt/Font.java
deleted file mode 100644
index 4ed9343..0000000
--- a/awt/java/awt/Font.java
+++ /dev/null
@@ -1,1541 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.awt;
-
-import com.android.internal.awt.AndroidGraphics2D;
-
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphVector;
-import java.awt.font.LineMetrics;
-import java.awt.font.TextAttribute;
-import java.awt.font.TransformAttribute;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.BufferedInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.text.CharacterIterator;
-import java.text.AttributedCharacterIterator.Attribute;
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import org.apache.harmony.awt.gl.font.AndroidGlyphVector;
-import org.apache.harmony.awt.gl.font.CommonGlyphVector;
-import org.apache.harmony.awt.gl.font.FontPeerImpl;
-import org.apache.harmony.awt.gl.font.FontMetricsImpl;
-import org.apache.harmony.awt.gl.font.LineMetricsImpl;
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.luni.util.NotImplementedException;
-import org.apache.harmony.misc.HashCode;
-
-/**
- * The Font class represents fonts for rendering text. This class allow to map
- * characters to glyphs.
- * <p>
- * A glyph is a shape used to render a character or a sequence of characters.
- * For example one character of Latin writing system represented by one glyph,
- * but in complex writing system such as South and South-East Asian there is
- * more complicated correspondence between characters and glyphs.
- * <p>
- * The Font object is identified by two types of names. The logical font name is
- * the name that is used to construct the font. The font name is the name of a
- * particular font face (for example, Arial Bold). The family name is the font's
- * family name that specifies the typographic design across several faces (for
- * example, Arial). In all the Font is identified by three attributes: the
- * family name, the style (such as bold or italic), and the size.
- * 
- * @since Android 1.0
- */
-public class Font implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -4206021311591459213L;
-
-    // Identity Transform attribute
-    /**
-     * The Constant IDENTITY_TRANSFORM.
-     */
-    private static final TransformAttribute IDENTITY_TRANSFORM = new TransformAttribute(
-            new AffineTransform());
-
-    /**
-     * The Constant PLAIN indicates font's plain style.
-     */
-    public static final int PLAIN = 0;
-
-    /**
-     * The Constant BOLD indicates font's bold style.
-     */
-    public static final int BOLD = 1;
-
-    /**
-     * The Constant ITALIC indicates font's italic style.
-     */
-    public static final int ITALIC = 2;
-
-    /**
-     * The Constant ROMAN_BASELINE indicated roman baseline.
-     */
-    public static final int ROMAN_BASELINE = 0;
-
-    /**
-     * The Constant CENTER_BASELINE indicates center baseline.
-     */
-    public static final int CENTER_BASELINE = 1;
-
-    /**
-     * The Constant HANGING_BASELINE indicates hanging baseline.
-     */
-    public static final int HANGING_BASELINE = 2;
-
-    /**
-     * The Constant TRUETYPE_FONT indicates a font resource of type TRUETYPE.
-     */
-    public static final int TRUETYPE_FONT = 0;
-
-    /**
-     * The Constant TYPE1_FONT indicates a font resource of type TYPE1.
-     */
-    public static final int TYPE1_FONT = 1;
-
-    /**
-     * The Constant LAYOUT_LEFT_TO_RIGHT indicates that text is left to right.
-     */
-    public static final int LAYOUT_LEFT_TO_RIGHT = 0;
-
-    /**
-     * The Constant LAYOUT_RIGHT_TO_LEFT indicates that text is right to left.
-     */
-    public static final int LAYOUT_RIGHT_TO_LEFT = 1;
-
-    /**
-     * The Constant LAYOUT_NO_START_CONTEXT indicates that the text in the char
-     * array before the indicated start should not be examined.
-     */
-    public static final int LAYOUT_NO_START_CONTEXT = 2;
-
-    /**
-     * The Constant LAYOUT_NO_LIMIT_CONTEXT indicates that text in the char
-     * array after the indicated limit should not be examined.
-     */
-    public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;
-
-    /**
-     * The Constant DEFAULT_FONT.
-     */
-    static final Font DEFAULT_FONT = new Font("Dialog", Font.PLAIN, 12); //$NON-NLS-1$
-
-    /**
-     * The name of the Font.
-     */
-    protected String name;
-
-    /**
-     * The style of the Font.
-     */
-    protected int style;
-
-    /**
-     * The size of the Font.
-     */
-    protected int size;
-
-    /**
-     * The point size of the Font.
-     */
-    protected float pointSize;
-
-    // Flag if the Font object transformed
-    /**
-     * The transformed.
-     */
-    private boolean transformed;
-
-    // Set of font attributes
-    /**
-     * The requested attributes.
-     */
-    private Hashtable<Attribute, Object> fRequestedAttributes;
-
-    // font peer object corresponding to this Font
-    /**
-     * The font peer.
-     */
-    private transient FontPeerImpl fontPeer;
-
-    // number of glyphs in this Font
-    /**
-     * The num glyphs.
-     */
-    private transient int numGlyphs = -1;
-
-    // code for missing glyph for this Font
-    /**
-     * The missing glyph code.
-     */
-    private transient int missingGlyphCode = -1;
-
-    /**
-     * Writes object to ObjectOutputStream.
-     * 
-     * @param out
-     *            ObjectOutputStream.
-     * @throws IOException
-     *             Signals that an I/O exception has occurred.
-     */
-    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
-        out.defaultWriteObject();
-    }
-
-    /**
-     * Reads object from ObjectInputStream object and set native platform
-     * dependent fields to default values.
-     * 
-     * @param in
-     *            ObjectInputStream object.
-     * @throws IOException
-     *             Signals that an I/O exception has occurred.
-     * @throws ClassNotFoundException
-     *             the class not found exception.
-     */
-    private void readObject(java.io.ObjectInputStream in) throws IOException,
-            ClassNotFoundException {
-        in.defaultReadObject();
-
-        numGlyphs = -1;
-        missingGlyphCode = -1;
-
-    }
-
-    /**
-     * Instantiates a new Font with the specified attributes. The Font will be
-     * created with default attributes if the attribute's parameter is null.
-     * 
-     * @param attributes
-     *            the attributes to be assigned to the new Font, or null.
-     */
-    public Font(Map<? extends Attribute, ?> attributes) {
-        Object currAttr;
-
-        // Default values are taken from the documentation of the Font class.
-        // See Font constructor, decode and getFont sections.
-
-        this.name = "default"; //$NON-NLS-1$
-        this.size = 12;
-        this.pointSize = 12;
-        this.style = Font.PLAIN;
-
-        if (attributes != null) {
-
-            fRequestedAttributes = new Hashtable<Attribute, Object>(attributes);
-
-            currAttr = attributes.get(TextAttribute.SIZE);
-            if (currAttr != null) {
-                this.pointSize = ((Float)currAttr).floatValue();
-                this.size = (int)Math.ceil(this.pointSize);
-            }
-
-            currAttr = attributes.get(TextAttribute.POSTURE);
-            if (currAttr != null && currAttr.equals(TextAttribute.POSTURE_OBLIQUE)) {
-                this.style |= Font.ITALIC;
-            }
-
-            currAttr = attributes.get(TextAttribute.WEIGHT);
-            if ((currAttr != null)
-                    && (((Float)currAttr).floatValue() >= (TextAttribute.WEIGHT_BOLD).floatValue())) {
-                this.style |= Font.BOLD;
-            }
-
-            currAttr = attributes.get(TextAttribute.FAMILY);
-            if (currAttr != null) {
-                this.name = (String)currAttr;
-            }
-
-            currAttr = attributes.get(TextAttribute.TRANSFORM);
-            if (currAttr != null) {
-                if (currAttr instanceof TransformAttribute) {
-                    this.transformed = !((TransformAttribute)currAttr).getTransform().isIdentity();
-                } else if (currAttr instanceof AffineTransform) {
-                    this.transformed = !((AffineTransform)currAttr).isIdentity();
-                }
-            }
-
-        } else {
-            fRequestedAttributes = new Hashtable<Attribute, Object>(5);
-            fRequestedAttributes.put(TextAttribute.TRANSFORM, IDENTITY_TRANSFORM);
-
-            this.transformed = false;
-
-            fRequestedAttributes.put(TextAttribute.FAMILY, name);
-
-            fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
-
-            if ((this.style & Font.BOLD) != 0) {
-                fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
-            } else {
-                fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
-            }
-            if ((this.style & Font.ITALIC) != 0) {
-                fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
-            } else {
-                fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
-            }
-
-        }
-    }
-
-    /**
-     * Instantiates a new Font with the specified name, style and size.
-     * 
-     * @param name
-     *            the name of font.
-     * @param style
-     *            the style of font.
-     * @param size
-     *            the size of font.
-     */
-    public Font(String name, int style, int size) {
-
-        this.name = (name != null) ? name : "Default"; //$NON-NLS-1$
-        this.size = (size >= 0) ? size : 0;
-        this.style = (style & ~0x03) == 0 ? style : Font.PLAIN;
-        this.pointSize = this.size;
-
-        fRequestedAttributes = new Hashtable<Attribute, Object>(5);
-
-        fRequestedAttributes.put(TextAttribute.TRANSFORM, IDENTITY_TRANSFORM);
-
-        this.transformed = false;
-
-        fRequestedAttributes.put(TextAttribute.FAMILY, this.name);
-        fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
-
-        if ((this.style & Font.BOLD) != 0) {
-            fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
-        } else {
-            fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
-        }
-        if ((this.style & Font.ITALIC) != 0) {
-            fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
-        } else {
-            fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
-        }
-    }
-
-    /**
-     * Returns true if this Font has a glyph for the specified character.
-     * 
-     * @param c
-     *            the character.
-     * @return true if this Font has a glyph for the specified character, false
-     *         otherwise.
-     */
-    public boolean canDisplay(char c) {
-        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
-        return peer.canDisplay(c);
-    }
-
-    /**
-     * Returns true if the Font can display the characters of the the specified
-     * text from the specified start position to the specified limit position.
-     * 
-     * @param text
-     *            the text.
-     * @param start
-     *            the start offset (in the character array).
-     * @param limit
-     *            the limit offset (in the character array).
-     * @return the a character's position in the text that this Font can not
-     *         display, or -1 if this Font can display all characters in this
-     *         text.
-     */
-    public int canDisplayUpTo(char[] text, int start, int limit) {
-        int st = start;
-        int result;
-        while ((st < limit) && canDisplay(text[st])) {
-            st++;
-        }
-
-        if (st == limit) {
-            result = -1;
-        } else {
-            result = st;
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns true if the Font can display the characters of the the specified
-     * CharacterIterator from the specified start position and the specified
-     * limit position.
-     * 
-     * @param iter
-     *            the CharacterIterator.
-     * @param start
-     *            the start offset.
-     * @param limit
-     *            the limit offset.
-     * @return the a character's position in the CharacterIterator that this
-     *         Font can not display, or -1 if this Font can display all
-     *         characters in this text.
-     */
-    public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
-        int st = start;
-        char c = iter.setIndex(start);
-        int result;
-
-        while ((st < limit) && (canDisplay(c))) {
-            st++;
-            c = iter.next();
-        }
-        if (st == limit) {
-            result = -1;
-        } else {
-            result = st;
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns true if this Font can display a specified String.
-     * 
-     * @param str
-     *            the String.
-     * @return the a character's position in the String that this Font can not
-     *         display, or -1 if this Font can display all characters in this
-     *         text.
-     */
-    public int canDisplayUpTo(String str) {
-        char[] chars = str.toCharArray();
-        return canDisplayUpTo(chars, 0, chars.length);
-    }
-
-    /**
-     * Creates a GlyphVector of associating characters to glyphs based on the
-     * Unicode map of this Font.
-     * 
-     * @param frc
-     *            the FontRenderContext.
-     * @param chars
-     *            the characters array.
-     * @return the GlyphVector of associating characters to glyphs based on the
-     *         Unicode map of this Font.
-     */
-    public GlyphVector createGlyphVector(FontRenderContext frc, char[] chars) {
-        return new AndroidGlyphVector(chars, frc, this, 0);
-    }
-
-    /**
-     * Creates a GlyphVector of associating characters contained in the
-     * specified CharacterIterator to glyphs based on the Unicode map of this
-     * Font.
-     * 
-     * @param frc
-     *            the FontRenderContext.
-     * @param iter
-     *            the CharacterIterator.
-     * @return the GlyphVector of associating characters contained in the
-     *         specified CharacterIterator to glyphs based on the Unicode map of
-     *         this Font.
-     */
-    public GlyphVector createGlyphVector(FontRenderContext frc, CharacterIterator iter) {
-        throw new RuntimeException("Not implemented!"); //$NON-NLS-1$    
-    }
-
-    /**
-     * Creates a GlyphVector of associating characters to glyphs based on the
-     * Unicode map of this Font.
-     * 
-     * @param frc
-     *            the FontRenderContext.
-     * @param glyphCodes
-     *            the specified integer array of glyph codes.
-     * @return the GlyphVector of associating characters to glyphs based on the
-     *         Unicode map of this Font.
-     * @throws NotImplementedException
-     *             if this method is not implemented by a subclass.
-     */
-    public GlyphVector createGlyphVector(FontRenderContext frc, int[] glyphCodes)
-            throws org.apache.harmony.luni.util.NotImplementedException {
-        throw new RuntimeException("Not implemented!"); //$NON-NLS-1$
-    }
-
-    /**
-     * Creates a GlyphVector of associating characters to glyphs based on the
-     * Unicode map of this Font.
-     * 
-     * @param frc
-     *            the FontRenderContext.
-     * @param str
-     *            the specified String.
-     * @return the GlyphVector of associating characters to glyphs based on the
-     *         Unicode map of this Font.
-     */
-    public GlyphVector createGlyphVector(FontRenderContext frc, String str) {
-        return new AndroidGlyphVector(str.toCharArray(), frc, this, 0);
-
-    }
-
-    /**
-     * Returns the font style constant value corresponding to one of the font
-     * style names ("BOLD", "ITALIC", "BOLDITALIC"). This method returns
-     * Font.PLAIN if the argument is not one of the predefined style names.
-     * 
-     * @param fontStyleName
-     *            font style name.
-     * @return font style constant value corresponding to the font style name
-     *         specified.
-     */
-    private static int getFontStyle(String fontStyleName) {
-        int result = Font.PLAIN;
-
-        if (fontStyleName.toUpperCase().equals("BOLDITALIC")) { //$NON-NLS-1$
-            result = Font.BOLD | Font.ITALIC;
-        } else if (fontStyleName.toUpperCase().equals("BOLD")) { //$NON-NLS-1$
-            result = Font.BOLD;
-        } else if (fontStyleName.toUpperCase().equals("ITALIC")) { //$NON-NLS-1$
-            result = Font.ITALIC;
-        }
-
-        return result;
-    }
-
-    /**
-     * Decodes the specified string which described the Font. The string should
-     * have the following format: fontname-style-pointsize. The style can be
-     * PLAIN, BOLD, BOLDITALIC, or ITALIC.
-     * 
-     * @param str
-     *            the string which describes the font.
-     * @return the Font from the specified string.
-     */
-    public static Font decode(String str) {
-        // XXX: Documentation doesn't describe all cases, e.g. fonts face names
-        // with
-        // symbols that are suggested as delimiters in the documentation.
-        // In this decode implementation only ***-***-*** format is used with
-        // '-'
-        // as the delimiter to avoid unexpected parse results of font face names
-        // with spaces.
-
-        if (str == null) {
-            return DEFAULT_FONT;
-        }
-
-        StringTokenizer strTokens;
-        String delim = "-"; //$NON-NLS-1$
-        String substr;
-
-        int fontSize = DEFAULT_FONT.size;
-        int fontStyle = DEFAULT_FONT.style;
-        String fontName = DEFAULT_FONT.name;
-
-        strTokens = new StringTokenizer(str.trim(), delim);
-
-        // Font Name
-        if (strTokens.hasMoreTokens()) {
-            fontName = strTokens.nextToken(); // first token is the font name
-        }
-
-        // Font Style or Size (if the style is undefined)
-        if (strTokens.hasMoreTokens()) {
-            substr = strTokens.nextToken();
-
-            try {
-                // if second token is the font size
-                fontSize = Integer.parseInt(substr);
-            } catch (NumberFormatException e) {
-                // then second token is the font style
-                fontStyle = getFontStyle(substr);
-            }
-
-        }
-
-        // Font Size
-        if (strTokens.hasMoreTokens()) {
-            try {
-                fontSize = Integer.parseInt(strTokens.nextToken());
-            } catch (NumberFormatException e) {
-            }
-        }
-
-        return new Font(fontName, fontStyle, fontSize);
-    }
-
-    /**
-     * Performs the specified affine transform to the Font and returns a new
-     * Font.
-     * 
-     * @param trans
-     *            the AffineTransform.
-     * @return the Font object.
-     * @throws IllegalArgumentException
-     *             if affine transform parameter is null.
-     */
-    @SuppressWarnings("unchecked")
-    public Font deriveFont(AffineTransform trans) {
-
-        if (trans == null) {
-            // awt.94=transform can not be null
-            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
-        }
-
-        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
-                .clone();
-
-        derivefRequestedAttributes.put(TextAttribute.TRANSFORM, new TransformAttribute(trans));
-
-        return new Font(derivefRequestedAttributes);
-
-    }
-
-    /**
-     * Returns a new Font that is a copy of the current Font modified so that
-     * the size is the specified size.
-     * 
-     * @param size
-     *            the size of font.
-     * @return the Font object.
-     */
-    @SuppressWarnings("unchecked")
-    public Font deriveFont(float size) {
-        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
-                .clone();
-        derivefRequestedAttributes.put(TextAttribute.SIZE, new Float(size));
-        return new Font(derivefRequestedAttributes);
-    }
-
-    /**
-     * Returns a new Font that is a copy of the current Font modified so that
-     * the style is the specified style.
-     * 
-     * @param style
-     *            the style of font.
-     * @return the Font object.
-     */
-    @SuppressWarnings("unchecked")
-    public Font deriveFont(int style) {
-        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
-                .clone();
-
-        if ((style & Font.BOLD) != 0) {
-            derivefRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
-        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
-            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
-        }
-
-        if ((style & Font.ITALIC) != 0) {
-            derivefRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
-        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
-            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
-        }
-
-        return new Font(derivefRequestedAttributes);
-    }
-
-    /**
-     * Returns a new Font that is a copy of the current Font modified to match
-     * the specified style and with the specified affine transform applied to
-     * its glyphs.
-     * 
-     * @param style
-     *            the style of font.
-     * @param trans
-     *            the AffineTransform.
-     * @return the Font object.
-     */
-    @SuppressWarnings("unchecked")
-    public Font deriveFont(int style, AffineTransform trans) {
-
-        if (trans == null) {
-            // awt.94=transform can not be null
-            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
-        }
-        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
-                .clone();
-
-        if ((style & BOLD) != 0) {
-            derivefRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
-        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
-            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
-        }
-
-        if ((style & ITALIC) != 0) {
-            derivefRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
-        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
-            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
-        }
-        derivefRequestedAttributes.put(TextAttribute.TRANSFORM, new TransformAttribute(trans));
-
-        return new Font(derivefRequestedAttributes);
-    }
-
-    /**
-     * Returns a new Font that is a copy of the current Font modified so that
-     * the size and style are the specified size and style.
-     * 
-     * @param style
-     *            the style of font.
-     * @param size
-     *            the size of font.
-     * @return the Font object.
-     */
-    @SuppressWarnings("unchecked")
-    public Font deriveFont(int style, float size) {
-        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
-                .clone();
-
-        if ((style & BOLD) != 0) {
-            derivefRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
-        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
-            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
-        }
-
-        if ((style & ITALIC) != 0) {
-            derivefRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
-        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
-            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
-        }
-
-        derivefRequestedAttributes.put(TextAttribute.SIZE, new Float(size));
-        return new Font(derivefRequestedAttributes);
-
-    }
-
-    /**
-     * Returns a new Font object with a new set of font attributes.
-     * 
-     * @param attributes
-     *            the map of attributes.
-     * @return the Font.
-     */
-    @SuppressWarnings("unchecked")
-    public Font deriveFont(Map<? extends Attribute, ?> attributes) {
-        Attribute[] avalAttributes = this.getAvailableAttributes();
-
-        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
-                .clone();
-        Object currAttribute;
-        for (Attribute element : avalAttributes) {
-            currAttribute = attributes.get(element);
-            if (currAttribute != null) {
-                derivefRequestedAttributes.put(element, currAttribute);
-            }
-        }
-        return new Font(derivefRequestedAttributes);
-    }
-
-    /**
-     * Compares the specified Object with the current Font.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if the specified Object is an instance of Font with the
-     *         same family, size, and style as this Font, false otherwise.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-
-        if (obj != null) {
-            try {
-                Font font = (Font)obj;
-
-                return ((this.style == font.style) && (this.size == font.size)
-                        && this.name.equals(font.name) && (this.pointSize == font.pointSize) && (this
-                        .getTransform()).equals(font.getTransform()));
-            } catch (ClassCastException e) {
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Gets the map of font's attributes.
-     * 
-     * @return the map of font's attributes.
-     */
-    @SuppressWarnings("unchecked")
-    public Map<TextAttribute, ?> getAttributes() {
-        return (Map<TextAttribute, ?>)fRequestedAttributes.clone();
-    }
-
-    /**
-     * Gets the keys of all available attributes.
-     * 
-     * @return the keys array of all available attributes.
-     */
-    public Attribute[] getAvailableAttributes() {
-        Attribute[] attrs = {
-                TextAttribute.FAMILY, TextAttribute.POSTURE, TextAttribute.SIZE,
-                TextAttribute.TRANSFORM, TextAttribute.WEIGHT, TextAttribute.SUPERSCRIPT,
-                TextAttribute.WIDTH
-        };
-        return attrs;
-    }
-
-    /**
-     * Gets the baseline for this character.
-     * 
-     * @param c
-     *            the character.
-     * @return the baseline for this character.
-     */
-    public byte getBaselineFor(char c) {
-        // TODO: implement using TT BASE table data
-        return 0;
-    }
-
-    /**
-     * Gets the family name of the Font.
-     * 
-     * @return the family name of the Font.
-     */
-    public String getFamily() {
-        if (fRequestedAttributes != null) {
-            fRequestedAttributes.get(TextAttribute.FAMILY);
-        }
-        return null;
-    }
-
-    /**
-     * Returns the family name of this Font associated with the specified
-     * locale.
-     * 
-     * @param l
-     *            the locale.
-     * @return the family name of this Font associated with the specified
-     *         locale.
-     */
-    public String getFamily(Locale l) {
-        if (l == null) {
-            // awt.01='{0}' parameter is null
-            throw new NullPointerException(Messages.getString("awt.01", "Locale")); //$NON-NLS-1$ //$NON-NLS-2$ 
-        }
-        return getFamily();
-    }
-
-    /**
-     * Gets a Font with the specified attribute set.
-     * 
-     * @param attributes
-     *            the attributes to be assigned to the new Font.
-     * @return the Font.
-     */
-    public static Font getFont(Map<? extends Attribute, ?> attributes) {
-        Font fnt = (Font)attributes.get(TextAttribute.FONT);
-        if (fnt != null) {
-            return fnt;
-        }
-        return new Font(attributes);
-    }
-
-    /**
-     * Gets a Font object from the system properties list with the specified
-     * name or returns the specified Font if there is no such property.
-     * 
-     * @param sp
-     *            the specified property name.
-     * @param f
-     *            the Font.
-     * @return the Font object from the system properties list with the
-     *         specified name or the specified Font if there is no such
-     *         property.
-     */
-    public static Font getFont(String sp, Font f) {
-        String pr = System.getProperty(sp);
-        if (pr == null) {
-            return f;
-        }
-        return decode(pr);
-    }
-
-    /**
-     * Gets a Font object from the system properties list with the specified
-     * name.
-     * 
-     * @param sp
-     *            the system property name.
-     * @return the Font, or null if there is no such property with the specified
-     *         name.
-     */
-    public static Font getFont(String sp) {
-        return getFont(sp, null);
-    }
-
-    /**
-     * Gets the font name.
-     * 
-     * @return the font name.
-     */
-    public String getFontName() {
-        if (fRequestedAttributes != null) {
-            fRequestedAttributes.get(TextAttribute.FAMILY);
-        }
-        return null;
-    }
-
-    /**
-     * Returns the font name associated with the specified locale.
-     * 
-     * @param l
-     *            the locale.
-     * @return the font name associated with the specified locale.
-     */
-    public String getFontName(Locale l) {
-        return getFamily();
-    }
-
-    /**
-     * Returns a LineMetrics object created with the specified parameters.
-     * 
-     * @param chars
-     *            the chars array.
-     * @param start
-     *            the start offset.
-     * @param end
-     *            the end offset.
-     * @param frc
-     *            the FontRenderContext.
-     * @return the LineMetrics for the specified parameters.
-     */
-    public LineMetrics getLineMetrics(char[] chars, int start, int end, FontRenderContext frc) {
-        if (frc == null) {
-            // awt.00=FontRenderContext is null
-            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
-        }
-
-        // FontMetrics fm = AndroidGraphics2D.getInstance().getFontMetrics();
-        FontMetrics fm = new FontMetricsImpl(this);
-        float[] fmet = {
-                fm.getAscent(), fm.getDescent(), fm.getLeading()
-        };
-        return new LineMetricsImpl(chars.length, fmet, null);
-    }
-
-    /**
-     * Returns a LineMetrics object created with the specified parameters.
-     * 
-     * @param iter
-     *            the CharacterIterator.
-     * @param start
-     *            the start offset.
-     * @param end
-     *            the end offset.
-     * @param frc
-     *            the FontRenderContext.
-     * @return the LineMetrics for the specified parameters.
-     */
-    public LineMetrics getLineMetrics(CharacterIterator iter, int start, int end,
-            FontRenderContext frc) {
-
-        if (frc == null) {
-            // awt.00=FontRenderContext is null
-            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
-        }
-
-        String resultString;
-        int iterCount;
-
-        iterCount = end - start;
-        if (iterCount < 0) {
-            resultString = ""; //$NON-NLS-1$
-        } else {
-            char[] chars = new char[iterCount];
-            int i = 0;
-            for (char c = iter.setIndex(start); c != CharacterIterator.DONE && (i < iterCount); c = iter
-                    .next()) {
-                chars[i] = c;
-                i++;
-            }
-            resultString = new String(chars);
-        }
-        return this.getLineMetrics(resultString, frc);
-    }
-
-    /**
-     * Returns a LineMetrics object created with the specified parameters.
-     * 
-     * @param str
-     *            the String.
-     * @param frc
-     *            the FontRenderContext.
-     * @return the LineMetrics for the specified parameters.
-     */
-    public LineMetrics getLineMetrics(String str, FontRenderContext frc) {
-        // FontMetrics fm = AndroidGraphics2D.getInstance().getFontMetrics();
-        FontMetrics fm = new FontMetricsImpl(this);
-        float[] fmet = {
-                fm.getAscent(), fm.getDescent(), fm.getLeading()
-        };
-        // Log.i("FONT FMET", fmet.toString());
-        return new LineMetricsImpl(str.length(), fmet, null);
-
-    }
-
-    /**
-     * Returns a LineMetrics object created with the specified parameters.
-     * 
-     * @param str
-     *            the String.
-     * @param start
-     *            the start offset.
-     * @param end
-     *            the end offset.
-     * @param frc
-     *            the FontRenderContext.
-     * @return the LineMetrics for the specified parameters.
-     */
-    public LineMetrics getLineMetrics(String str, int start, int end, FontRenderContext frc) {
-        return this.getLineMetrics(str.substring(start, end), frc);
-    }
-
-    /**
-     * Gets the logical bounds of the specified String in the specified
-     * FontRenderContext. The logical bounds contains the origin, ascent,
-     * advance, and height.
-     * 
-     * @param ci
-     *            the specified CharacterIterator.
-     * @param start
-     *            the start offset.
-     * @param end
-     *            the end offset.
-     * @param frc
-     *            the FontRenderContext.
-     * @return a Rectangle2D object.
-     */
-    public Rectangle2D getStringBounds(CharacterIterator ci, int start, int end,
-            FontRenderContext frc) {
-        int first = ci.getBeginIndex();
-        int finish = ci.getEndIndex();
-        char[] chars;
-
-        if (start < first) {
-            // awt.95=Wrong start index: {0}
-            throw new IndexOutOfBoundsException(Messages.getString("awt.95", start)); //$NON-NLS-1$
-        }
-        if (end > finish) {
-            // awt.96=Wrong finish index: {0}
-            throw new IndexOutOfBoundsException(Messages.getString("awt.96", end)); //$NON-NLS-1$
-        }
-        if (start > end) {
-            // awt.97=Wrong range length: {0}
-            throw new IndexOutOfBoundsException(Messages.getString("awt.97", //$NON-NLS-1$
-                    (end - start)));
-        }
-
-        if (frc == null) {
-            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
-        }
-
-        chars = new char[end - start];
-
-        ci.setIndex(start);
-        for (int i = 0; i < chars.length; i++) {
-            chars[i] = ci.current();
-            ci.next();
-        }
-
-        return this.getStringBounds(chars, 0, chars.length, frc);
-
-    }
-
-    /**
-     * Gets the logical bounds of the specified String in the specified
-     * FontRenderContext. The logical bounds contains the origin, ascent,
-     * advance, and height.
-     * 
-     * @param str
-     *            the specified String.
-     * @param frc
-     *            the FontRenderContext.
-     * @return a Rectangle2D object.
-     */
-    public Rectangle2D getStringBounds(String str, FontRenderContext frc) {
-        char[] chars = str.toCharArray();
-        return this.getStringBounds(chars, 0, chars.length, frc);
-
-    }
-
-    /**
-     * Gets the logical bounds of the specified String in the specified
-     * FontRenderContext. The logical bounds contains the origin, ascent,
-     * advance, and height.
-     * 
-     * @param str
-     *            the specified String.
-     * @param start
-     *            the start offset.
-     * @param end
-     *            the end offset.
-     * @param frc
-     *            the FontRenderContext.
-     * @return a Rectangle2D object.
-     */
-    public Rectangle2D getStringBounds(String str, int start, int end, FontRenderContext frc) {
-
-        return this.getStringBounds((str.substring(start, end)), frc);
-    }
-
-    /**
-     * Gets the logical bounds of the specified String in the specified
-     * FontRenderContext. The logical bounds contains the origin, ascent,
-     * advance, and height.
-     * 
-     * @param chars
-     *            the specified character array.
-     * @param start
-     *            the start offset.
-     * @param end
-     *            the end offset.
-     * @param frc
-     *            the FontRenderContext.
-     * @return a Rectangle2D object.
-     */
-    public Rectangle2D getStringBounds(char[] chars, int start, int end, FontRenderContext frc) {
-        if (start < 0) {
-            // awt.95=Wrong start index: {0}
-            throw new IndexOutOfBoundsException(Messages.getString("awt.95", start)); //$NON-NLS-1$
-        }
-        if (end > chars.length) {
-            // awt.96=Wrong finish index: {0}
-            throw new IndexOutOfBoundsException(Messages.getString("awt.96", end)); //$NON-NLS-1$
-        }
-        if (start > end) {
-            // awt.97=Wrong range length: {0}
-            throw new IndexOutOfBoundsException(Messages.getString("awt.97", //$NON-NLS-1$
-                    (end - start)));
-        }
-
-        if (frc == null) {
-            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
-        }
-
-        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
-
-        final int TRANSFORM_MASK = AffineTransform.TYPE_GENERAL_ROTATION
-                | AffineTransform.TYPE_GENERAL_TRANSFORM;
-        Rectangle2D bounds;
-
-        AffineTransform transform = getTransform();
-
-        // XXX: for transforms where an angle between basis vectors is not 90
-        // degrees Rectanlge2D class doesn't fit as Logical bounds.
-        if ((transform.getType() & TRANSFORM_MASK) == 0) {
-            int width = 0;
-            for (int i = start; i < end; i++) {
-                width += peer.charWidth(chars[i]);
-            }
-            // LineMetrics nlm = peer.getLineMetrics();
-
-            LineMetrics nlm = getLineMetrics(chars, start, end, frc);
-
-            bounds = transform.createTransformedShape(
-                    new Rectangle2D.Float(0, -nlm.getAscent(), width, nlm.getHeight()))
-                    .getBounds2D();
-        } else {
-            int len = end - start;
-            char[] subChars = new char[len];
-            System.arraycopy(chars, start, subChars, 0, len);
-            bounds = createGlyphVector(frc, subChars).getLogicalBounds();
-        }
-        return bounds;
-    }
-
-    /**
-     * Gets the character's maximum bounds as defined in the specified
-     * FontRenderContext.
-     * 
-     * @param frc
-     *            the FontRenderContext.
-     * @return the character's maximum bounds.
-     */
-    public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
-        if (frc == null) {
-            // awt.00=FontRenderContext is null
-            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$ 
-        }
-
-        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
-
-        Rectangle2D bounds = peer.getMaxCharBounds(frc);
-        AffineTransform transform = getTransform();
-        // !! Documentation doesn't describe meaning of max char bounds
-        // for the fonts that have rotate transforms. For all transforms
-        // returned bounds are the bounds of transformed maxCharBounds
-        // Rectangle2D that corresponds to the font with identity transform.
-        // TODO: resolve this issue to return correct bounds
-        bounds = transform.createTransformedShape(bounds).getBounds2D();
-
-        return bounds;
-    }
-
-    /**
-     * Returns a new GlyphVector object performing full layout of the text.
-     * 
-     * @param frc
-     *            the FontRenderContext.
-     * @param chars
-     *            the character array to be layout.
-     * @param start
-     *            the start offset of the text to use for the GlyphVector.
-     * @param count
-     *            the count of characters to use for the GlyphVector.
-     * @param flags
-     *            the flag indicating text direction: LAYOUT_RIGHT_TO_LEFT,
-     *            LAYOUT_LEFT_TO_RIGHT.
-     * @return the GlyphVector.
-     */
-    public GlyphVector layoutGlyphVector(FontRenderContext frc, char[] chars, int start, int count,
-            int flags) {
-        // TODO: implement method for bidirectional text.
-        // At the moment only LTR and RTL texts supported.
-        if (start < 0) {
-            // awt.95=Wrong start index: {0}
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.95", //$NON-NLS-1$
-                    start));
-        }
-
-        if (count < 0) {
-            // awt.98=Wrong count value, can not be negative: {0}
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.98", //$NON-NLS-1$
-                    count));
-        }
-
-        if (start + count > chars.length) {
-            // awt.99=Wrong [start + count] is out of range: {0}
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.99", //$NON-NLS-1$
-                    (start + count)));
-        }
-
-        char[] out = new char[count];
-        System.arraycopy(chars, start, out, 0, count);
-
-        return new CommonGlyphVector(out, frc, this, flags);
-    }
-
-    /**
-     * Returns the String representation of this Font.
-     * 
-     * @return the String representation of this Font.
-     */
-    @Override
-    public String toString() {
-        String stl = "plain"; //$NON-NLS-1$
-        String result;
-
-        if (this.isBold() && this.isItalic()) {
-            stl = "bolditalic"; //$NON-NLS-1$
-        }
-        if (this.isBold() && !this.isItalic()) {
-            stl = "bold"; //$NON-NLS-1$
-        }
-
-        if (!this.isBold() && this.isItalic()) {
-            stl = "italic"; //$NON-NLS-1$
-        }
-
-        result = this.getClass().getName() + "[family=" + this.getFamily() + //$NON-NLS-1$
-                ",name=" + this.name + //$NON-NLS-1$
-                ",style=" + stl + //$NON-NLS-1$
-                ",size=" + this.size + "]"; //$NON-NLS-1$ //$NON-NLS-2$
-        return result;
-    }
-
-    /**
-     * Gets the postscript name of this Font.
-     * 
-     * @return the postscript name of this Font.
-     */
-    public String getPSName() {
-        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
-        return peer.getPSName();
-    }
-
-    /**
-     * Gets the logical name of this Font.
-     * 
-     * @return the logical name of this Font.
-     */
-    public String getName() {
-        return (this.name);
-    }
-
-    /**
-     * Gets the peer of this Font.
-     * 
-     * @return the peer of this Font.
-     * @deprecated Font rendering is platform independent now.
-     */
-    @Deprecated
-    public java.awt.peer.FontPeer getPeer() {
-        if (fontPeer == null) {
-            fontPeer = (FontPeerImpl)Toolkit.getDefaultToolkit().getGraphicsFactory().getFontPeer(
-                    this);
-        }
-        return fontPeer;
-
-    }
-
-    /**
-     * Gets the transform acting on this Font (from the Font's attributes).
-     * 
-     * @return the transformation of this Font.
-     */
-    public AffineTransform getTransform() {
-        Object transform = fRequestedAttributes.get(TextAttribute.TRANSFORM);
-
-        if (transform != null) {
-            if (transform instanceof TransformAttribute) {
-                return ((TransformAttribute)transform).getTransform();
-            }
-            if (transform instanceof AffineTransform) {
-                return new AffineTransform((AffineTransform)transform);
-            }
-        } else {
-            transform = new AffineTransform();
-        }
-        return (AffineTransform)transform;
-
-    }
-
-    /**
-     * Checks if this font is transformed or not.
-     * 
-     * @return true, if this font is transformed, false otherwise.
-     */
-    public boolean isTransformed() {
-        return this.transformed;
-    }
-
-    /**
-     * Checks if this font has plain style or not.
-     * 
-     * @return true, if this font has plain style, false otherwise.
-     */
-    public boolean isPlain() {
-        return (this.style == PLAIN);
-    }
-
-    /**
-     * Checks if this font has italic style or not.
-     * 
-     * @return true, if this font has italic style, false otherwise.
-     */
-    public boolean isItalic() {
-        return (this.style & ITALIC) != 0;
-    }
-
-    /**
-     * Checks if this font has bold style or not.
-     * 
-     * @return true, if this font has bold style, false otherwise.
-     */
-    public boolean isBold() {
-        return (this.style & BOLD) != 0;
-    }
-
-    /**
-     * Returns true if this Font has uniform line metrics.
-     * 
-     * @return true if this Font has uniform line metrics, false otherwise.
-     */
-    public boolean hasUniformLineMetrics() {
-        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
-        return peer.hasUniformLineMetrics();
-    }
-
-    /**
-     * Returns hash code of this Font object.
-     * 
-     * @return the hash code of this Font object.
-     */
-    @Override
-    public int hashCode() {
-        HashCode hash = new HashCode();
-
-        hash.append(this.name);
-        hash.append(this.style);
-        hash.append(this.size);
-
-        return hash.hashCode();
-    }
-
-    /**
-     * Gets the style of this Font.
-     * 
-     * @return the style of this Font.
-     */
-    public int getStyle() {
-        return this.style;
-    }
-
-    /**
-     * Gets the size of this Font.
-     * 
-     * @return the size of this Font.
-     */
-    public int getSize() {
-        return this.size;
-    }
-
-    /**
-     * Gets the number of glyphs for this Font.
-     * 
-     * @return the number of glyphs for this Font.
-     */
-    public int getNumGlyphs() {
-        if (numGlyphs == -1) {
-            FontPeerImpl peer = (FontPeerImpl)this.getPeer();
-            this.numGlyphs = peer.getNumGlyphs();
-        }
-        return this.numGlyphs;
-    }
-
-    /**
-     * Gets the glyphCode which is used as default glyph when this Font does not
-     * have a glyph for a specified Unicode.
-     * 
-     * @return the missing glyph code.
-     */
-    public int getMissingGlyphCode() {
-        if (missingGlyphCode == -1) {
-            FontPeerImpl peer = (FontPeerImpl)this.getPeer();
-            this.missingGlyphCode = peer.getMissingGlyphCode();
-        }
-        return this.missingGlyphCode;
-    }
-
-    /**
-     * Gets the float value of font's size.
-     * 
-     * @return the float value of font's size.
-     */
-    public float getSize2D() {
-        return this.pointSize;
-    }
-
-    /**
-     * Gets the italic angle of this Font.
-     * 
-     * @return the italic angle of this Font.
-     */
-    public float getItalicAngle() {
-        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
-        return peer.getItalicAngle();
-    }
-
-    /**
-     * Creates the font with the specified font format and font file.
-     * 
-     * @param fontFormat
-     *            the font format.
-     * @param fontFile
-     *            the file object represented the input data for the font.
-     * @return the Font.
-     * @throws FontFormatException
-     *             is thrown if fontFile does not contain the required font
-     *             tables for the specified format.
-     * @throws IOException
-     *             signals that an I/O exception has occurred.
-     */
-    public static Font createFont(int fontFormat, File fontFile) throws FontFormatException,
-            IOException {
-        // ???AWT not supported
-        InputStream is = new FileInputStream(fontFile);
-        try {
-            return createFont(fontFormat, is);
-        } finally {
-            is.close();
-        }
-    }
-
-    /**
-     * Creates the font with the specified font format and input stream.
-     * 
-     * @param fontFormat
-     *            the font format.
-     * @param fontStream
-     *            the input stream represented input data for the font.
-     * @return the Font.
-     * @throws FontFormatException
-     *             is thrown if fontFile does not contain the required font
-     *             tables for the specified format.
-     * @throws IOException
-     *             signals that an I/O exception has occurred.
-     */
-    public static Font createFont(int fontFormat, InputStream fontStream)
-            throws FontFormatException, IOException {
-
-        // ???AWT not supported
-
-        BufferedInputStream buffStream;
-        int bRead = 0;
-        int size = 8192;
-        // memory page size, for the faster reading
-        byte buf[] = new byte[size];
-
-        if (fontFormat != TRUETYPE_FONT) { // awt.9A=Unsupported font format
-            throw new IllegalArgumentException(Messages.getString("awt.9A")); //$NON-NLS-1$ 
-        }
-
-        /* Get font file in system-specific directory */
-
-        File fontFile = Toolkit.getDefaultToolkit().getGraphicsFactory().getFontManager()
-                .getTempFontFile();
-
-        // BEGIN android-modified
-        buffStream = new BufferedInputStream(fontStream, 8192);
-        // END android-modified
-        FileOutputStream fOutStream = new FileOutputStream(fontFile);
-
-        bRead = buffStream.read(buf, 0, size);
-
-        while (bRead != -1) {
-            fOutStream.write(buf, 0, bRead);
-            bRead = buffStream.read(buf, 0, size);
-        }
-
-        buffStream.close();
-        fOutStream.close();
-
-        Font font = null;
-
-        font = Toolkit.getDefaultToolkit().getGraphicsFactory().embedFont(
-                fontFile.getAbsolutePath());
-        if (font == null) { // awt.9B=Can't create font - bad font data
-            throw new FontFormatException(Messages.getString("awt.9B")); //$NON-NLS-1$
-        }
-        return font;
-    }
-
-}
diff --git a/awt/java/awt/FontFormatException.java b/awt/java/awt/FontFormatException.java
deleted file mode 100644
index 806711a..0000000
--- a/awt/java/awt/FontFormatException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * The FontFormatException class is used to provide notification and information
- * that font can't be created.
- * 
- * @since Android 1.0
- */
-public class FontFormatException extends Exception {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -4481290147811361272L;
-
-    /**
-     * Instantiates a new font format exception with detailed message.
-     * 
-     * @param reason
-     *            the detailed message.
-     */
-    public FontFormatException(String reason) {
-        super(reason);
-    }
-
-}
diff --git a/awt/java/awt/FontMetrics.java b/awt/java/awt/FontMetrics.java
deleted file mode 100644
index 90826265..0000000
--- a/awt/java/awt/FontMetrics.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.font.FontRenderContext;
-import java.awt.font.LineMetrics;
-import java.awt.geom.Rectangle2D;
-import java.io.Serializable;
-import java.text.CharacterIterator;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The FontMetrics class contains information about the rendering of a
- * particular font on a particular screen.
- * <p>
- * Each character in the Font has three values that help define where to place
- * it: an ascent, a descent, and an advance. The ascent is the distance the
- * character extends above the baseline. The descent is the distance the
- * character extends below the baseline. The advance width defines the position
- * at which the next character should be placed.
- * <p>
- * An array of characters or a string has an ascent, a descent, and an advance
- * width too. The ascent or descent of the array is specified by the maximum
- * ascent or descent of the characters in the array. The advance width is the
- * sum of the advance widths of each of the characters in the character array.
- * </p>
- * 
- * @since Android 1.0
- */
-public abstract class FontMetrics implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 1681126225205050147L;
-
-    /**
-     * The font from which the FontMetrics is created.
-     */
-    protected Font font;
-
-    /**
-     * Instantiates a new font metrics from the specified Font.
-     * 
-     * @param fnt
-     *            the Font.
-     */
-    protected FontMetrics(Font fnt) {
-        this.font = fnt;
-    }
-
-    /**
-     * Returns the String representation of this FontMetrics.
-     * 
-     * @return the string.
-     */
-    @Override
-    public String toString() {
-        return this.getClass().getName() + "[font=" + this.getFont() + //$NON-NLS-1$
-                "ascent=" + this.getAscent() + //$NON-NLS-1$
-                ", descent=" + this.getDescent() + //$NON-NLS-1$
-                ", height=" + this.getHeight() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    /**
-     * Gets the font associated with this FontMetrics.
-     * 
-     * @return the font associated with this FontMetrics.
-     */
-    public Font getFont() {
-        return font;
-    }
-
-    /**
-     * Gets the height of the text line in this Font.
-     * 
-     * @return the height of the text line in this Font.
-     */
-    public int getHeight() {
-        return this.getAscent() + this.getDescent() + this.getLeading();
-    }
-
-    /**
-     * Gets the font ascent of the Font associated with this FontMetrics. The
-     * font ascent is the distance from the font's baseline to the top of most
-     * alphanumeric characters.
-     * 
-     * @return the ascent of the Font associated with this FontMetrics.
-     */
-    public int getAscent() {
-        return 0;
-    }
-
-    /**
-     * Gets the font descent of the Font associated with this FontMetrics. The
-     * font descent is the distance from the font's baseline to the bottom of
-     * most alphanumeric characters with descenders.
-     * 
-     * @return the descent of the Font associated with this FontMetrics.
-     */
-    public int getDescent() {
-        return 0;
-    }
-
-    /**
-     * Gets the leading of the Font associated with this FontMetrics.
-     * 
-     * @return the leading of the Font associated with this FontMetrics.
-     */
-    public int getLeading() {
-        return 0;
-    }
-
-    /**
-     * Gets the LineMetrics object for the specified CharacterIterator in the
-     * specified Graphics.
-     * 
-     * @param ci
-     *            the CharacterIterator.
-     * @param beginIndex
-     *            the offset.
-     * @param limit
-     *            the number of characters to be used.
-     * @param context
-     *            the Graphics.
-     * @return the LineMetrics object for the specified CharacterIterator in the
-     *         specified Graphics.
-     */
-    public LineMetrics getLineMetrics(CharacterIterator ci, int beginIndex, int limit,
-            Graphics context) {
-        return font.getLineMetrics(ci, beginIndex, limit, this.getFRCFromGraphics(context));
-    }
-
-    /**
-     * Gets the LineMetrics object for the specified String in the specified
-     * Graphics.
-     * 
-     * @param str
-     *            the String.
-     * @param context
-     *            the Graphics.
-     * @return the LineMetrics object for the specified String in the specified
-     *         Graphics.
-     */
-    public LineMetrics getLineMetrics(String str, Graphics context) {
-        return font.getLineMetrics(str, this.getFRCFromGraphics(context));
-    }
-
-    /**
-     * Gets the LineMetrics object for the specified character array in the
-     * specified Graphics.
-     * 
-     * @param chars
-     *            the character array.
-     * @param beginIndex
-     *            the offset of array.
-     * @param limit
-     *            the number of characters to be used.
-     * @param context
-     *            the Graphics.
-     * @return the LineMetrics object for the specified character array in the
-     *         specified Graphics.
-     */
-    public LineMetrics getLineMetrics(char[] chars, int beginIndex, int limit, Graphics context) {
-        return font.getLineMetrics(chars, beginIndex, limit, this.getFRCFromGraphics(context));
-    }
-
-    /**
-     * Gets the LineMetrics object for the specified String in the specified
-     * Graphics.
-     * 
-     * @param str
-     *            the String.
-     * @param beginIndex
-     *            the offset.
-     * @param limit
-     *            the number of characters to be used.
-     * @param context
-     *            the Graphics.
-     * @return the LineMetrics object for the specified String in the specified
-     *         Graphics.
-     */
-    public LineMetrics getLineMetrics(String str, int beginIndex, int limit, Graphics context) {
-        return font.getLineMetrics(str, beginIndex, limit, this.getFRCFromGraphics(context));
-    }
-
-    /**
-     * Returns the character's maximum bounds in the specified Graphics context.
-     * 
-     * @param context
-     *            the Graphics context.
-     * @return the character's maximum bounds in the specified Graphics context.
-     */
-    public Rectangle2D getMaxCharBounds(Graphics context) {
-        return this.font.getMaxCharBounds(this.getFRCFromGraphics(context));
-    }
-
-    /**
-     * Gets the bounds of the specified CharacterIterator in the specified
-     * Graphics context.
-     * 
-     * @param ci
-     *            the CharacterIterator.
-     * @param beginIndex
-     *            the begin offset of the array.
-     * @param limit
-     *            the number of characters.
-     * @param context
-     *            the Graphics.
-     * @return the bounds of the specified CharacterIterator in the specified
-     *         Graphics context.
-     */
-    public Rectangle2D getStringBounds(CharacterIterator ci, int beginIndex, int limit,
-            Graphics context) {
-        return font.getStringBounds(ci, beginIndex, limit, this.getFRCFromGraphics(context));
-    }
-
-    /**
-     * Gets the bounds of the specified String in the specified Graphics
-     * context.
-     * 
-     * @param str
-     *            the String.
-     * @param beginIndex
-     *            the begin offset of the array.
-     * @param limit
-     *            the number of characters.
-     * @param context
-     *            the Graphics.
-     * @return the bounds of the specified String in the specified Graphics
-     *         context.
-     */
-    public Rectangle2D getStringBounds(String str, int beginIndex, int limit, Graphics context) {
-        return font.getStringBounds(str, beginIndex, limit, this.getFRCFromGraphics(context));
-    }
-
-    /**
-     * Gets the bounds of the specified characters array in the specified
-     * Graphics context.
-     * 
-     * @param chars
-     *            the characters array.
-     * @param beginIndex
-     *            the begin offset of the array.
-     * @param limit
-     *            the number of characters.
-     * @param context
-     *            the Graphics.
-     * @return the bounds of the specified characters array in the specified
-     *         Graphics context.
-     */
-    public Rectangle2D getStringBounds(char[] chars, int beginIndex, int limit, Graphics context) {
-        return font.getStringBounds(chars, beginIndex, limit, this.getFRCFromGraphics(context));
-    }
-
-    /**
-     * Gets the bounds of the specified String in the specified Graphics
-     * context.
-     * 
-     * @param str
-     *            the String.
-     * @param context
-     *            the Graphics.
-     * @return the bounds of the specified String in the specified Graphics
-     *         context.
-     */
-    public Rectangle2D getStringBounds(String str, Graphics context) {
-        return font.getStringBounds(str, this.getFRCFromGraphics(context));
-    }
-
-    /**
-     * Checks if the Font has uniform line metrics or not. The Font can contain
-     * characters of other fonts for covering character set. In this case the
-     * Font isn't uniform.
-     * 
-     * @return true, if the Font has uniform line metrics, false otherwise.
-     */
-    public boolean hasUniformLineMetrics() {
-        return this.font.hasUniformLineMetrics();
-    }
-
-    /**
-     * Returns the distance from the leftmost point to the rightmost point on
-     * the string's baseline showing the specified array of bytes in this Font.
-     * 
-     * @param data
-     *            the array of bytes to be measured.
-     * @param off
-     *            the start offset.
-     * @param len
-     *            the number of bytes to be measured.
-     * @return the advance width of the array.
-     */
-    public int bytesWidth(byte[] data, int off, int len) {
-        int width = 0;
-        if ((off >= data.length) || (off < 0)) {
-            // awt.13B=offset off is out of range
-            throw new IllegalArgumentException(Messages.getString("awt.13B")); //$NON-NLS-1$
-        }
-
-        if ((off + len > data.length)) {
-            // awt.13C=number of elemets len is out of range
-            throw new IllegalArgumentException(Messages.getString("awt.13C")); //$NON-NLS-1$
-        }
-
-        for (int i = off; i < off + len; i++) {
-            width += charWidth(data[i]);
-        }
-
-        return width;
-    }
-
-    /**
-     * Returns the distance from the leftmost point to the rightmost point on
-     * the string's baseline showing the specified array of characters in this
-     * Font.
-     * 
-     * @param data
-     *            the array of characters to be measured.
-     * @param off
-     *            the start offset.
-     * @param len
-     *            the number of bytes to be measured.
-     * @return the advance width of the array.
-     */
-    public int charsWidth(char[] data, int off, int len) {
-        int width = 0;
-        if ((off >= data.length) || (off < 0)) {
-            // awt.13B=offset off is out of range
-            throw new IllegalArgumentException(Messages.getString("awt.13B")); //$NON-NLS-1$
-        }
-
-        if ((off + len > data.length)) {
-            // awt.13C=number of elemets len is out of range
-            throw new IllegalArgumentException(Messages.getString("awt.13C")); //$NON-NLS-1$
-        }
-
-        for (int i = off; i < off + len; i++) {
-            width += charWidth(data[i]);
-        }
-
-        return width;
-    }
-
-    /**
-     * Returns the distance from the leftmost point to the rightmost point of
-     * the specified character in this Font.
-     * 
-     * @param ch
-     *            the specified Unicode point code of character to be measured.
-     * @return the advance width of the character.
-     */
-    public int charWidth(int ch) {
-        return 0;
-    }
-
-    /**
-     * Returns the distance from the leftmost point to the rightmost point of
-     * the specified character in this Font.
-     * 
-     * @param ch
-     *            the specified character to be measured.
-     * @return the advance width of the character.
-     */
-    public int charWidth(char ch) {
-        return 0;
-    }
-
-    /**
-     * Gets the maximum advance width of character in this Font.
-     * 
-     * @return the maximum advance width of character in this Font.
-     */
-    public int getMaxAdvance() {
-        return 0;
-    }
-
-    /**
-     * Gets the maximum font ascent of the Font associated with this
-     * FontMetrics.
-     * 
-     * @return the maximum font ascent of the Font associated with this
-     *         FontMetrics.
-     */
-    public int getMaxAscent() {
-        return 0;
-    }
-
-    /**
-     * Gets the maximum font descent of character in this Font.
-     * 
-     * @return the maximum font descent of character in this Font.
-     * @deprecated Replaced by getMaxDescent() method.
-     */
-    @Deprecated
-    public int getMaxDecent() {
-        return 0;
-    }
-
-    /**
-     * Gets the maximum font descent of character in this Font.
-     * 
-     * @return the maximum font descent of character in this Font.
-     */
-    public int getMaxDescent() {
-        return 0;
-    }
-
-    /**
-     * Gets the advance widths of the characters in the Font.
-     * 
-     * @return the advance widths of the characters in the Font.
-     */
-    public int[] getWidths() {
-        return null;
-    }
-
-    /**
-     * Returns the advance width for the specified String in this Font.
-     * 
-     * @param str
-     *            String to be measured.
-     * @return the the advance width for the specified String in this Font.
-     */
-    public int stringWidth(String str) {
-        return 0;
-    }
-
-    /**
-     * Returns a FontRenderContext instance of the Graphics context specified.
-     * 
-     * @param context
-     *            the specified Graphics context.
-     * @return a FontRenderContext of the specified Graphics context.
-     */
-    private FontRenderContext getFRCFromGraphics(Graphics context) {
-        FontRenderContext frc;
-        if (context instanceof Graphics2D) {
-            frc = ((Graphics2D)context).getFontRenderContext();
-        } else {
-            frc = new FontRenderContext(null, false, false);
-        }
-
-        return frc;
-    }
-}
diff --git a/awt/java/awt/GradientPaint.java b/awt/java/awt/GradientPaint.java
deleted file mode 100644
index 3b32ef5..0000000
--- a/awt/java/awt/GradientPaint.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.awt;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.ColorModel;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The GradientPaint class defines a way to fill a Shape with a linear color
- * gradient pattern.
- * <p>
- * The GradientPaint's fill pattern is determined by two points and two colors,
- * plus the cyclic mode option. Each of the two points is painted with its
- * corresponding color, and on the line segment connecting the two points, the
- * color is proportionally changed between the two colors. For points on the
- * same line which are not between the two specified points (outside of the
- * connecting segment) their color is determined by the cyclic mode option. If
- * the mode is cyclic, then the rest of the line repeats the color pattern of
- * the connecting segment, cycling back and forth between the two colors. If
- * not, the mode is acyclic which means that all points on the line outside the
- * connecting line segment are given the same color as the closest of the two
- * specified points.
- * <p>
- * The color of points that are not on the line connecting the two specified
- * points are given by perpendicular projection: by taking the set of lines
- * perpendicular to the connecting line and for each one, the whole line is
- * colored with the same color.
- * 
- * @since Android 1.0
- */
-public class GradientPaint implements Paint {
-
-    /**
-     * The start point color.
-     */
-    Color color1;
-
-    /**
-     * The end color point.
-     */
-    Color color2;
-
-    /**
-     * The location of the start point.
-     */
-    Point2D point1;
-
-    /**
-     * The location of the end point.
-     */
-    Point2D point2;
-
-    /**
-     * The indicator of cycle filling. If TRUE filling repeated outside points
-     * stripe, if FALSE solid color filling outside.
-     */
-    boolean cyclic;
-
-    /**
-     * Instantiates a new GradientPaint with cyclic or acyclic mode.
-     * 
-     * @param point1
-     *            the first specified point.
-     * @param color1
-     *            the Color of the first specified point.
-     * @param point2
-     *            the second specified point.
-     * @param color2
-     *            the Color of the second specified point.
-     * @param cyclic
-     *            the cyclic mode - true if the gradient pattern should cycle
-     *            repeatedly between the two colors; false otherwise.
-     */
-    public GradientPaint(Point2D point1, Color color1, Point2D point2, Color color2, boolean cyclic) {
-        if (point1 == null || point2 == null) {
-            // awt.6D=Point is null
-            throw new NullPointerException(Messages.getString("awt.6D")); //$NON-NLS-1$
-        }
-        if (color1 == null || color2 == null) {
-            // awt.6E=Color is null
-            throw new NullPointerException(Messages.getString("awt.6E")); //$NON-NLS-1$
-        }
-
-        this.point1 = point1;
-        this.point2 = point2;
-        this.color1 = color1;
-        this.color2 = color2;
-        this.cyclic = cyclic;
-    }
-
-    /**
-     * Instantiates a new GradientPaint with cyclic or acyclic mode; points are
-     * specified by coordinates.
-     * 
-     * @param x1
-     *            the X coordinate of the first point.
-     * @param y1
-     *            the Y coordinate of the first point.
-     * @param color1
-     *            the color of the first point.
-     * @param x2
-     *            the X coordinate of the second point.
-     * @param y2
-     *            the Y coordinate of the second point.
-     * @param color2
-     *            the color of the second point.
-     * @param cyclic
-     *            the cyclic mode - true if the gradient pattern should cycle
-     *            repeatedly between the two colors; false otherwise.
-     */
-    public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2,
-            boolean cyclic) {
-        this(new Point2D.Float(x1, y1), color1, new Point2D.Float(x2, y2), color2, cyclic);
-    }
-
-    /**
-     * Instantiates a new acyclic GradientPaint; points are specified by
-     * coordinates.
-     * 
-     * @param x1
-     *            the X coordinate of the first point.
-     * @param y1
-     *            the Y coordinate of the first point.
-     * @param color1
-     *            the color of the first point.
-     * @param x2
-     *            the X coordinate of the second point.
-     * @param y2
-     *            the Y coordinate of the second point.
-     * @param color2
-     *            the color of the second point.
-     */
-    public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2) {
-        this(x1, y1, color1, x2, y2, color2, false);
-    }
-
-    /**
-     * Instantiates a new acyclic GradientPaint.
-     * 
-     * @param point1
-     *            the first specified point.
-     * @param color1
-     *            the Color of the first specified point.
-     * @param point2
-     *            the second specified point.
-     * @param color2
-     *            the Color of the second specified point.
-     */
-    public GradientPaint(Point2D point1, Color color1, Point2D point2, Color color2) {
-        this(point1, color1, point2, color2, false);
-    }
-
-    /**
-     * Creates PaintContext for a color pattern generating.
-     * 
-     * @param cm
-     *            the ColorModel of the Paint data.
-     * @param deviceBounds
-     *            the bounding Rectangle of graphics primitives being rendered
-     *            in the device space.
-     * @param userBounds
-     *            the bounding Rectangle of graphics primitives being rendered
-     *            in the user space.
-     * @param t
-     *            the AffineTransform from user space into device space.
-     * @param hints
-     *            the RrenderingHints object.
-     * @return the PaintContext for color pattern generating.
-     * @see java.awt.Paint#createContext(java.awt.image.ColorModel,
-     *      java.awt.Rectangle, java.awt.geom.Rectangle2D,
-     *      java.awt.geom.AffineTransform, java.awt.RenderingHints)
-     */
-    public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
-            Rectangle2D userBounds, AffineTransform t, RenderingHints hints) {
-        return new GradientPaintContext(cm, t, point1, color1, point2, color2, cyclic);
-    }
-
-    /**
-     * Gets the color of the first point.
-     * 
-     * @return the color of the first point.
-     */
-    public Color getColor1() {
-        return color1;
-    }
-
-    /**
-     * Gets the color of the second point.
-     * 
-     * @return the color of the second point.
-     */
-    public Color getColor2() {
-        return color2;
-    }
-
-    /**
-     * Gets the first point.
-     * 
-     * @return the Point object - the first point.
-     */
-    public Point2D getPoint1() {
-        return point1;
-    }
-
-    /**
-     * Gets the second point.
-     * 
-     * @return the Point object - the second point.
-     */
-    public Point2D getPoint2() {
-        return point2;
-    }
-
-    /**
-     * Gets the transparency mode for the GradientPaint.
-     * 
-     * @return the transparency mode for the GradientPaint.
-     * @see java.awt.Transparency#getTransparency()
-     */
-    public int getTransparency() {
-        int a1 = color1.getAlpha();
-        int a2 = color2.getAlpha();
-        return (a1 == 0xFF && a2 == 0xFF) ? OPAQUE : TRANSLUCENT;
-    }
-
-    /**
-     * Returns the GradientPaint mode: true for cyclic mode, false for acyclic
-     * mode.
-     * 
-     * @return true if the gradient cycles repeatedly between the two colors;
-     *         false otherwise.
-     */
-    public boolean isCyclic() {
-        return cyclic;
-    }
-}
diff --git a/awt/java/awt/GradientPaintContext.java b/awt/java/awt/GradientPaintContext.java
deleted file mode 100644
index 74575f5..0000000
--- a/awt/java/awt/GradientPaintContext.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-package java.awt;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBufferInt;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-
-class GradientPaintContext implements PaintContext {
-
-    /**
-     * The size of noncyclic part of color lookup table
-     */
-    static int LOOKUP_SIZE = 256;
-    
-    /**
-     * The index mask to lookup color in the table
-     */
-    static int LOOKUP_MASK = 0x1FF;
-    
-    /**
-     * The min value equivalent to zero. If absolute value less then ZERO it considered as zero.  
-     */
-    static double ZERO = 1E-10;
-
-    /**
-     * The ColorModel user defined for PaintContext
-     */
-    ColorModel cm;
-    
-    /**
-     * The indicator of cycle filling.
-     */
-    boolean cyclic;
-    
-    /**
-     * The integer color value of the start point
-     */
-    int c1;
-    
-    /**
-     * The integer color value of the end point
-     */
-    int c2;
-    
-    /**
-     * The lookup gradient color table 
-     */
-    int[] table;
-
-    /**
-     * The tempopary pre-calculated value to evalutae color index 
-     */
-    int dx;
-    
-    /**
-     * The tempopary pre-calculated value to evalutae color index 
-     */
-    int dy;
-    
-    /**
-     * The tempopary pre-calculated value to evalutae color index 
-     */
-    int delta;
-    
-    /**
-     * Constructs a new GradientPaintcontext
-     * @param cm - not used
-     * @param t - the fill transformation
-     * @param point1 - the start fill point
-     * @param color1 - color of the start point 
-     * @param point2 - the end fill point
-     * @param color2 - color of the end point
-     * @param cyclic - the indicator of cycle filling
-     */
-    GradientPaintContext(ColorModel cm, AffineTransform t, Point2D point1, Color color1, Point2D point2, Color color2, boolean cyclic) {
-        this.cyclic = cyclic;
-        this.cm = ColorModel.getRGBdefault();
-
-        c1 = color1.getRGB();
-        c2 = color2.getRGB();
-
-        double px = point2.getX() - point1.getX();
-        double py = point2.getY() - point1.getY();
-
-        Point2D p = t.transform(point1, null);
-        Point2D bx = new Point2D.Double(px, py);
-        Point2D by = new Point2D.Double(py, -px);
-
-        t.deltaTransform(bx, bx);
-        t.deltaTransform(by, by);
-
-        double vec = bx.getX() * by.getY() - bx.getY() * by.getX();
-
-        if (Math.abs(vec) < ZERO) {
-            dx = dy = delta = 0;
-            table = new int[1];
-            table[0] = c1;
-        } else {
-            double mult = LOOKUP_SIZE * 256 / vec;
-            dx = (int)(by.getX() * mult);
-            dy = (int)(by.getY() * mult);
-            delta = (int)((p.getX() * by.getY() - p.getY() * by.getX()) * mult);
-            createTable();
-        }
-    }
-
-    /**
-     * Create color index lookup table. Calculate 256 step trasformation from 
-     * the start point color to the end point color. Colors multiplied by 256 to do integer calculations. 
-     */
-    void createTable() {
-        double ca = (c1 >> 24) & 0xFF;
-        double cr = (c1 >> 16) & 0xFF;
-        double cg = (c1 >> 8) & 0xFF;
-        double cb = c1 & 0xFF;
-
-        double k = 1.0 / LOOKUP_SIZE;
-        double da = (((c2 >> 24) & 0xFF) - ca) * k;
-        double dr = (((c2 >> 16) & 0xFF) - cr) * k;
-        double dg = (((c2 >> 8) & 0xFF) - cg) * k;
-        double db = ((c2 & 0xFF) - cb) * k;
-
-        table = new int[cyclic ? LOOKUP_SIZE + LOOKUP_SIZE : LOOKUP_SIZE];
-        for(int i = 0; i < LOOKUP_SIZE; i++) {
-            table[i] =
-                (int)ca << 24 |
-                (int)cr << 16 |
-                (int)cg << 8 |
-                (int)cb;
-            ca += da;
-            cr += dr;
-            cg += dg;
-            cb += db;
-        }
-        if (cyclic) {
-            for(int i = 0; i < LOOKUP_SIZE; i++) {
-                table[LOOKUP_SIZE + LOOKUP_SIZE - 1 - i] = table[i];
-            }
-        }
-    }
-
-    public ColorModel getColorModel() {
-        return cm;
-    }
-
-    public void dispose() {
-    }
-
-    public Raster getRaster(int x, int y, int w, int h) {
-        WritableRaster rast = cm.createCompatibleWritableRaster(w, h);
-
-        int[] buf = ((DataBufferInt)rast.getDataBuffer()).getData();
-
-        int c = x * dy - y * dx - delta;
-        int cx = dy;
-        int cy = - w * dy - dx;
-        int k = 0;
-
-        if (cyclic) {
-            for(int j = 0; j < h; j++) {
-                for(int i = 0; i < w; i++) {
-                    buf[k++] = table[(c >> 8) & LOOKUP_MASK];
-                    c += cx;
-                }
-                c += cy;
-            }
-        } else {
-            for(int j = 0; j < h; j++) {
-                for(int i = 0; i < w; i++) {
-                    int index = c >> 8;
-                    buf[k++] = index < 0 ? c1 : index >= LOOKUP_SIZE ? c2 : table[index];
-                    c += cx;
-                }
-                c += cy;
-            }
-        }
-
-        return rast;
-    }
-
-}
-
diff --git a/awt/java/awt/Graphics.java b/awt/java/awt/Graphics.java
deleted file mode 100644
index 2d6e79f..0000000
--- a/awt/java/awt/Graphics.java
+++ /dev/null
@@ -1,924 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.image.ImageObserver;
-import java.text.AttributedCharacterIterator;
-
-/**
- * The abstract Graphics class allows applications to draw on a screen or other
- * rendering target. There are several properties which define rendering
- * options: origin point, clipping area, color, font. <br>
- * <br>
- * The origin point specifies the beginning of the clipping area coordinate
- * system. All coordinates used in rendering operations are computed with
- * respect to this point. The clipping area defines the boundaries where
- * rendering operations can be performed. Rendering operations can't modify
- * pixels outside of the clipping area. <br>
- * <br>
- * The draw and fill methods allow applications to drawing shapes, text, images
- * with specified font and color options in the specified part of the screen.
- * 
- * @since Android 1.0
- */
-public abstract class Graphics {
-
-    // Constructors
-
-    /**
-     * Instantiates a new Graphics. This constructor is default for Graphics and
-     * can not be called directly.
-     */
-    protected Graphics() {
-    }
-
-    // Public methods
-
-    /**
-     * Creates a copy of the Graphics object with a new origin and a new
-     * specified clip area. The new clip area is the rectangle defined by the
-     * origin point with coordinates X,Y and the given width and height. The
-     * coordinates of all subsequent rendering operations will be computed with
-     * respect to the new origin and can be performed only within the range of
-     * the clipping area dimensions.
-     * 
-     * @param x
-     *            the X coordinate of the original point.
-     * @param y
-     *            the Y coordinate of the original point.
-     * @param width
-     *            the width of clipping area.
-     * @param height
-     *            the height of clipping area.
-     * @return the Graphics object with new origin point and clipping area.
-     */
-    public Graphics create(int x, int y, int width, int height) {
-        Graphics res = create();
-        res.translate(x, y);
-        res.clipRect(0, 0, width, height);
-        return res;
-    }
-
-    /**
-     * Draws the highlighted outline of a rectangle.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle's top left corner.
-     * @param y
-     *            the Y coordinate of the rectangle's top left corner.
-     * @param width
-     *            the width of rectangle.
-     * @param height
-     *            the height of rectangle.
-     * @param raised
-     *            a boolean value that determines whether the rectangle is drawn
-     *            as raised or indented.
-     */
-    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
-        // Note: lighter/darker colors should be used to draw 3d rect.
-        // The resulting rect is (width+1)x(height+1). Stroke and paint
-        // attributes of
-        // the Graphics2D should be reset to the default values.
-        // fillRect is used instead of drawLine to bypass stroke
-        // reset/set and rasterization.
-
-        Color color = getColor();
-        Color colorUp, colorDown;
-        if (raised) {
-            colorUp = color.brighter();
-            colorDown = color.darker();
-        } else {
-            colorUp = color.darker();
-            colorDown = color.brighter();
-        }
-
-        setColor(colorUp);
-        fillRect(x, y, width, 1);
-        fillRect(x, y + 1, 1, height);
-
-        setColor(colorDown);
-        fillRect(x + width, y, 1, height);
-        fillRect(x + 1, y + height, width, 1);
-    }
-
-    /**
-     * Draws the text represented by byte array. This method uses the current
-     * font and color for rendering.
-     * 
-     * @param bytes
-     *            the byte array which contains the text to be drawn.
-     * @param off
-     *            the offset within the byte array of the text to be drawn.
-     * @param len
-     *            the number of bytes of text to draw.
-     * @param x
-     *            the X coordinate where the text is to be drawn.
-     * @param y
-     *            the Y coordinate where the text is to be drawn.
-     */
-    public void drawBytes(byte[] bytes, int off, int len, int x, int y) {
-        drawString(new String(bytes, off, len), x, y);
-    }
-
-    /**
-     * Draws the text represented by character array. This method uses the
-     * current font and color for rendering.
-     * 
-     * @param chars
-     *            the character array.
-     * @param off
-     *            the offset within the character array of the text to be drawn.
-     * @param len
-     *            the number of characters which will be drawn.
-     * @param x
-     *            the X coordinate where the text is to be drawn.
-     * @param y
-     *            the Y coordinate where the text is to be drawn.
-     */
-    public void drawChars(char[] chars, int off, int len, int x, int y) {
-        drawString(new String(chars, off, len), x, y);
-    }
-
-    /**
-     * Draws the outline of a polygon which is defined by Polygon object.
-     * 
-     * @param p
-     *            the Polygon object.
-     */
-    public void drawPolygon(Polygon p) {
-        drawPolygon(p.xpoints, p.ypoints, p.npoints);
-    }
-
-    /**
-     * Draws the rectangle with the specified width and length and top left
-     * corner coordinates.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle's top left corner.
-     * @param y
-     *            the Y coordinate of the rectangle's top left corner.
-     * @param width
-     *            the width of the rectangle.
-     * @param height
-     *            the height of the rectangle.
-     */
-    public void drawRect(int x, int y, int width, int height) {
-        int[] xpoints = {
-                x, x, x + width, x + width
-        };
-        int[] ypoints = {
-                y, y + height, y + height, y
-        };
-
-        drawPolygon(xpoints, ypoints, 4);
-    }
-
-    /**
-     * Fills the highlighted outline of a rectangle.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle's top left corner.
-     * @param y
-     *            the Y coordinate of the rectangle's top left corner.
-     * @param width
-     *            the width of the rectangle.
-     * @param height
-     *            the height of the rectangle.
-     * @param raised
-     *            a boolean value that determines whether the rectangle is drawn
-     *            as raised or indented.
-     */
-    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
-        // Note: lighter/darker colors should be used to draw 3d rect.
-        // The resulting rect is (width)x(height), same as fillRect.
-        // Stroke and paint attributes of the Graphics2D should be reset
-        // to the default values. fillRect is used instead of drawLine to
-        // bypass stroke reset/set and line rasterization.
-
-        Color color = getColor();
-        Color colorUp, colorDown;
-        if (raised) {
-            colorUp = color.brighter();
-            colorDown = color.darker();
-            setColor(color);
-        } else {
-            colorUp = color.darker();
-            colorDown = color.brighter();
-            setColor(colorUp);
-        }
-
-        width--;
-        height--;
-        fillRect(x + 1, y + 1, width - 1, height - 1);
-
-        setColor(colorUp);
-        fillRect(x, y, width, 1);
-        fillRect(x, y + 1, 1, height);
-
-        setColor(colorDown);
-        fillRect(x + width, y, 1, height);
-        fillRect(x + 1, y + height, width, 1);
-    }
-
-    /**
-     * Fills the polygon with the current color.
-     * 
-     * @param p
-     *            the Polygon object.
-     */
-    public void fillPolygon(Polygon p) {
-        fillPolygon(p.xpoints, p.ypoints, p.npoints);
-    }
-
-    /**
-     * Disposes of the Graphics.
-     */
-    @Override
-    public void finalize() {
-    }
-
-    /**
-     * Gets the bounds of the current clipping area as a rectangle and copies it
-     * to an existing rectangle.
-     * 
-     * @param r
-     *            a Rectangle object where the current clipping area bounds are
-     *            to be copied.
-     * @return the bounds of the current clipping area.
-     */
-    public Rectangle getClipBounds(Rectangle r) {
-        Shape clip = getClip();
-
-        if (clip != null) {
-            // TODO: Can we get shape bounds without creating Rectangle object?
-            Rectangle b = clip.getBounds();
-            r.x = b.x;
-            r.y = b.y;
-            r.width = b.width;
-            r.height = b.height;
-        }
-
-        return r;
-    }
-
-    /**
-     * Gets the bounds of the current clipping area as a rectangle.
-     * 
-     * @return a Rectangle object.
-     * @deprecated Use {@link #getClipBounds()}
-     */
-    @Deprecated
-    public Rectangle getClipRect() {
-        return getClipBounds();
-    }
-
-    /**
-     * Gets the font metrics of the current font. The font metrics object
-     * contains information about the rendering of a particular font.
-     * 
-     * @return the font metrics of current font.
-     */
-    public FontMetrics getFontMetrics() {
-        return getFontMetrics(getFont());
-    }
-
-    /**
-     * Determines whether or not the specified rectangle intersects the current
-     * clipping area.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle.
-     * @param y
-     *            the Y coordinate of the rectangle.
-     * @param width
-     *            the width of the rectangle.
-     * @param height
-     *            the height of the rectangle.
-     * @return true, if the specified rectangle intersects the current clipping
-     *         area, false otherwise.
-     */
-    public boolean hitClip(int x, int y, int width, int height) {
-        // TODO: Create package private method Rectangle.intersects(int, int,
-        // int, int);
-        return getClipBounds().intersects(new Rectangle(x, y, width, height));
-    }
-
-    /**
-     * Returns string which represents this Graphics object.
-     * 
-     * @return the string which represents this Graphics object.
-     */
-    @Override
-    public String toString() {
-        // TODO: Think about string representation of Graphics.
-        return "Graphics"; //$NON-NLS-1$
-    }
-
-    // Abstract methods
-
-    /**
-     * Clears the specified rectangle. This method fills specified rectangle
-     * with background color.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle.
-     * @param y
-     *            the Y coordinate of the rectangle.
-     * @param width
-     *            the width of the rectangle.
-     * @param height
-     *            the height of the rectangle.
-     */
-    public abstract void clearRect(int x, int y, int width, int height);
-
-    /**
-     * Intersects the current clipping area with a new rectangle. If the current
-     * clipping area is not defined, the rectangle becomes a new clipping area.
-     * Rendering operations are only allowed within the new the clipping area.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle for intersection.
-     * @param y
-     *            the Y coordinate of the rectangle for intersection.
-     * @param width
-     *            the width of the rectangle for intersection.
-     * @param height
-     *            the height of the rectangle for intersection.
-     */
-    public abstract void clipRect(int x, int y, int width, int height);
-
-    /**
-     * Copies the rectangle area to another area specified by a distance (dx,
-     * dy) from the original rectangle's location. Positive dx and dy values
-     * give a new location defined by translation to the right and down from the
-     * original location, negative dx and dy values - to the left and up.
-     * 
-     * @param sx
-     *            the X coordinate of the rectangle which will be copied.
-     * @param sy
-     *            the Y coordinate of the rectangle which will be copied.
-     * @param width
-     *            the width of the rectangle which will be copied.
-     * @param height
-     *            the height of the rectangle which will be copied.
-     * @param dx
-     *            the horizontal distance from the source rectangle's location
-     *            to the copy's location.
-     * @param dy
-     *            the vertical distance from the source rectangle's location to
-     *            the copy's location.
-     */
-    public abstract void copyArea(int sx, int sy, int width, int height, int dx, int dy);
-
-    /**
-     * Creates a new copy of this Graphics.
-     * 
-     * @return a new Graphics context which is a copy of this Graphics.
-     */
-    public abstract Graphics create();
-
-    /**
-     * Disposes of the Graphics. This Graphics object can not be used after
-     * calling this method.
-     */
-    public abstract void dispose();
-
-    /**
-     * Draws the arc covering the specified rectangle and using the current
-     * color. The rectangle is defined by the origin point (X, Y) and dimensions
-     * (width and height). The arc center is the the center of specified
-     * rectangle. The angle origin is 3 o'clock position, the positive angle is
-     * counted as a counter-clockwise rotation, the negative angle is counted as
-     * clockwise rotation.
-     * 
-     * @param x
-     *            the X origin coordinate of the rectangle which scales the arc.
-     * @param y
-     *            the Y origin coordinate of the rectangle which scales the arc.
-     * @param width
-     *            the width of the rectangle which scales the arc.
-     * @param height
-     *            the height of the rectangle which scales the arc.
-     * @param sa
-     *            start angle - the origin angle of arc.
-     * @param ea
-     *            arc angle - the angular arc value relative to the start angle.
-     */
-    public abstract void drawArc(int x, int y, int width, int height, int sa, int ea);
-
-    /**
-     * Draws the specified image with the defined background color. The top left
-     * corner of image will be drawn at point (x, y) in current coordinate
-     * system. The image loading process notifies the specified Image Observer.
-     * This method returns true if the image has loaded, otherwise it returns
-     * false.
-     * 
-     * @param img
-     *            the image which will be drawn.
-     * @param x
-     *            the X coordinate of the image top left corner.
-     * @param y
-     *            the Y coordinate of the image top left corner.
-     * @param bgcolor
-     *            the background color.
-     * @param observer
-     *            the ImageObserver object which should be notified about image
-     *            loading process.
-     * @return true, if loading image is successful or image is null, false
-     *         otherwise.
-     */
-    public abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer);
-
-    /**
-     * Draws the specified image. The top left corner of image will be drawn at
-     * point (x, y) in current coordinate system. The image loading process
-     * notifies the specified Image Observer. This method returns true if the
-     * image has loaded, otherwise it returns false.
-     * 
-     * @param img
-     *            the image which will be drawn.
-     * @param x
-     *            the X coordinate of the image top left corner.
-     * @param y
-     *            the Y coordinate of the image top left corner.
-     * @param observer
-     *            the ImageObserver object which should be notified about image
-     *            loading process.
-     * @return true, if loading image is successful or image is null, otherwise
-     *         false.
-     */
-    public abstract boolean drawImage(Image img, int x, int y, ImageObserver observer);
-
-    /**
-     * Scales the specified image to fit in the specified rectangle and draws it
-     * with the defined background color. The top left corner of the image will
-     * be drawn at the point (x, y) in current coordinate system. The non-opaque
-     * pixels will be drawn in the background color. The image loading process
-     * notifies the specified Image Observer. This method returns true if the
-     * image has loaded, otherwise it returns false.
-     * 
-     * @param img
-     *            the image which will be drawn.
-     * @param x
-     *            the X coordinate of the image's top left corner.
-     * @param y
-     *            the Y coordinate of the image's top left corner.
-     * @param width
-     *            the width of rectangle which scales the image.
-     * @param height
-     *            the height of rectangle which scales the image.
-     * @param bgcolor
-     *            the background color.
-     * @param observer
-     *            the ImageObserver object which should be notified about image
-     *            loading process.
-     * @return true, if loading image is successful or image is null, otherwise
-     *         false.
-     */
-    public abstract boolean drawImage(Image img, int x, int y, int width, int height,
-            Color bgcolor, ImageObserver observer);
-
-    /**
-     * Scales the specified image to fit in the specified rectangle and draws
-     * it. The top left corner of the image will be drawn at the point (x, y) in
-     * current coordinate system. The image loading process notifies the
-     * specified Image Observer. This method returns true if the image has
-     * loaded, otherwise it returns false.
-     * 
-     * @param img
-     *            the image which will be drawn.
-     * @param x
-     *            the X coordinate of the image top left corner.
-     * @param y
-     *            the Y coordinate of the image top left corner.
-     * @param width
-     *            the width of rectangle which scales the image.
-     * @param height
-     *            the height of rectangle which scales the image.
-     * @param observer
-     *            the ImageObserver object which should be notified about image
-     *            loading process.
-     * @return true, if loading image is successful or image is null, otherwise
-     *         false.
-     */
-    public abstract boolean drawImage(Image img, int x, int y, int width, int height,
-            ImageObserver observer);
-
-    /**
-     * Scales the specified area of the specified image to fit in the rectangle
-     * area defined by its corners coordinates and draws the sub-image with the
-     * specified background color. The sub-image to be drawn is defined by its
-     * top left corner coordinates (sx1, sy1) and bottom right corner
-     * coordinates (sx2, sy2) computed with respect to the origin (top left
-     * corner) of the source image. The non opaque pixels will be drawn in the
-     * background color. The image loading process notifies specified Image
-     * Observer. This method returns true if the image has loaded, otherwise it
-     * returns false.
-     * 
-     * @param img
-     *            the image which will be drawn.
-     * @param dx1
-     *            the X top left corner coordinate of the destination rectangle
-     *            area.
-     * @param dy1
-     *            the Y top left corner coordinate of the destination rectangle
-     *            area.
-     * @param dx2
-     *            the X bottom right corner coordinate of the destination
-     *            rectangle area.
-     * @param dy2
-     *            the Y bottom right corner coordinate of the destination
-     *            rectangle area.
-     * @param sx1
-     *            the X top left corner coordinate of the area to be drawn
-     *            within the source image.
-     * @param sy1
-     *            the Y top left corner coordinate of the area to be drawn
-     *            within the source image.
-     * @param sx2
-     *            the X bottom right corner coordinate of the area to be drawn
-     *            within the source image.
-     * @param sy2
-     *            the Y bottom right corner coordinate of the area to be drawn
-     *            within the source image.
-     * @param bgcolor
-     *            the background color.
-     * @param observer
-     *            the ImageObserver object which should be notified about image
-     *            loading process.
-     * @return true, if loading image is successful or image is null, false
-     *         otherwise.
-     */
-    public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1,
-            int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer);
-
-    /**
-     * Scales the specified area of the specified image to fit in the rectangle
-     * area defined by its corners coordinates and draws the sub-image. The
-     * sub-image to be drawn is defined by its top left corner coordinates (sx1,
-     * sy1) and bottom right corner coordinates (sx2, sy2) computed with respect
-     * to the origin (top left corner) of the source image. The image loading
-     * process notifies specified Image Observer. This method returns true if
-     * the image has loaded, otherwise it returns false.
-     * 
-     * @param img
-     *            the image which will be drawn.
-     * @param dx1
-     *            the X top left corner coordinate of the destination rectangle
-     *            area.
-     * @param dy1
-     *            the Y top left corner coordinate of the destination rectangle
-     *            area.
-     * @param dx2
-     *            the X bottom right corner coordinate of the destination
-     *            rectangle area.
-     * @param dy2
-     *            the Y bottom right corner coordinate of the destination
-     *            rectangle area.
-     * @param sx1
-     *            the X top left corner coordinate of the area to be drawn
-     *            within the source image.
-     * @param sy1
-     *            the Y top left corner coordinate of the area to be drawn
-     *            within the source image.
-     * @param sx2
-     *            the X bottom right corner coordinate of the area to be drawn
-     *            within the source image.
-     * @param sy2
-     *            the Y bottom right corner coordinate of the area to be drawn
-     *            within the source image.
-     * @param observer
-     *            the ImageObserver object which should be notified about image
-     *            loading process.
-     * @return true, if loading image is successful or image is null, false
-     *         otherwise.
-     */
-    public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1,
-            int sy1, int sx2, int sy2, ImageObserver observer);
-
-    /**
-     * Draws a line from the point (x1, y1) to the point (x2, y2). This method
-     * draws the line with current color which can be changed by setColor(Color
-     * c) method.
-     * 
-     * @param x1
-     *            the X coordinate of the first point.
-     * @param y1
-     *            the Y coordinate of the first point.
-     * @param x2
-     *            the X coordinate of the second point.
-     * @param y2
-     *            the Y coordinate of the second point.
-     */
-    public abstract void drawLine(int x1, int y1, int x2, int y2);
-
-    /**
-     * Draws the outline of an oval to fit in the rectangle defined by the given
-     * width, height, and top left corner.
-     * 
-     * @param x
-     *            the X top left corner oval coordinate.
-     * @param y
-     *            the Y top left corner oval coordinate.
-     * @param width
-     *            the oval width.
-     * @param height
-     *            the oval height.
-     */
-    public abstract void drawOval(int x, int y, int width, int height);
-
-    /**
-     * Draws the outline of a polygon. The polygon vertices are defined by
-     * points with xpoints[i], ypoints[i] as coordinates. The polygon edges are
-     * the lines from the points with (xpoints[i-1], ypoints[i-1]) coordinates
-     * to the points with (xpoints[i], ypoints[i]) coordinates, for 0 < i <
-     * npoints +1.
-     * 
-     * @param xpoints
-     *            the array of X coordinates of the polygon vertices.
-     * @param ypoints
-     *            the array of Y coordinates of the polygon vertices.
-     * @param npoints
-     *            the number of polygon vertices/points.
-     */
-    public abstract void drawPolygon(int[] xpoints, int[] ypoints, int npoints);
-
-    /**
-     * Draws a set of connected lines which are defined by the x and y
-     * coordinate arrays. The polyline is closed if coordinates of the first
-     * point are the same as coordinates of the last point.
-     * 
-     * @param xpoints
-     *            the array of X point coordinates.
-     * @param ypoints
-     *            the array of Y point coordinates.
-     * @param npoints
-     *            the number of points.
-     */
-    public abstract void drawPolyline(int[] xpoints, int[] ypoints, int npoints);
-
-    /**
-     * Draws the outline of a rectangle with round corners.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle's top left corner.
-     * @param y
-     *            the Y coordinate of the rectangle's top left corner.
-     * @param width
-     *            the width of the rectangle.
-     * @param height
-     *            the height of the rectangle.
-     * @param arcWidth
-     *            the arc width for the corners.
-     * @param arcHeight
-     *            the arc height for the corners.
-     */
-    public abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth,
-            int arcHeight);
-
-    /**
-     * Draws a text defined by an iterator. The iterator should specify the font
-     * for every character.
-     * 
-     * @param iterator
-     *            the iterator.
-     * @param x
-     *            the X coordinate of the first character.
-     * @param y
-     *            the Y coordinate of the first character.
-     */
-    public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);
-
-    /**
-     * Draws a text defined by a string. This method draws the text with current
-     * font and color.
-     * 
-     * @param str
-     *            the string.
-     * @param x
-     *            the X coordinate of the first character.
-     * @param y
-     *            the Y coordinate of the first character.
-     */
-    public abstract void drawString(String str, int x, int y);
-
-    /**
-     * Fills the arc covering the rectangle and using the current color. The
-     * rectangle is defined by the origin point (X, Y) and dimensions (width and
-     * height). The arc center is the the center of specified rectangle. The
-     * angle origin is at the 3 o'clock position, and a positive angle gives
-     * counter-clockwise rotation, a negative angle gives clockwise rotation.
-     * 
-     * @param x
-     *            the X origin coordinate of the rectangle which scales the arc.
-     * @param y
-     *            the Y origin coordinate of the rectangle which scales the arc.
-     * @param width
-     *            the width of the rectangle which scales the arc.
-     * @param height
-     *            the height of the rectangle which scales the arc.
-     * @param sa
-     *            start angle - the origin angle of arc.
-     * @param ea
-     *            arc angle - the angular arc value relative to the start angle.
-     */
-    public abstract void fillArc(int x, int y, int width, int height, int sa, int ea);
-
-    /**
-     * Fills an oval with the current color where the oval is defined by the
-     * bounding rectangle with the given width, height, and top left corner.
-     * 
-     * @param x
-     *            the X top left corner oval coordinate.
-     * @param y
-     *            the Y top left corner oval coordinate.
-     * @param width
-     *            the oval width.
-     * @param height
-     *            the oval height.
-     */
-    public abstract void fillOval(int x, int y, int width, int height);
-
-    /**
-     * Fills a polygon with the current color. The polygon vertices are defined
-     * by the points with xpoints[i], ypoints[i] as coordinates. The polygon
-     * edges are the lines from the points with (xpoints[i-1], ypoints[i-1])
-     * coordinates to the points with (xpoints[i], ypoints[i]) coordinates, for
-     * 0 < i < npoints +1.
-     * 
-     * @param xpoints
-     *            the array of X coordinates of the polygon vertices.
-     * @param ypoints
-     *            the array of Y coordinates of the polygon vertices.
-     * @param npoints
-     *            the number of polygon vertices/points.
-     */
-    public abstract void fillPolygon(int[] xpoints, int[] ypoints, int npoints);
-
-    /**
-     * Fills a rectangle with the current color. The rectangle is defined by its
-     * width and length and top left corner coordinates.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle's top left corner.
-     * @param y
-     *            the Y coordinate of the rectangle's top left corner.
-     * @param width
-     *            the width of rectangle.
-     * @param height
-     *            the height of rectangle.
-     */
-    public abstract void fillRect(int x, int y, int width, int height);
-
-    /**
-     * Fills a round cornered rectangle with the current color.
-     * 
-     * @param x
-     *            the X coordinate of the top left corner of the bounding
-     *            rectangle.
-     * @param y
-     *            the Y coordinate of the top left corner of the bounding
-     *            rectangle.
-     * @param width
-     *            the width of the bounding rectangle.
-     * @param height
-     *            the height of the bounding rectangle.
-     * @param arcWidth
-     *            the arc width at the corners.
-     * @param arcHeight
-     *            the arc height at the corners.
-     */
-    public abstract void fillRoundRect(int x, int y, int width, int height, int arcWidth,
-            int arcHeight);
-
-    /**
-     * Gets the clipping area. <br>
-     * <br>
-     * 
-     * @return a Shape object of the clipping area or null if it is not set.
-     */
-    public abstract Shape getClip();
-
-    /**
-     * Gets the bounds of the current clipping area as a rectangle.
-     * 
-     * @return a Rectangle object which represents the bounds of the current
-     *         clipping area.
-     */
-    public abstract Rectangle getClipBounds();
-
-    /**
-     * Gets the current color of Graphics.
-     * 
-     * @return the current color.
-     */
-    public abstract Color getColor();
-
-    /**
-     * Gets the current font of Graphics.
-     * 
-     * @return the current font.
-     */
-    public abstract Font getFont();
-
-    /**
-     * Gets the font metrics of the specified font. The font metrics object
-     * contains information about the rendering of a particular font.
-     * 
-     * @param font
-     *            the specified font.
-     * @return the font metrics for the specified font.
-     */
-    public abstract FontMetrics getFontMetrics(Font font);
-
-    /**
-     * Sets the new clipping area specified by rectangle. The new clipping area
-     * doesn't depend on the window's visibility. Rendering operations can't be
-     * performed outside new clipping area.
-     * 
-     * @param x
-     *            the X coordinate of the new clipping rectangle.
-     * @param y
-     *            the Y coordinate of the new clipping rectangle.
-     * @param width
-     *            the width of the new clipping rectangle.
-     * @param height
-     *            the height of the new clipping rectangle.
-     */
-    public abstract void setClip(int x, int y, int width, int height);
-
-    /**
-     * Sets the new clipping area to be the area specified by Shape object. The
-     * new clipping area doesn't depend on the window's visibility. Rendering
-     * operations can't be performed outside new clipping area.
-     * 
-     * @param clip
-     *            the Shape object which represents new clipping area.
-     */
-    public abstract void setClip(Shape clip);
-
-    /**
-     * Sets the current Graphics color. All rendering operations with this
-     * Graphics will use this color.
-     * 
-     * @param c
-     *            the new color.
-     */
-    public abstract void setColor(Color c);
-
-    /**
-     * Sets the current Graphics font. All rendering operations with this
-     * Graphics will use this font.
-     * 
-     * @param font
-     *            the new font.
-     */
-    public abstract void setFont(Font font);
-
-    /**
-     * Sets the paint mode for the Graphics which overwrites all rendering
-     * operations with the current color.
-     */
-    public abstract void setPaintMode();
-
-    /**
-     * Sets the XOR mode for the Graphics which changes a pixel from the current
-     * color to the specified XOR color. <br>
-     * <br>
-     * 
-     * @param color
-     *            the new XOR mode.
-     */
-    public abstract void setXORMode(Color color);
-
-    /**
-     * Translates the origin of Graphics current coordinate system to the point
-     * with X, Y coordinates in the current coordinate system. All rendering
-     * operation in this Graphics will be related to the new origin.
-     * 
-     * @param x
-     *            the X coordinate of the origin.
-     * @param y
-     *            the Y coordinate of the origin.
-     */
-    public abstract void translate(int x, int y);
-}
diff --git a/awt/java/awt/Graphics2D.java b/awt/java/awt/Graphics2D.java
deleted file mode 100644
index 04a7319..0000000
--- a/awt/java/awt/Graphics2D.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.awt;
-
-import java.awt.font.GlyphVector;
-import java.awt.font.FontRenderContext;
-import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-import java.awt.image.BufferedImageOp;
-import java.awt.image.ImageObserver;
-import java.awt.image.RenderedImage;
-import java.awt.image.renderable.RenderableImage;
-import java.text.AttributedCharacterIterator;
-import java.util.Map;
-
-/**
- * The Graphics2D class extends Graphics class and provides more capabilities
- * for rendering text, images, shapes. This provides methods to perform
- * transformation of coordinate system, color management, and text layout. The
- * following attributes exist for rendering:
- * <ul>
- * <li>Color - current Graphics2D color;</li>
- * <li>Font - current Graphics2D font;</li>
- * <li>Stroke - pen with a width of 1 pixel;</li>
- * <li>Transform - current Graphics2D Transformation;</li>
- * <li>Composite - alpha compositing rules for combining source and destination
- * colors.</li>
- * </ul>
- * 
- * @since Android 1.0
- */
-public abstract class Graphics2D extends Graphics {
-
-    /**
-     * Instantiates a new Graphics2D object. This constructor should never be
-     * called directly.
-     */
-    protected Graphics2D() {
-        super();
-    }
-
-    /**
-     * Adds preferences for the rendering algorithms. The preferences are
-     * arbitrary and specified by Map objects. All specified by Map object
-     * preferences can be modified.
-     * 
-     * @param hints
-     *            the rendering hints.
-     */
-    public abstract void addRenderingHints(Map<?, ?> hints);
-
-    /**
-     * Intersects the current clipping area with the specified Shape and the
-     * result becomes a new clipping area. If current clipping area is not
-     * defined, the Shape becomes the new clipping area. No rendering operations
-     * are allowed outside the clipping area.
-     * 
-     * @param s
-     *            the specified Shape object which will be intersected with
-     *            current clipping area.
-     */
-    public abstract void clip(Shape s);
-
-    /**
-     * Draws the outline of the specified Shape.
-     * 
-     * @param s
-     *            the Shape which outline is drawn.
-     */
-    public abstract void draw(Shape s);
-
-    /**
-     * Draws the specified GlyphVector object's text at the point x, y.
-     * 
-     * @param g
-     *            the GlyphVector object to be drawn.
-     * @param x
-     *            the X position where the GlyphVector's text should be
-     *            rendered.
-     * @param y
-     *            the Y position where the GlyphVector's text should be
-     *            rendered.
-     */
-    public abstract void drawGlyphVector(GlyphVector g, float x, float y);
-
-    /**
-     * Draws the BufferedImage -- modified according to the operation
-     * BufferedImageOp -- at the point x, y.
-     * 
-     * @param img
-     *            the BufferedImage to be rendered.
-     * @param op
-     *            the filter to be applied to the image before rendering.
-     * @param x
-     *            the X coordinate of the point where the image's upper left
-     *            corner will be placed.
-     * @param y
-     *            the Y coordinate of the point where the image's upper left
-     *            corner will be placed.
-     */
-    public abstract void drawImage(BufferedImage img, BufferedImageOp op, int x, int y);
-
-    /**
-     * Draws BufferedImage transformed from image space into user space
-     * according to the AffineTransform xform and notifies the ImageObserver.
-     * 
-     * @param img
-     *            the BufferedImage to be rendered.
-     * @param xform
-     *            the affine transformation from the image to the user space.
-     * @param obs
-     *            the ImageObserver to be notified about the image conversion.
-     * @return true, if the image is successfully loaded and rendered, or it's
-     *         null, otherwise false.
-     */
-    public abstract boolean drawImage(Image img, AffineTransform xform, ImageObserver obs);
-
-    /**
-     * Draws a RenderableImage which is transformed from image space into user
-     * according to the AffineTransform xform.
-     * 
-     * @param img
-     *            the RenderableImage to be rendered.
-     * @param xform
-     *            the affine transformation from image to user space.
-     */
-    public abstract void drawRenderableImage(RenderableImage img, AffineTransform xform);
-
-    /**
-     * Draws a RenderedImage which is transformed from image space into user
-     * according to the AffineTransform xform.
-     * 
-     * @param img
-     *            the RenderedImage to be rendered.
-     * @param xform
-     *            the affine transformation from image to user space.
-     */
-    public abstract void drawRenderedImage(RenderedImage img, AffineTransform xform);
-
-    /**
-     * Draws the string specified by the AttributedCharacterIterator. The first
-     * character's position is specified by the X, Y parameters.
-     * 
-     * @param iterator
-     *            whose text is drawn.
-     * @param x
-     *            the X position where the first character is drawn.
-     * @param y
-     *            the Y position where the first character is drawn.
-     */
-    public abstract void drawString(AttributedCharacterIterator iterator, float x, float y);
-
-    /**
-     * Draws the string specified by the AttributedCharacterIterator. The first
-     * character's position is specified by the X, Y parameters.
-     * 
-     * @param iterator
-     *            whose text is drawn.
-     * @param x
-     *            the X position where the first character is drawn.
-     * @param y
-     *            the Y position where the first character is drawn.
-     * @see java.awt.Graphics#drawString(AttributedCharacterIterator, int, int)
-     */
-    @Override
-    public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);
-
-    /**
-     * Draws the String whose the first character position is specified by the
-     * parameters X, Y.
-     * 
-     * @param s
-     *            the String to be drawn.
-     * @param x
-     *            the X position of the first character.
-     * @param y
-     *            the Y position of the first character.
-     */
-    public abstract void drawString(String s, float x, float y);
-
-    /**
-     * Draws the String whose the first character coordinates are specified by
-     * the parameters X, Y.
-     * 
-     * @param str
-     *            the String to be drawn.
-     * @param x
-     *            the X coordinate of the first character.
-     * @param y
-     *            the Y coordinate of the first character.
-     * @see java.awt.Graphics#drawString(String, int, int)
-     */
-    @Override
-    public abstract void drawString(String str, int x, int y);
-
-    /**
-     * Fills the interior of the specified Shape.
-     * 
-     * @param s
-     *            the Shape to be filled.
-     */
-    public abstract void fill(Shape s);
-
-    /**
-     * Gets the background color.
-     * 
-     * @return the current background color.
-     */
-    public abstract Color getBackground();
-
-    /**
-     * Gets the current composite of the Graphics2D.
-     * 
-     * @return the current composite which specifies the compositing style.
-     */
-    public abstract Composite getComposite();
-
-    /**
-     * Gets the device configuration.
-     * 
-     * @return the device configuration.
-     */
-    public abstract GraphicsConfiguration getDeviceConfiguration();
-
-    /**
-     * Gets the rendering context of the Font.
-     * 
-     * @return the FontRenderContext.
-     */
-    public abstract FontRenderContext getFontRenderContext();
-
-    /**
-     * Gets the current Paint of Graphics2D.
-     * 
-     * @return the current Paint of Graphics2D.
-     */
-    public abstract Paint getPaint();
-
-    /**
-     * Gets the value of single preference for specified key.
-     * 
-     * @param key
-     *            the specified key of the rendering hint.
-     * @return the value of rendering hint for specified key.
-     */
-    public abstract Object getRenderingHint(RenderingHints.Key key);
-
-    /**
-     * Gets the set of the rendering preferences as a collection of key/value
-     * pairs.
-     * 
-     * @return the RenderingHints which contains the rendering preferences.
-     */
-    public abstract RenderingHints getRenderingHints();
-
-    /**
-     * Gets current stroke of the Graphics2D.
-     * 
-     * @return current stroke of the Graphics2D.
-     */
-    public abstract Stroke getStroke();
-
-    /**
-     * Gets current affine transform of the Graphics2D.
-     * 
-     * @return current AffineTransform of the Graphics2D.
-     */
-    public abstract AffineTransform getTransform();
-
-    /**
-     * Determines whether or not the specified Shape intersects the specified
-     * Rectangle. If the onStroke parameter is true, this method checks whether
-     * or not the specified Shape outline intersects the specified Rectangle,
-     * otherwise this method checks whether or not the specified Shape's
-     * interior intersects the specified Rectangle.
-     * 
-     * @param rect
-     *            the specified Rectangle.
-     * @param s
-     *            the Shape to check for intersection.
-     * @param onStroke
-     *            the parameter determines whether or not this method checks for
-     *            intersection of the Shape outline or of the Shape interior
-     *            with the Rectangle.
-     * @return true, if there is a hit, false otherwise.
-     */
-    public abstract boolean hit(Rectangle rect, Shape s, boolean onStroke);
-
-    /**
-     * Performs a rotation transform relative to current Graphics2D Transform.
-     * The coordinate system is rotated by the specified angle in radians
-     * relative to current origin.
-     * 
-     * @param theta
-     *            the angle of rotation in radians.
-     */
-    public abstract void rotate(double theta);
-
-    /**
-     * Performs a translated rotation transform relative to current Graphics2D
-     * Transform. The coordinate system is rotated by the specified angle in
-     * radians relative to current origin and then moved to point (x, y). Is
-     * this right?
-     * 
-     * @param theta
-     *            the angle of rotation in radians.
-     * @param x
-     *            the X coordinate.
-     * @param y
-     *            the Y coordinate.
-     */
-    public abstract void rotate(double theta, double x, double y);
-
-    /**
-     * Performs a linear scale transform relative to current Graphics2D
-     * Transform. The coordinate system is rescaled vertically and horizontally
-     * by the specified parameters.
-     * 
-     * @param sx
-     *            the scaling factor by which the X coordinate is multiplied.
-     * @param sy
-     *            the scaling factor by which the Y coordinate is multiplied.
-     */
-    public abstract void scale(double sx, double sy);
-
-    /**
-     * Sets a new background color for clearing rectangular areas. The clearRect
-     * method uses the current background color.
-     * 
-     * @param color
-     *            the new background color.
-     */
-    public abstract void setBackground(Color color);
-
-    /**
-     * Sets the current composite for Graphics2D.
-     * 
-     * @param comp
-     *            the Composite object.
-     */
-    public abstract void setComposite(Composite comp);
-
-    /**
-     * Sets the paint for Graphics2D.
-     * 
-     * @param paint
-     *            the Paint object.
-     */
-    public abstract void setPaint(Paint paint);
-
-    /**
-     * Sets a key-value pair in the current RenderingHints map.
-     * 
-     * @param key
-     *            the key of the rendering hint to set.
-     * @param value
-     *            the value to set for the rendering hint.
-     */
-    public abstract void setRenderingHint(RenderingHints.Key key, Object value);
-
-    /**
-     * Replaces the current rendering hints with the specified rendering
-     * preferences.
-     * 
-     * @param hints
-     *            the new Map of rendering hints.
-     */
-    public abstract void setRenderingHints(Map<?, ?> hints);
-
-    /**
-     * Sets the stroke for the Graphics2D.
-     * 
-     * @param s
-     *            the Stroke object.
-     */
-    public abstract void setStroke(Stroke s);
-
-    /**
-     * Overwrite the current Transform of the Graphics2D. The specified
-     * Transform should be received from the getTransform() method and should be
-     * used only for restoring the original Graphics2D transform after calling
-     * draw or fill methods.
-     * 
-     * @param Tx
-     *            the specified Transform.
-     */
-    public abstract void setTransform(AffineTransform Tx);
-
-    /**
-     * Performs a shear transform relative to current Graphics2D Transform. The
-     * coordinate system is shifted by the specified multipliers relative to
-     * current position.
-     * 
-     * @param shx
-     *            the multiplier by which the X coordinates shift position along
-     *            X axis as a function of Y coordinates.
-     * @param shy
-     *            the multiplier by which the Y coordinates shift position along
-     *            Y axis as a function of X coordinates.
-     */
-    public abstract void shear(double shx, double shy);
-
-    /**
-     * Concatenates the AffineTransform object with current Transform of this
-     * Graphics2D. The transforms are applied in reverse order with the last
-     * specified transform applied first and the next transformation applied to
-     * the result of previous transformation. More precisely, if Cx is the
-     * current Graphics2D transform, the transform method's result with Tx as
-     * the parameter is the transformation Rx, where Rx(p) = Cx(Tx(p)), for p -
-     * a point in current coordinate system. Rx becomes the current Transform
-     * for this Graphics2D.
-     * 
-     * @param Tx
-     *            the AffineTransform object to be concatenated with current
-     *            Transform.
-     */
-    public abstract void transform(AffineTransform Tx);
-
-    /**
-     * Performs a translate transform relative to current Graphics2D Transform.
-     * The coordinate system is moved by the specified distance relative to
-     * current position.
-     * 
-     * @param tx
-     *            the translation distance along the X axis.
-     * @param ty
-     *            the translation distance along the Y axis.
-     */
-    public abstract void translate(double tx, double ty);
-
-    /**
-     * Moves the origin Graphics2D Transform to the point with x, y coordinates
-     * in current coordinate system. The new origin of coordinate system is
-     * moved to the (x, y) point accordingly. All rendering and transform
-     * operations are performed relative to this new origin.
-     * 
-     * @param x
-     *            the X coordinate.
-     * @param y
-     *            the Y coordinate.
-     * @see java.awt.Graphics#translate(int, int)
-     */
-    @Override
-    public abstract void translate(int x, int y);
-
-    /**
-     * Fills a 3D rectangle with the current color. The rectangle is specified
-     * by its width, height, and top left corner coordinates.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle's top left corner.
-     * @param y
-     *            the Y coordinate of the rectangle's top left corner.
-     * @param width
-     *            the width of rectangle.
-     * @param height
-     *            the height of rectangle.
-     * @param raised
-     *            a boolean value that determines whether the rectangle is drawn
-     *            as raised or indented.
-     * @see java.awt.Graphics#fill3DRect(int, int, int, int, boolean)
-     */
-    @Override
-    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
-        // According to the spec, color should be used instead of paint,
-        // so Graphics.fill3DRect resets paint and
-        // it should be restored after the call
-        Paint savedPaint = getPaint();
-        super.fill3DRect(x, y, width, height, raised);
-        setPaint(savedPaint);
-    }
-
-    /**
-     * Draws the highlighted outline of a rectangle.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle's top left corner.
-     * @param y
-     *            the Y coordinate of the rectangle's top left corner.
-     * @param width
-     *            the width of rectangle.
-     * @param height
-     *            the height of rectangle.
-     * @param raised
-     *            a boolean value that determines whether the rectangle is drawn
-     *            as raised or indented.
-     * @see java.awt.Graphics#draw3DRect(int, int, int, int, boolean)
-     */
-    @Override
-    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
-        // According to the spec, color should be used instead of paint,
-        // so Graphics.draw3DRect resets paint and
-        // it should be restored after the call
-        Paint savedPaint = getPaint();
-        super.draw3DRect(x, y, width, height, raised);
-        setPaint(savedPaint);
-    }
-}
\ No newline at end of file
diff --git a/awt/java/awt/GraphicsConfiguration.java b/awt/java/awt/GraphicsConfiguration.java
deleted file mode 100644
index d59e896..0000000
--- a/awt/java/awt/GraphicsConfiguration.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.VolatileImage;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The GraphicsConfiguration class contains the characteristics of graphics
- * devices such as a printer or monitor, and represents device's capabilities
- * and modes. Many GraphicsConfiguration objects can be associated with single
- * graphics device.
- * 
- * @since Android 1.0
- */
-public abstract class GraphicsConfiguration {
-
-    /**
-     * Constructor could not be used directly and should be obtained in extended
-     * classes.
-     */
-    protected GraphicsConfiguration() {
-    }
-
-    /**
-     * Creates BufferedImage image object with a data layout and color model
-     * compatible with this GraphicsConfiguration with specified width and
-     * height parameters.
-     * 
-     * @param width
-     *            the width of BufferedImage.
-     * @param height
-     *            the height of BufferedImage.
-     * @return the BufferedImage object with specified width and height
-     *         parameters.
-     */
-    public abstract BufferedImage createCompatibleImage(int width, int height);
-
-    /**
-     * Creates a BufferedImage that has the specified width, height,
-     * transparency and has a data layout and color model compatible with this
-     * GraphicsConfiguration.
-     * 
-     * @param width
-     *            the width of image.
-     * @param height
-     *            the height of image.
-     * @param transparency
-     *            the transparency mode.
-     * @return the BufferedImage object.
-     */
-    public abstract BufferedImage createCompatibleImage(int width, int height, int transparency);
-
-    /**
-     * Creates a VolatileImage that has the specified width and height and has a
-     * data layout and color model compatible with this GraphicsConfiguration.
-     * 
-     * @param width
-     *            the width of image.
-     * @param height
-     *            the height of image.
-     * @return the VolatileImage object.
-     */
-    public abstract VolatileImage createCompatibleVolatileImage(int width, int height);
-
-    /**
-     * Creates a VolatileImage that supports the specified width, height,
-     * transparency and has a data layout and color model compatible with this
-     * GraphicsConfiguration.
-     * 
-     * @param width
-     *            the width of image.
-     * @param height
-     *            the height of image.
-     * @param transparency
-     *            the transparency mode.
-     * @return the VolatileImage object.
-     */
-    public abstract VolatileImage createCompatibleVolatileImage(int width, int height,
-            int transparency);
-
-    /**
-     * Gets the bounds of area covered by the GraphicsConfiguration in the
-     * device coordinates space.
-     * 
-     * @return the Rectangle of GraphicsConfiguration's bounds.
-     */
-    public abstract Rectangle getBounds();
-
-    /**
-     * Gets the ColorModel of the GraphicsConfiguration.
-     * 
-     * @return the ColorModel object of the GraphicsConfiguration.
-     */
-    public abstract ColorModel getColorModel();
-
-    /**
-     * Gets the ColorModel of the GraphicsConfiguration which supports specified
-     * Transparency.
-     * 
-     * @param transparency
-     *            the Transparency mode: OPAQUE, BITMASK, or TRANSLUCENT.
-     * @return the ColorModel of the GraphicsConfiguration which supports
-     *         specified Transparency.
-     */
-    public abstract ColorModel getColorModel(int transparency);
-
-    /**
-     * Gets the default AffineTransform of the GraphicsConfiguration. This
-     * method translates user coordinates to device coordinates.
-     * 
-     * @return the default AffineTransform of the GraphicsConfiguration.
-     */
-    public abstract AffineTransform getDefaultTransform();
-
-    /**
-     * Gets the GraphicsDevice of the GraphicsConfiguration.
-     * 
-     * @return the GraphicsDevice of the GraphicsConfiguration.
-     */
-    public abstract GraphicsDevice getDevice();
-
-    /**
-     * Gets the normalizing AffineTransform of the GraphicsConfiguration.
-     * 
-     * @return the normalizing AffineTransform of the GraphicsConfiguration.
-     */
-    public abstract AffineTransform getNormalizingTransform();
-
-    /**
-     * Creates VolatileImage with specified width, height, ImageCapabilities; a
-     * data layout and color model compatible with this GraphicsConfiguration.
-     * 
-     * @param width
-     *            the width of image.
-     * @param height
-     *            the height of image.
-     * @param caps
-     *            the ImageCapabilities object.
-     * @return the VolatileImage which data layout and color model compatible
-     *         with this GraphicsConfiguration.
-     * @throws AWTException
-     *             if ImageCapabilities is not supported by the
-     *             GraphicsConfiguration.
-     */
-    public VolatileImage createCompatibleVolatileImage(int width, int height, ImageCapabilities caps)
-            throws AWTException {
-        VolatileImage res = createCompatibleVolatileImage(width, height);
-        if (!res.getCapabilities().equals(caps)) {
-            // awt.14A=Can not create VolatileImage with specified capabilities
-            throw new AWTException(Messages.getString("awt.14A")); //$NON-NLS-1$
-        }
-        return res;
-    }
-
-    /**
-     * Creates a VolatileImage with specified width, height, transparency and
-     * ImageCapabilities; a data layout and color model compatible with this
-     * GraphicsConfiguration.
-     * 
-     * @param width
-     *            the width of image.
-     * @param height
-     *            the height of image.
-     * @param caps
-     *            the ImageCapabilities object.
-     * @param transparency
-     *            the Transparency mode: OPAQUE, BITMASK, or TRANSLUCENT.
-     * @return the VolatileImage which data layout and color model compatible
-     *         with this GraphicsConfiguration.
-     * @throws AWTException
-     *             if ImageCapabilities is not supported by the
-     *             GraphicsConfiguration.
-     */
-    public VolatileImage createCompatibleVolatileImage(int width, int height,
-            ImageCapabilities caps, int transparency) throws AWTException {
-        VolatileImage res = createCompatibleVolatileImage(width, height, transparency);
-        if (!res.getCapabilities().equals(caps)) {
-            // awt.14A=Can not create VolatileImage with specified capabilities
-            throw new AWTException(Messages.getString("awt.14A")); //$NON-NLS-1$
-        }
-        return res;
-    }
-
-    /**
-     * Gets the buffering capabilities of the GraphicsConfiguration.
-     * 
-     * @return the BufferCapabilities object.
-     */
-    public BufferCapabilities getBufferCapabilities() {
-        return new BufferCapabilities(new ImageCapabilities(false), new ImageCapabilities(false),
-                BufferCapabilities.FlipContents.UNDEFINED);
-    }
-
-    /**
-     * Gets the image capabilities of the GraphicsConfiguration.
-     * 
-     * @return the ImageCapabilities object.
-     */
-    public ImageCapabilities getImageCapabilities() {
-        return new ImageCapabilities(false);
-    }
-}
diff --git a/awt/java/awt/GraphicsDevice.java b/awt/java/awt/GraphicsDevice.java
deleted file mode 100644
index 9eda4e0..0000000
--- a/awt/java/awt/GraphicsDevice.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The GraphicsDevice class describes the graphics devices (such as screens or
- * printers) which are available in a particular graphics environment. Many
- * GraphicsDevice instances can be associated with a single GraphicsEnvironment.
- * Each GraphicsDevice has one or more GraphicsConfiguration objects which
- * specify the different configurations and modes of GraphicsDevice.
- * 
- * @since Android 1.0
- */
-public abstract class GraphicsDevice {
-
-    /**
-     * The display mode.
-     */
-    private DisplayMode displayMode;
-
-    // ???AWT
-    // private Window fullScreenWindow = null;
-
-    /**
-     * The Constant TYPE_IMAGE_BUFFER indicates a image buffer device.
-     */
-
-    public static final int TYPE_IMAGE_BUFFER = 2;
-
-    /**
-     * The Constant TYPE_PRINTER indicates a printer device.
-     */
-    public static final int TYPE_PRINTER = 1;
-
-    /**
-     * The Constant TYPE_RASTER_SCREEN indicates a raster screen device.
-     */
-    public static final int TYPE_RASTER_SCREEN = 0;
-
-    /**
-     * Constructor is not to be used directly as this class is abstract.
-     */
-    protected GraphicsDevice() {
-        displayMode = new DisplayMode(0, 0, DisplayMode.BIT_DEPTH_MULTI,
-                DisplayMode.REFRESH_RATE_UNKNOWN);
-    }
-
-    /**
-     * Returns an array of GraphicsConfiguration objects associated with the
-     * GraphicsDevice.
-     * 
-     * @return an array of GraphicsConfiguration objects associated with the
-     *         GraphicsDevice.
-     */
-    public abstract GraphicsConfiguration[] getConfigurations();
-
-    /**
-     * Gets the default configuration for the GraphicsDevice.
-     * 
-     * @return the default GraphicsConfiguration object for the GraphicsDevice.
-     */
-    public abstract GraphicsConfiguration getDefaultConfiguration();
-
-    /**
-     * Gets the String identifier which associated with the GraphicsDevice in
-     * the GraphicsEnvironment.
-     * 
-     * @return the String identifier of the GraphicsDevice in the
-     *         GraphicsEnvironment.
-     */
-    public abstract String getIDstring();
-
-    /**
-     * Gets the type of this GraphicsDevice: TYPE_IMAGE_BUFFER, TYPE_PRINTER or
-     * TYPE_RASTER_SCREEN.
-     * 
-     * @return the type of this GraphicsDevice: TYPE_IMAGE_BUFFER, TYPE_PRINTER
-     *         or TYPE_RASTER_SCREEN.
-     */
-    public abstract int getType();
-
-    /**
-     * Returns the number of bytes available in accelerated memory on this
-     * device.
-     * 
-     * @return the number of bytes available accelerated memory.
-     */
-    public int getAvailableAcceleratedMemory() {
-        return 0;
-    }
-
-    /*
-     * ???AWT public GraphicsConfiguration
-     * getBestConfiguration(GraphicsConfigTemplate gct) { return
-     * gct.getBestConfiguration(getConfigurations()); }
-     */
-
-    /**
-     * Gets the current display mode of the GraphicsDevice.
-     * 
-     * @return the current display mode of the GraphicsDevice.
-     */
-    public DisplayMode getDisplayMode() {
-        return displayMode;
-    }
-
-    /**
-     * Gets an array of display modes available in this GraphicsDevice.
-     * 
-     * @return an array of display modes available in this GraphicsDevice.
-     */
-    public DisplayMode[] getDisplayModes() {
-        DisplayMode[] dms = {
-            displayMode
-        };
-        return dms;
-    }
-
-    /*
-     * ???AWT public Window getFullScreenWindow() { return fullScreenWindow; }
-     */
-
-    /**
-     * Returns true if this GraphicsDevice supports low-level display changes.
-     * 
-     * @return true, if this GraphicsDevice supports low-level display changes;
-     *         false otherwise.
-     */
-    public boolean isDisplayChangeSupported() {
-        return false;
-    }
-
-    /**
-     * Returns true if this GraphicsDevice supports full screen mode.
-     * 
-     * @return true, if this GraphicsDevice supports full screen mode, false
-     *         otherwise.
-     */
-    public boolean isFullScreenSupported() {
-        return false;
-    }
-
-    // an array of display modes available in this GraphicsDevice.
-
-    /**
-     * Sets the display mode of this GraphicsDevice.
-     * 
-     * @param dm
-     *            the new display mode of this GraphicsDevice.
-     */
-    public void setDisplayMode(DisplayMode dm) {
-        if (!isDisplayChangeSupported()) {
-            // awt.122=Does not support display mode changes
-            throw new UnsupportedOperationException(Messages.getString("awt.122")); //$NON-NLS-1$
-        }
-
-        DisplayMode[] dms = getDisplayModes();
-        for (DisplayMode element : dms) {
-            if (element.equals(dm)) {
-                displayMode = dm;
-                return;
-            }
-        }
-        // awt.123=Unsupported display mode: {0}
-        throw new IllegalArgumentException(Messages.getString("awt.123", dm)); //$NON-NLS-1$
-    }
-
-    /*
-     * ???AWT public void setFullScreenWindow(Window w) { if (w == null) {
-     * fullScreenWindow = null; return; } fullScreenWindow = w; if
-     * (isFullScreenSupported()) { w.enableInputMethods(false); } else {
-     * w.setSize(displayMode.getWidth(), displayMode.getHeight());
-     * w.setLocation(0, 0); } w.setVisible(true); w.setAlwaysOnTop(true); }
-     */
-}
diff --git a/awt/java/awt/GraphicsEnvironment.java b/awt/java/awt/GraphicsEnvironment.java
deleted file mode 100644
index d527417..0000000
--- a/awt/java/awt/GraphicsEnvironment.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.image.BufferedImage;
-import java.util.Locale;
-
-import org.apache.harmony.awt.ContextStorage;
-import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
-
-/**
- * The GraphicsEnvironment class defines a collection of GraphicsDevice objects
- * and Font objects which are available for Java application on current
- * platform.
- * 
- * @since Android 1.0
- */
-public abstract class GraphicsEnvironment {
-
-    /**
-     * Constructor could not be used directly and should be obtained in extended
-     * classes.
-     */
-    protected GraphicsEnvironment() {
-    }
-
-    /**
-     * Gets the local GraphicsEnvironment.
-     * 
-     * @return the local GraphicsEnvironment.
-     */
-    public static GraphicsEnvironment getLocalGraphicsEnvironment() {
-        synchronized (ContextStorage.getContextLock()) {
-            if (ContextStorage.getGraphicsEnvironment() == null) {
-                if (isHeadless()) {
-                    ContextStorage.setGraphicsEnvironment(new HeadlessGraphicsEnvironment());
-                } else {
-                    CommonGraphics2DFactory g2df = (CommonGraphics2DFactory)Toolkit
-                            .getDefaultToolkit().getGraphicsFactory();
-
-                    ContextStorage.setGraphicsEnvironment(g2df
-                            .createGraphicsEnvironment(ContextStorage.getWindowFactory()));
-                }
-            }
-
-            return ContextStorage.getGraphicsEnvironment();
-        }
-    }
-
-    /**
-     * Returns whether or not a display, keyboard, and mouse are supported in
-     * this graphics environment.
-     * 
-     * @return true, if HeadlessException will be thrown from areas of the
-     *         graphics environment that are dependent on a display, keyboard,
-     *         or mouse, false otherwise.
-     */
-    public boolean isHeadlessInstance() {
-        return false;
-    }
-
-    /**
-     * Checks whether or not a display, keyboard, and mouse are supported in
-     * this environment.
-     * 
-     * @return true, if a HeadlessException is thrown from areas of the Toolkit
-     *         and GraphicsEnvironment that are dependent on a display,
-     *         keyboard, or mouse, false otherwise.
-     */
-    public static boolean isHeadless() {
-        return "true".equals(System.getProperty("java.awt.headless"));
-    }
-
-    /**
-     * Gets the maximum bounds of system centered windows.
-     * 
-     * @return the maximum bounds of system centered windows.
-     * @throws HeadlessException
-     *             if isHeadless() method returns true.
-     */
-    public Rectangle getMaximumWindowBounds() throws HeadlessException {
-        return getDefaultScreenDevice().getDefaultConfiguration().getBounds();
-    }
-
-    /**
-     * Gets the Point which should defines the center of system window.
-     * 
-     * @return the Point where the system window should be centered.
-     * @throws HeadlessException
-     *             if isHeadless() method returns true.
-     */
-    public Point getCenterPoint() throws HeadlessException {
-        Rectangle mwb = getMaximumWindowBounds();
-        return new Point(mwb.width >> 1, mwb.height >> 1);
-    }
-
-    /**
-     * Indicates that the primary font should be used. Primary font is specified
-     * by initial system locale or default encoding).
-     */
-    public void preferLocaleFonts() {
-        // Note: API specification says following:
-        // "The actual change in font rendering behavior resulting
-        // from a call to this method is implementation dependent;
-        // it may have no effect at all." So, doing nothing is an
-        // acceptable behavior for this method.
-
-        // For now FontManager uses 1.4 font.properties scheme for font mapping,
-        // so
-        // this method doesn't make any sense. The implementation of this method
-        // which will influence font mapping is postponed until
-        // 1.5 mapping scheme not implemented.
-
-        // todo - Implement non-default behavior with 1.5 font mapping scheme
-    }
-
-    /**
-     * Indicates that a proportional preference of the font should be used.
-     */
-    public void preferProportionalFonts() {
-        // Note: API specification says following:
-        // "The actual change in font rendering behavior resulting
-        // from a call to this method is implementation dependent;
-        // it may have no effect at all." So, doing nothing is an
-        // acceptable behavior for this method.
-
-        // For now FontManager uses 1.4 font.properties scheme for font mapping,
-        // so
-        // this method doesn't make any sense. The implementation of this method
-        // which will influence font mapping is postponed until
-        // 1.5 mapping scheme not implemented.
-
-        // todo - Implement non-default behavior with 1.5 font mapping scheme
-    }
-
-    /**
-     * Creates the Graphics2D object for rendering to the specified
-     * BufferedImage.
-     * 
-     * @param bufferedImage
-     *            the BufferedImage object.
-     * @return the Graphics2D object which allows to render to the specified
-     *         BufferedImage.
-     */
-    public abstract Graphics2D createGraphics(BufferedImage bufferedImage);
-
-    /**
-     * Gets the array of all available fonts instances in this
-     * GraphicsEnviroments.
-     * 
-     * @return the array of all available fonts instances in this
-     *         GraphicsEnviroments.
-     */
-    public abstract Font[] getAllFonts();
-
-    /**
-     * Gets the array of all available font family names.
-     * 
-     * @return the array of all available font family names.
-     */
-    public abstract String[] getAvailableFontFamilyNames();
-
-    /**
-     * Gets the array of all available font family names for the specified
-     * locale.
-     * 
-     * @param locale
-     *            the Locale object which represents geographical region. The
-     *            default locale is used if locale is null.
-     * @return the array of available font family names for the specified
-     *         locale.
-     */
-    public abstract String[] getAvailableFontFamilyNames(Locale locale);
-
-    /**
-     * Gets the default screen device as GraphicDevice object.
-     * 
-     * @return the GraphicDevice object which represents default screen device.
-     * @throws HeadlessException
-     *             if isHeadless() returns true.
-     */
-    public abstract GraphicsDevice getDefaultScreenDevice() throws HeadlessException;
-
-    /**
-     * Gets an array of all available screen devices.
-     * 
-     * @return the array of GraphicsDevice objects which represents all
-     *         available screen devices.
-     * @throws HeadlessException
-     *             if isHeadless() returns true.
-     */
-    public abstract GraphicsDevice[] getScreenDevices() throws HeadlessException;
-}
diff --git a/awt/java/awt/HeadlessException.java b/awt/java/awt/HeadlessException.java
deleted file mode 100644
index ec111f1..0000000
--- a/awt/java/awt/HeadlessException.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * The HeadlessException class provides notifications and error messages when
- * code that is dependent on a keyboard, display, or mouse is called in an
- * environment that does not support a keyboard, display, or mouse.
- * 
- * @since Android 1.0
- */
-public class HeadlessException extends UnsupportedOperationException {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 167183644944358563L;
-
-    /**
-     * Instantiates a new headless exception.
-     */
-    public HeadlessException() {
-        super();
-    }
-
-    /**
-     * Instantiates a new headless exception with the specified message.
-     * 
-     * @param msg
-     *            the String which represents error message.
-     */
-    public HeadlessException(String msg) {
-        super(msg);
-    }
-}
diff --git a/awt/java/awt/HeadlessGraphicsEnvironment.java b/awt/java/awt/HeadlessGraphicsEnvironment.java
deleted file mode 100644
index 306393f..0000000
--- a/awt/java/awt/HeadlessGraphicsEnvironment.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.awt;
-
-import java.awt.GraphicsDevice;
-import java.awt.HeadlessException;
-
-import org.apache.harmony.awt.gl.CommonGraphicsEnvironment;
-
-/**
- * The HeadlessGraphicsEnvironment class is the CommonGraphicsEnvironment
- * implementation to use in the case where the environment lacks display,
- * keyboard, and mouse support.
- * 
- * @since Android 1.0
- */
-public class HeadlessGraphicsEnvironment extends CommonGraphicsEnvironment {
-
-    /**
-     * Returns whether or not a display, keyboard, and mouse are supported in
-     * this graphics environment.
-     * 
-     * @return true, if HeadlessException will be thrown from areas of the
-     *         graphics environment that are dependent on a display, keyboard,
-     *         or mouse, false otherwise.
-     */
-    @Override
-    public boolean isHeadlessInstance() {
-        return true;
-    }
-
-    /**
-     * Gets the default screen device as GraphicDevice object.
-     * 
-     * @return the GraphicDevice object which represents default screen device.
-     * @throws HeadlessException
-     *             if isHeadless() returns true.
-     */
-    @Override
-    public GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    /**
-     * Gets an array of all available screen devices.
-     * 
-     * @return the array of GraphicsDevice objects which represents all
-     *         available screen devices.
-     * @throws HeadlessException
-     *             if isHeadless() returns true.
-     */
-    @Override
-    public GraphicsDevice[] getScreenDevices() throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-}
diff --git a/awt/java/awt/HeadlessToolkit.java b/awt/java/awt/HeadlessToolkit.java
deleted file mode 100644
index c64a85a..0000000
--- a/awt/java/awt/HeadlessToolkit.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.awt;
-
-//???AWT
-//import java.awt.datatransfer.Clipboard;
-//import java.awt.dnd.DragGestureEvent;
-//import java.awt.dnd.DragGestureListener;
-//import java.awt.dnd.DragGestureRecognizer;
-//import java.awt.dnd.DragSource;
-//import java.awt.dnd.InvalidDnDOperationException;
-//import java.awt.dnd.peer.DragSourceContextPeer;
-import java.awt.im.InputMethodHighlight;
-import java.awt.image.ColorModel; //import java.awt.peer.*;
-//import java.beans.PropertyChangeSupport;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.harmony.awt.ComponentInternals; //import org.apache.harmony.awt.datatransfer.DTK;
-import org.apache.harmony.awt.wtk.GraphicsFactory;
-import org.apache.harmony.awt.wtk.NativeEventQueue;
-import org.apache.harmony.awt.wtk.WindowFactory;
-
-/**
- * The HeadlessToolkit class is a subclass of ToolkitImpl to be used for
- * graphical environments that lack keyboard and mouse capabilities.
- * 
- * @since Android 1.0
- */
-public final class HeadlessToolkit extends ToolkitImpl {
-
-    // ???AWT
-    /*
-     * @Override protected ButtonPeer createButton(Button a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected CheckboxPeer createCheckbox(Checkbox a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected CheckboxMenuItemPeer
-     * createCheckboxMenuItem(CheckboxMenuItem a0) throws HeadlessException {
-     * throw new HeadlessException(); }
-     * @Override protected ChoicePeer createChoice(Choice a0) throws
-     * HeadlessException { throw new HeadlessException(); } public Cursor
-     * createCustomCursor(Image img, Point hotSpot, String name) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected DialogPeer createDialog(Dialog a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override public <T extends DragGestureRecognizer> T
-     * createDragGestureRecognizer( Class<T> recognizerAbstractClass, DragSource
-     * ds, Component c, int srcActions, DragGestureListener dgl) { return null;
-     * }
-     * @Override public DragSourceContextPeer
-     * createDragSourceContextPeer(DragGestureEvent dge) throws
-     * InvalidDnDOperationException { throw new InvalidDnDOperationException();
-     * }
-     * @Override protected FileDialogPeer createFileDialog(FileDialog a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected FramePeer createFrame(Frame a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected LabelPeer createLabel(Label a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected ListPeer createList(List a0) throws HeadlessException
-     * { throw new HeadlessException(); }
-     * @Override protected MenuPeer createMenu(Menu a0) throws HeadlessException
-     * { throw new HeadlessException(); }
-     * @Override protected MenuBarPeer createMenuBar(MenuBar a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected MenuItemPeer createMenuItem(MenuItem a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected PopupMenuPeer createPopupMenu(PopupMenu a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected ScrollbarPeer createScrollbar(Scrollbar a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected ScrollPanePeer createScrollPane(ScrollPane a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected TextAreaPeer createTextArea(TextArea a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected TextFieldPeer createTextField(TextField a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     * @Override protected WindowPeer createWindow(Window a0) throws
-     * HeadlessException { throw new HeadlessException(); }
-     */
-
-    @Override
-    public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public ColorModel getColorModel() throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public GraphicsFactory getGraphicsFactory() throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public int getMaximumCursorColors() throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public int getMenuShortcutKeyMask() throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    // ???AWT
-    /*
-     * @Override NativeEventQueue getNativeEventQueue() throws HeadlessException
-     * { throw new HeadlessException(); }
-     * @Override public PrintJob getPrintJob(Frame frame, String jobtitle,
-     * JobAttributes jobAttributes, PageAttributes pageAttributes) throws
-     * IllegalArgumentException { throw new IllegalArgumentException(); }
-     * @Override public PrintJob getPrintJob(Frame frame, String jobtitle,
-     * Properties props) throws NullPointerException { throw new
-     * NullPointerException(); }
-     */
-
-    @Override
-    public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public int getScreenResolution() throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public Dimension getScreenSize() throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    // ???AWT
-    /*
-     * @Override public Clipboard getSystemClipboard() throws HeadlessException
-     * { throw new HeadlessException(); }
-     * @Override public Clipboard getSystemSelection() throws HeadlessException
-     * { throw new HeadlessException(); }
-     * @Override WindowFactory getWindowFactory() throws HeadlessException {
-     * throw new HeadlessException(); }
-     */
-
-    @Override
-    protected void init() {
-        lockAWT();
-        try {
-            ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
-            // ???AWT: new EventQueue(this); // create the system EventQueue
-            // ???AWT: dispatcher = new Dispatcher(this);
-            desktopProperties = new HashMap<String, Object>();
-            // ???AWT: desktopPropsSupport = new PropertyChangeSupport(this);
-            // ???AWT: awtEventsManager = new AWTEventsManager();
-            // ???AWT: dispatchThread = new HeadlessEventDispatchThread(this,
-            // dispatcher);
-            // ???AWT: dtk = DTK.getDTK();
-            dispatchThread.start();
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public boolean isDynamicLayoutActive() throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    protected boolean isDynamicLayoutSet() throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public boolean isFrameStateSupported(int state) throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    protected void loadSystemColors(int[] systemColors) throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
-            InputMethodHighlight highlight) throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(InputMethodHighlight highlight)
-            throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public void setDynamicLayout(boolean dynamic) throws HeadlessException {
-        throw new HeadlessException();
-    }
-
-    @Override
-    public void setLockingKeyState(int keyCode, boolean on) throws UnsupportedOperationException {
-        throw new HeadlessException();
-    }
-}
diff --git a/awt/java/awt/IllegalComponentStateException.java b/awt/java/awt/IllegalComponentStateException.java
deleted file mode 100644
index bed1729..0000000
--- a/awt/java/awt/IllegalComponentStateException.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * The IllegalComponentStateException class is used to provide notification that
- * AWT component is not in an appropriate state for the requested operation.
- * 
- * @since Android 1.0
- */
-public class IllegalComponentStateException extends IllegalStateException {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -1889339587208144238L;
-
-    /**
-     * Instantiates a new IllegalComponentStateException with the specified
-     * message.
-     * 
-     * @param s
-     *            the String message which describes the exception.
-     */
-    public IllegalComponentStateException(String s) {
-        super(s);
-    }
-
-    /**
-     * Instantiates a new IllegalComponentStateException without detailed
-     * message.
-     */
-    public IllegalComponentStateException() {
-    }
-
-}
diff --git a/awt/java/awt/Image.java b/awt/java/awt/Image.java
deleted file mode 100644
index 7ae3ed8..0000000
--- a/awt/java/awt/Image.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.image.AreaAveragingScaleFilter;
-import java.awt.image.FilteredImageSource;
-import java.awt.image.ImageFilter;
-import java.awt.image.ImageObserver;
-import java.awt.image.ImageProducer;
-import java.awt.image.ReplicateScaleFilter;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Image abstract class represents the graphic images.
- * 
- * @since Android 1.0
- */
-public abstract class Image {
-
-    /**
-     * The UndefinedProperty object should be returned if property is not
-     * defined for a particular image.
-     */
-    public static final Object UndefinedProperty = new Object(); // $NON-LOCK-1$
-
-    /**
-     * The Constant SCALE_DEFAULT indicates the default image scaling algorithm.
-     */
-    public static final int SCALE_DEFAULT = 1;
-
-    /**
-     * The Constant SCALE_FAST indicates an image scaling algorithm which places
-     * a higher priority on scaling speed than on the image's smoothness.
-     */
-    public static final int SCALE_FAST = 2;
-
-    /**
-     * The Constant SCALE_SMOOTH indicates an image scaling algorithm which
-     * places a higher priority on image smoothness than on scaling speed.
-     */
-    public static final int SCALE_SMOOTH = 4;
-
-    /**
-     * The Constant SCALE_REPLICATE indicates the image scaling algorithm in the
-     * ReplicateScaleFilter class.
-     */
-    public static final int SCALE_REPLICATE = 8;
-
-    /**
-     * The Constant SCALE_AREA_AVERAGING indicates the area averaging image
-     * scaling algorithm.
-     */
-    public static final int SCALE_AREA_AVERAGING = 16;
-
-    /**
-     * The acceleration priority indicates image acceleration.
-     */
-    protected float accelerationPriority = 0.5f;
-
-    /**
-     * The Constant capabilities.
-     */
-    private static final ImageCapabilities capabilities = new ImageCapabilities(false);
-
-    /**
-     * Gets the image property with the specified name. The UndefinedProperty
-     * object should be return if the property is not specified for this image.
-     * The return value should be null if the property is currently unknown yet
-     * and the specified ImageObserver is to be notified later.
-     * 
-     * @param name
-     *            the name of image's property.
-     * @param observer
-     *            the ImageObserver.
-     * @return the Object which represents value of the specified property.
-     */
-    public abstract Object getProperty(String name, ImageObserver observer);
-
-    /**
-     * Gets the ImageProducer object which represents data of this Image.
-     * 
-     * @return the ImageProducer object which represents data of this Image.
-     */
-    public abstract ImageProducer getSource();
-
-    /**
-     * Gets the width of this image. The specified ImageObserver object is
-     * notified when the width of this image is available.
-     * 
-     * @param observer
-     *            the ImageObserver object which is is notified when the width
-     *            of this image is available.
-     * @return the width of image, or -1 if the width of this image is not
-     *         available.
-     */
-    public abstract int getWidth(ImageObserver observer);
-
-    /**
-     * Gets the height of this image. The specified ImageObserver object is
-     * notified when the height of this image is available.
-     * 
-     * @param observer
-     *            the ImageObserver object which is is notified when the height
-     *            of this image is available.
-     * @return the height of image, or -1 if the height of this image is not
-     *         available.
-     */
-    public abstract int getHeight(ImageObserver observer);
-
-    /**
-     * Gets the scaled instance of this Image. This method returns an Image
-     * object constructed from the source of this image with the specified
-     * width, height, and applied scaling algorithm.
-     * 
-     * @param width
-     *            the width of scaled Image.
-     * @param height
-     *            the height of scaled Image.
-     * @param hints
-     *            the constant which indicates scaling algorithm.
-     * @return the scaled Image.
-     */
-    public Image getScaledInstance(int width, int height, int hints) {
-        ImageFilter filter;
-        if ((hints & (SCALE_SMOOTH | SCALE_AREA_AVERAGING)) != 0) {
-            filter = new AreaAveragingScaleFilter(width, height);
-        } else {
-            filter = new ReplicateScaleFilter(width, height);
-        }
-        ImageProducer producer = new FilteredImageSource(getSource(), filter);
-        return Toolkit.getDefaultToolkit().createImage(producer);
-    }
-
-    /**
-     * Gets a Graphics object for rendering this image. This method can be used
-     * for off-screen images.
-     * 
-     * @return a Graphics object for rendering to this image.
-     */
-    public abstract Graphics getGraphics();
-
-    /**
-     * Flushes resources which are used by this Image object. This method resets
-     * the image to the reconstructed state from the image's source.
-     */
-    public abstract void flush();
-
-    /**
-     * Gets the acceleration priority of this image.
-     * 
-     * @return the acceleration priority of this image.
-     */
-    public float getAccelerationPriority() {
-        return accelerationPriority;
-    }
-
-    /**
-     * Sets the acceleration priority for this image.
-     * 
-     * @param priority
-     *            the new acceleration priority (value in the range 0-1).
-     */
-    public void setAccelerationPriority(float priority) {
-        if (priority < 0 || priority > 1) {
-            // awt.10A=Priority must be a value between 0 and 1, inclusive
-            throw new IllegalArgumentException(Messages.getString("awt.10A")); //$NON-NLS-1$
-        }
-        accelerationPriority = priority;
-    }
-
-    /**
-     * Gets an ImageCapabilities object of this Image object for the specified
-     * GraphicsConfiguration.
-     * 
-     * @param gc
-     *            the specified GraphicsConfiguration object (null value means
-     *            default GraphicsConfiguration).
-     * @return an ImageCapabilities object of this Image object for the
-     *         specified GraphicsConfiguration.
-     */
-    public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
-        // Note: common image is not accelerated.
-        return capabilities;
-    }
-}
diff --git a/awt/java/awt/ImageCapabilities.java b/awt/java/awt/ImageCapabilities.java
deleted file mode 100644
index c6d5946..0000000
--- a/awt/java/awt/ImageCapabilities.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * The ImageCapabilities class gives information about an image's capabilities.
- * 
- * @since Android 1.0
- */
-public class ImageCapabilities implements Cloneable {
-
-    /**
-     * The accelerated.
-     */
-    private final boolean accelerated;
-
-    /**
-     * Instantiates a new ImageCapabilities with the specified acceleration flag
-     * which indicates whether acceleration is desired or not.
-     * 
-     * @param accelerated
-     *            the accelerated flag.
-     */
-    public ImageCapabilities(boolean accelerated) {
-        this.accelerated = accelerated;
-    }
-
-    /**
-     * Returns a copy of this ImageCapabilities object.
-     * 
-     * @return the copy of this ImageCapabilities object.
-     */
-    @Override
-    public Object clone() {
-        return new ImageCapabilities(accelerated);
-    }
-
-    /**
-     * Returns true if the Image of this ImageCapabilities is or can be
-     * accelerated.
-     * 
-     * @return true, if the Image of this ImageCapabilities is or can be
-     *         accelerated, false otherwise.
-     */
-    public boolean isAccelerated() {
-        return accelerated;
-    }
-
-    /**
-     * Returns true if this ImageCapabilities applies to the VolatileImage which
-     * can lose its surfaces.
-     * 
-     * @return true if this ImageCapabilities applies to the VolatileImage which
-     *         can lose its surfaces, false otherwise.
-     */
-    public boolean isTrueVolatile() {
-        return true;
-    }
-}
diff --git a/awt/java/awt/Insets.java b/awt/java/awt/Insets.java
deleted file mode 100644
index 04f198c6..0000000
--- a/awt/java/awt/Insets.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.io.Serializable;
-
-import org.apache.harmony.misc.HashCode;
-
-/**
- * The Insets class represents the borders of a container. This class describes
- * the space that a container should leave at each edge: the top, the bottom,
- * the right side, and the left side. The space can be filled with a border, a
- * blank space, or a title.
- * 
- * @since Android 1.0
- */
-public class Insets implements Cloneable, Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -2272572637695466749L;
-
-    /**
-     * The top inset indicates the size of the space added to the top of the
-     * rectangle.
-     */
-    public int top;
-
-    /**
-     * The left inset indicates the size of the space added to the left side of
-     * the rectangle.
-     */
-    public int left;
-
-    /**
-     * The bottom inset indicates the size of the space subtracted from the
-     * bottom of the rectangle.
-     */
-    public int bottom;
-
-    /**
-     * The right inset indicates the size of the space subtracted from the right
-     * side of the rectangle.
-     */
-    public int right;
-
-    /**
-     * Instantiates a new Inset object with the specified top, left, bottom,
-     * right parameters.
-     * 
-     * @param top
-     *            the top inset.
-     * @param left
-     *            the left inset.
-     * @param bottom
-     *            the bottom inset.
-     * @param right
-     *            the right inset.
-     */
-    public Insets(int top, int left, int bottom, int right) {
-        setValues(top, left, bottom, right);
-    }
-
-    /**
-     * Returns a hash code of the Insets object.
-     * 
-     * @return a hash code of the Insets object.
-     */
-    @Override
-    public int hashCode() {
-        int hashCode = HashCode.EMPTY_HASH_CODE;
-        hashCode = HashCode.combine(hashCode, top);
-        hashCode = HashCode.combine(hashCode, left);
-        hashCode = HashCode.combine(hashCode, bottom);
-        hashCode = HashCode.combine(hashCode, right);
-        return hashCode;
-    }
-
-    /**
-     * Returns a copy of this Insets object.
-     * 
-     * @return a copy of this Insets object.
-     */
-    @Override
-    public Object clone() {
-        return new Insets(top, left, bottom, right);
-    }
-
-    /**
-     * Checks if this Insets object is equal to the specified object.
-     * 
-     * @param o
-     *            the Object to be compared.
-     * @return true, if the object is an Insets object whose data values are
-     *         equal to those of this object, false otherwise.
-     */
-    @Override
-    public boolean equals(Object o) {
-        if (o == this) {
-            return true;
-        }
-        if (o instanceof Insets) {
-            Insets i = (Insets)o;
-            return ((i.left == left) && (i.bottom == bottom) && (i.right == right) && (i.top == top));
-        }
-        return false;
-    }
-
-    /**
-     * Returns a String representation of this Insets object.
-     * 
-     * @return a String representation of this Insets object.
-     */
-    @Override
-    public String toString() {
-        /*
-         * The format is based on 1.5 release behavior which can be revealed by
-         * the following code: System.out.println(new Insets(1, 2, 3, 4));
-         */
-
-        return (getClass().getName() + "[left=" + left + ",top=" + top + //$NON-NLS-1$ //$NON-NLS-2$
-                ",right=" + right + ",bottom=" + bottom + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    }
-
-    /**
-     * Sets top, left, bottom, and right insets to the specified values.
-     * 
-     * @param top
-     *            the top inset.
-     * @param left
-     *            the left inset.
-     * @param bottom
-     *            the bottom inset.
-     * @param right
-     *            the right inset.
-     */
-    public void set(int top, int left, int bottom, int right) {
-        setValues(top, left, bottom, right);
-    }
-
-    /**
-     * Sets the values.
-     * 
-     * @param top
-     *            the top.
-     * @param left
-     *            the left.
-     * @param bottom
-     *            the bottom.
-     * @param right
-     *            the right.
-     */
-    private void setValues(int top, int left, int bottom, int right) {
-        this.top = top;
-        this.left = left;
-        this.bottom = bottom;
-        this.right = right;
-    }
-}
diff --git a/awt/java/awt/ItemSelectable.java b/awt/java/awt/ItemSelectable.java
deleted file mode 100644
index 212cf70..0000000
--- a/awt/java/awt/ItemSelectable.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.event.ItemListener;
-
-/**
- * The ItemSelectable interface represents a set of items which can be selected.
- * 
- * @since Android 1.0
- */
-public interface ItemSelectable {
-
-    /**
-     * Adds an ItemListener for receiving item events when the state of an item
-     * is changed by the user.
-     * 
-     * @param l
-     *            the ItemListener.
-     */
-    public void addItemListener(ItemListener l);
-
-    /**
-     * Gets an array of the selected objects or null if there is no selected
-     * object.
-     * 
-     * @return an array of the selected objects or null if there is no selected
-     *         object.
-     */
-    public Object[] getSelectedObjects();
-
-    /**
-     * Removes the specified ItemListener.
-     * 
-     * @param l
-     *            the ItemListener which will be removed.
-     */
-    public void removeItemListener(ItemListener l);
-
-}
diff --git a/awt/java/awt/MenuComponent.java b/awt/java/awt/MenuComponent.java
deleted file mode 100644
index 9c1b120..0000000
--- a/awt/java/awt/MenuComponent.java
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.awt;
-
-import java.awt.event.FocusListener;
-import java.awt.event.MouseEvent;
-import java.awt.peer.MenuComponentPeer;
-import java.io.Serializable;
-import java.util.Locale; //import javax.accessibility.Accessible;
-//import javax.accessibility.AccessibleComponent;
-//import javax.accessibility.AccessibleContext;
-//import javax.accessibility.AccessibleRole;
-//import javax.accessibility.AccessibleSelection;
-//import javax.accessibility.AccessibleStateSet;
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.state.MenuItemState;
-import org.apache.harmony.awt.state.MenuState;
-import org.apache.harmony.luni.util.NotImplementedException;
-
-/**
- * The MenuComponent abstract class is the superclass for menu components. Menu
- * components receive and process AWT events.
- * 
- * @since Android 1.0
- */
-public abstract class MenuComponent implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -4536902356223894379L;
-
-    /**
-     * The name.
-     */
-    private String name;
-
-    /**
-     * The font.
-     */
-    private Font font;
-
-    /**
-     * The parent.
-     */
-    MenuContainer parent;
-
-    /**
-     * The deprecated event handler.
-     */
-    boolean deprecatedEventHandler = true;
-
-    /**
-     * The selected item index.
-     */
-    private int selectedItemIndex;
-
-    // ???AWT: private AccessibleContext accessibleContext;
-
-    /**
-     * The toolkit.
-     */
-    final Toolkit toolkit = Toolkit.getDefaultToolkit();
-
-    // ???AWT
-    /*
-     * protected abstract class AccessibleAWTMenuComponent extends
-     * AccessibleContext implements Serializable, AccessibleComponent,
-     * AccessibleSelection { private static final long serialVersionUID =
-     * -4269533416223798698L; public void addFocusListener(FocusListener
-     * listener) { } public boolean contains(Point pt) { return false; } public
-     * Accessible getAccessibleAt(Point pt) { return null; } public Color
-     * getBackground() { return null; } public Rectangle getBounds() { return
-     * null; } public Cursor getCursor() { return null; } public Font getFont()
-     * { return MenuComponent.this.getFont(); } public FontMetrics
-     * getFontMetrics(Font font) { return null; } public Color getForeground() {
-     * return null; } public Point getLocation() { return null; } public Point
-     * getLocationOnScreen() { return null; } public Dimension getSize() {
-     * return null; } public boolean isEnabled() { return true; // always
-     * enabled } public boolean isFocusTraversable() { return true; // always
-     * focus traversable } public boolean isShowing() { return true;// always
-     * showing } public boolean isVisible() { return true; // always visible }
-     * public void removeFocusListener(FocusListener listener) { } public void
-     * requestFocus() { } public void setBackground(Color color) { } public void
-     * setBounds(Rectangle rect) { } public void setCursor(Cursor cursor) { }
-     * public void setEnabled(boolean enabled) { } public void setFont(Font
-     * font) { MenuComponent.this.setFont(font); } public void
-     * setForeground(Color color) { } public void setLocation(Point pt) { }
-     * public void setSize(Dimension pt) { } public void setVisible(boolean
-     * visible) { } public void addAccessibleSelection(int index) { } public
-     * void clearAccessibleSelection() { } public Accessible
-     * getAccessibleSelection(int index) { return null; } public int
-     * getAccessibleSelectionCount() { return 0; } public boolean
-     * isAccessibleChildSelected(int index) { return false; } public void
-     * removeAccessibleSelection(int index) { } public void
-     * selectAllAccessibleSelection() { }
-     * @Override public Accessible getAccessibleChild(int index) { return null;
-     * }
-     * @Override public int getAccessibleChildrenCount() { return 0; }
-     * @Override public AccessibleComponent getAccessibleComponent() { return
-     * this; }
-     * @Override public String getAccessibleDescription() { return
-     * super.getAccessibleDescription(); }
-     * @Override public int getAccessibleIndexInParent() { toolkit.lockAWT();
-     * try { Accessible aParent = getAccessibleParent(); int aIndex = -1; if
-     * (aParent instanceof MenuComponent) { MenuComponent parent =
-     * (MenuComponent) aParent; int count = parent.getItemCount(); for (int i =
-     * 0; i < count; i++) { MenuComponent comp = parent.getItem(i); if (comp
-     * instanceof Accessible) { aIndex++; if (comp == MenuComponent.this) {
-     * return aIndex; } } } } return -1; } finally { toolkit.unlockAWT(); } }
-     * @Override public String getAccessibleName() { return
-     * super.getAccessibleName(); }
-     * @Override public Accessible getAccessibleParent() { toolkit.lockAWT();
-     * try { Accessible aParent = super.getAccessibleParent(); if (aParent !=
-     * null) { return aParent; } MenuContainer parent = getParent(); if (parent
-     * instanceof Accessible) { aParent = (Accessible) parent; } return aParent;
-     * } finally { toolkit.unlockAWT(); } }
-     * @Override public AccessibleRole getAccessibleRole() { return
-     * AccessibleRole.AWT_COMPONENT; }
-     * @Override public AccessibleSelection getAccessibleSelection() { return
-     * this; }
-     * @Override public AccessibleStateSet getAccessibleStateSet() { return new
-     * AccessibleStateSet(); }
-     * @Override public Locale getLocale() { return Locale.getDefault(); } }
-     */
-
-    /**
-     * The accessor to MenuComponent internal state, utilized by the visual
-     * theme.
-     * 
-     * @throws HeadlessException
-     *             the headless exception.
-     */
-    // ???AWT
-    /*
-     * class State implements MenuState { Dimension size; Dimension getSize() {
-     * if (size == null) { calculate(); } return size; } public int getWidth() {
-     * return getSize().width; } public int getHeight() { return
-     * getSize().height; } public Font getFont() { return
-     * MenuComponent.this.getFont(); } public int getItemCount() { return
-     * MenuComponent.this.getItemCount(); } public int getSelectedItemIndex() {
-     * return MenuComponent.this.getSelectedItemIndex(); } public boolean
-     * isFontSet() { return MenuComponent.this.isFontSet(); }
-     * @SuppressWarnings("deprecation") public FontMetrics getFontMetrics(Font
-     * f) { return MenuComponent.this.toolkit.getFontMetrics(f); } public Point
-     * getLocation() { return MenuComponent.this.getLocation(); } public
-     * MenuItemState getItem(int index) { MenuItem item =
-     * MenuComponent.this.getItem(index); return item.itemState; } public void
-     * setSize(int w, int h) { this.size = new Dimension(w, h); } void
-     * calculate() { size = new Dimension();
-     * size.setSize(toolkit.theme.calculateMenuSize(this)); } void reset() { for
-     * (int i = 0; i < getItemCount(); i++) { ((MenuItem.State)
-     * getItem(i)).reset(); } } }
-     */
-
-    /**
-     * Pop-up box for menu. It transfers the paint events, keyboard and mouse
-     * events to the menu component itself.
-     */
-    // ???AWT
-    /*
-     * class MenuPopupBox extends PopupBox { private final Point lastMousePos =
-     * new Point();
-     * @Override boolean isMenu() { return true; }
-     * @Override void paint(Graphics gr) { MenuComponent.this.paint(gr); }
-     * @Override void onKeyEvent(int eventId, int vKey, long when, int
-     * modifiers) { MenuComponent.this.onKeyEvent(eventId, vKey, when,
-     * modifiers); }
-     * @Override void onMouseEvent(int eventId, Point where, int mouseButton,
-     * long when, int modifiers, int wheelRotation) { // prevent conflict of
-     * mouse and keyboard // when sub-menu drops down due to keyboard navigation
-     * if (lastMousePos.equals(where) && (eventId == MouseEvent.MOUSE_MOVED ||
-     * eventId == MouseEvent.MOUSE_ENTERED)) { return; }
-     * lastMousePos.setLocation(where); MenuComponent.this.onMouseEvent(eventId,
-     * where, mouseButton, when, modifiers); } }
-     */
-
-    /**
-     * Instantiates a new MenuComponent object.
-     * 
-     * @throws HeadlessException
-     *             if the graphical interface environment can't support
-     *             MenuComponents.
-     */
-    public MenuComponent() throws HeadlessException {
-        toolkit.lockAWT();
-        try {
-            Toolkit.checkHeadless();
-            name = autoName();
-            selectedItemIndex = -1;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the name of the MenuComponent object.
-     * 
-     * @return the name of the MenuComponent object.
-     */
-    public String getName() {
-        toolkit.lockAWT();
-        try {
-            return name;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Returns a String representation of the MenuComponent object.
-     * 
-     * @return a String representation of the MenuComponent object.
-     */
-    @Override
-    public String toString() {
-        toolkit.lockAWT();
-        try {
-            return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the parent menu container.
-     * 
-     * @return the parent.
-     */
-    public MenuContainer getParent() {
-        toolkit.lockAWT();
-        try {
-            return parent;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the name of the MenuComponent to the specified string.
-     * 
-     * @param name
-     *            the new name of the MenuComponent object.
-     */
-    public void setName(String name) {
-        toolkit.lockAWT();
-        try {
-            this.name = name;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Dispatches AWT event.
-     * 
-     * @param event
-     *            the AWTEvent.
-     */
-    public final void dispatchEvent(AWTEvent event) {
-        toolkit.lockAWT();
-        try {
-            processEvent(event);
-            if (deprecatedEventHandler) {
-                postDeprecatedEvent(event);
-            }
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Post deprecated event.
-     * 
-     * @param event
-     *            the event.
-     */
-    void postDeprecatedEvent(AWTEvent event) {
-        Event evt = event.getEvent();
-        if (evt != null) {
-            postEvent(evt);
-        }
-    }
-
-    /**
-     * Gets the peer of the MenuComponent; an application must not use this
-     * method directly.
-     * 
-     * @return the MenuComponentPeer object.
-     * @throws NotImplementedException
-     *             if this method is not implemented by a subclass.
-     * @deprecated an application must not use this method directly.
-     */
-    @Deprecated
-    public MenuComponentPeer getPeer() throws org.apache.harmony.luni.util.NotImplementedException {
-        toolkit.lockAWT();
-        try {
-        } finally {
-            toolkit.unlockAWT();
-        }
-        if (true) {
-            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
-        }
-        return null;
-    }
-
-    /**
-     * Gets the locking object of this MenuComponent.
-     * 
-     * @return the locking object of this MenuComponent.
-     */
-    protected final Object getTreeLock() {
-        return toolkit.awtTreeLock;
-    }
-
-    /**
-     * Posts the Event to the MenuComponent.
-     * 
-     * @param e
-     *            the Event.
-     * @return true, if the event is posted successfully, false otherwise.
-     * @deprecated Replaced dispatchEvent method.
-     */
-    @SuppressWarnings("deprecation")
-    @Deprecated
-    public boolean postEvent(Event e) {
-        toolkit.lockAWT();
-        try {
-            if (parent != null) {
-                return parent.postEvent(e);
-            }
-            return false;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Returns the string representation of the MenuComponent state.
-     * 
-     * @return returns the string representation of the MenuComponent state.
-     */
-    protected String paramString() {
-        toolkit.lockAWT();
-        try {
-            return getName();
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    // ???AWT
-    /*
-     * public AccessibleContext getAccessibleContext() { toolkit.lockAWT(); try
-     * { if (accessibleContext == null) { accessibleContext =
-     * createAccessibleContext(); } return accessibleContext; } finally {
-     * toolkit.unlockAWT(); } }
-     */
-
-    /**
-     * Gets the font of the MenuComponent object.
-     * 
-     * @return the Font of the MenuComponent object.
-     */
-    public Font getFont() {
-        toolkit.lockAWT();
-        try {
-            if (font == null && hasDefaultFont()) {
-                return toolkit.getDefaultFont();
-            }
-            if (font == null && parent != null) {
-                return parent.getFont();
-            }
-            return font;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Checks if is font set.
-     * 
-     * @return true, if is font set
-     */
-    boolean isFontSet() {
-        return font != null
-                || ((parent instanceof MenuComponent) && ((MenuComponent)parent).isFontSet());
-    }
-
-    /**
-     * Checks for default font.
-     * 
-     * @return true, if successful.
-     */
-    boolean hasDefaultFont() {
-        return false;
-    }
-
-    /**
-     * Processes an AWTEevent on this menu component.
-     * 
-     * @param event
-     *            the AWTEvent.
-     */
-    protected void processEvent(AWTEvent event) {
-        toolkit.lockAWT();
-        try {
-            // do nothing
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Removes the peer of the MenuComponent.
-     */
-    public void removeNotify() {
-        toolkit.lockAWT();
-        try {
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the Font for this MenuComponent object.
-     * 
-     * @param font
-     *            the new Font to be used for this MenuComponent.
-     */
-    public void setFont(Font font) {
-        toolkit.lockAWT();
-        try {
-            this.font = font;
-        } finally {
-            toolkit.unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the parent.
-     * 
-     * @param parent
-     *            the new parent.
-     */
-    void setParent(MenuContainer parent) {
-        this.parent = parent;
-    }
-
-    /**
-     * Gets the location.
-     * 
-     * @return the location.
-     */
-    Point getLocation() {
-        // to be overridden
-        return new Point(0, 0);
-    }
-
-    /**
-     * Gets the width.
-     * 
-     * @return the width.
-     */
-    int getWidth() {
-        // to be overridden
-        return 1;
-    }
-
-    /**
-     * Gets the height.
-     * 
-     * @return the height.
-     */
-    int getHeight() {
-        // to be overridden
-        return 1;
-    }
-
-    /**
-     * Recursively find the menu item for a menu shortcut.
-     * 
-     * @param gr
-     *            the gr.
-     * @return the menu item; or null if the item is not available for this
-     *         shortcut.
-     */
-    // ???AWT
-    /*
-     * MenuItem getShortcutMenuItemImpl(MenuShortcut ms) { if (ms == null) {
-     * return null; } for (int i = 0; i < getItemCount(); i++) { MenuItem mi =
-     * getItem(i); if (mi instanceof Menu) { mi = ((Menu)
-     * mi).getShortcutMenuItemImpl(ms); if (mi != null) { return mi; } } else if
-     * (ms.equals(mi.getShortcut())) { return mi; } } return null; }
-     */
-
-    void paint(Graphics gr) {
-        gr.setColor(Color.LIGHT_GRAY);
-        gr.fillRect(0, 0, getWidth(), getHeight());
-        gr.setColor(Color.BLACK);
-    }
-
-    /**
-     * Mouse events handler.
-     * 
-     * @param eventId
-     *            one of the MouseEvent.MOUSE_* constants.
-     * @param where
-     *            mouse location.
-     * @param mouseButton
-     *            mouse button that was pressed or released.
-     * @param when
-     *            event time.
-     * @param modifiers
-     *            input event modifiers.
-     */
-    void onMouseEvent(int eventId, Point where, int mouseButton, long when, int modifiers) {
-        // to be overridden
-    }
-
-    /**
-     * Keyboard event handler.
-     * 
-     * @param eventId
-     *            one of the KeyEvent.KEY_* constants.
-     * @param vKey
-     *            the key code.
-     * @param when
-     *            event time.
-     * @param modifiers
-     *            input event modifiers.
-     */
-    void onKeyEvent(int eventId, int vKey, long when, int modifiers) {
-        // to be overridden
-    }
-
-    /**
-     * Post the ActionEvent or ItemEvent, depending on type of the menu item.
-     * 
-     * @param index
-     *            the index.
-     * @return the item rect.
-     */
-    // ???AWT
-    /*
-     * void fireItemAction(int item, long when, int modifiers) { MenuItem mi =
-     * getItem(item); mi.itemSelected(when, modifiers); } MenuItem getItem(int
-     * index) { // to be overridden return null; } int getItemCount() { return
-     * 0; }
-     */
-
-    /**
-     * @return The sub-menu of currently selecetd item, or null if such a
-     *         sub-menu is not available.
-     */
-    // ???AWT
-    /*
-     * Menu getSelectedSubmenu() { if (selectedItemIndex < 0) { return null; }
-     * MenuItem item = getItem(selectedItemIndex); return (item instanceof Menu)
-     * ? (Menu) item : null; }
-     */
-
-    /**
-     * Convenience method for selectItem(index, true).
-     */
-    // ???AWT
-    /*
-     * void selectItem(int index) { selectItem(index, true); }
-     */
-
-    /**
-     * Change the selection in the menu.
-     * 
-     * @param index
-     *            new selecetd item's index.
-     * @param showSubMenu
-     *            if new selected item has a sub-menu, should that sub-menu be
-     *            displayed.
-     */
-    // ???AWT
-    /*
-     * void selectItem(int index, boolean showSubMenu) { if (selectedItemIndex
-     * == index) { return; } if (selectedItemIndex >= 0 &&
-     * getItem(selectedItemIndex) instanceof Menu) { ((Menu)
-     * getItem(selectedItemIndex)).hide(); } MultiRectArea clip =
-     * getUpdateClip(index, selectedItemIndex); selectedItemIndex = index;
-     * Graphics gr = getGraphics(clip); if (gr != null) { paint(gr); } if
-     * (showSubMenu) { showSubMenu(selectedItemIndex); } }
-     */
-
-    /**
-     * Change the selected item to the next one in the requested direction
-     * moving cyclically, skipping separators
-     * 
-     * @param forward
-     *            the direction to move the selection.
-     * @param showSubMenu
-     *            if new selected item has a sub-menu, should that sub-menu be
-     *            displayed.
-     */
-    // ???AWT
-    /*
-     * void selectNextItem(boolean forward, boolean showSubMenu) { int selected
-     * = getSelectedItemIndex(); int count = getItemCount(); if (count == 0) {
-     * return; } if (selected < 0) { selected = (forward ? count - 1 : 0); } int
-     * i = selected; do { i = (forward ? (i + 1) : (i + count - 1)) % count; i
-     * %= count; MenuItem item = getItem(i); if (!"-".equals(item.getLabel())) {
-     * //$NON-NLS-1$ selectItem(i, showSubMenu); return; } } while (i !=
-     * selected); } void showSubMenu(int index) { if ((index < 0) ||
-     * !isActive()) { return; } MenuItem item = getItem(index); if (item
-     * instanceof Menu) { Menu menu = ((Menu) getItem(index)); if
-     * (menu.getItemCount() == 0) { return; } Point location =
-     * getSubmenuLocation(index); menu.show(location.x, location.y, false); } }
-     */
-
-    /**
-     * @return the menu bar which is the root of current menu's hierarchy; or
-     *         null if the hierarchy root is not a menu bar.
-     */
-    // ???AWT
-    /*
-     * MenuBar getMenuBar() { if (parent instanceof MenuBar) { return (MenuBar)
-     * parent; } if (parent instanceof MenuComponent) { return ((MenuComponent)
-     * parent).getMenuBar(); } return null; } PopupBox getPopupBox() { return
-     * null; }
-     */
-
-    Rectangle getItemRect(int index) {
-        // to be overridden
-        return null;
-    }
-
-    /**
-     * Determine the clip region when menu selection is changed from index1 to
-     * index2.
-     * 
-     * @param index1
-     *            old selected item.
-     * @param index2
-     *            new selected item.
-     * @return the region to repaint.
-     */
-    final MultiRectArea getUpdateClip(int index1, int index2) {
-        MultiRectArea clip = new MultiRectArea();
-        if (index1 >= 0) {
-            clip.add(getItemRect(index1));
-        }
-        if (index2 >= 0) {
-            clip.add(getItemRect(index2));
-        }
-        return clip;
-    }
-
-    /**
-     * Gets the submenu location.
-     * 
-     * @param index
-     *            the index.
-     * @return the submenu location.
-     */
-    Point getSubmenuLocation(int index) {
-        // to be overridden
-        return new Point(0, 0);
-    }
-
-    /**
-     * Gets the selected item index.
-     * 
-     * @return the selected item index.
-     */
-    int getSelectedItemIndex() {
-        return selectedItemIndex;
-    }
-
-    /**
-     * Hide.
-     */
-    void hide() {
-        selectedItemIndex = -1;
-        if (parent instanceof MenuComponent) {
-            ((MenuComponent)parent).itemHidden(this);
-        }
-    }
-
-    /**
-     * Item hidden.
-     * 
-     * @param mc
-     *            the mc.
-     */
-    void itemHidden(MenuComponent mc) {
-        // to be overridden
-    }
-
-    /**
-     * Checks if is visible.
-     * 
-     * @return true, if is visible.
-     */
-    boolean isVisible() {
-        return true;
-    }
-
-    /**
-     * Checks if is active.
-     * 
-     * @return true, if is active.
-     */
-    boolean isActive() {
-        return true;
-    }
-
-    /**
-     * Hide all menu hierarchy.
-     */
-    void endMenu() {
-        // ???AWT: toolkit.dispatcher.popupDispatcher.deactivateAll();
-    }
-
-    /**
-     * Handle the mouse click or Enter key event on a menu's item.
-     * 
-     * @param when
-     *            the event time.
-     * @param modifiers
-     *            input event modifiers.
-     */
-    void itemSelected(long when, int modifiers) {
-        endMenu();
-    }
-
-    /**
-     * Auto name.
-     * 
-     * @return the string.
-     */
-    String autoName() {
-        String name = getClass().getName();
-        if (name.indexOf("$") != -1) { //$NON-NLS-1$
-            return null;
-        }
-        // ???AWT: int number = toolkit.autoNumber.nextMenuComponent++;
-        int number = 0;
-        name = name.substring(name.lastIndexOf(".") + 1) + Integer.toString(number); //$NON-NLS-1$
-        return name;
-    }
-
-    /**
-     * Creates the Graphics object for the pop-up box of this menu component.
-     * 
-     * @param clip
-     *            the clip to set on this Graphics.
-     * @return the created Graphics object, or null if such object is not
-     *         available.
-     */
-    Graphics getGraphics(MultiRectArea clip) {
-        // to be overridden
-        return null;
-    }
-
-    /**
-     * @return accessible context specific for particular menu component.
-     */
-    // ???AWT
-    /*
-     * AccessibleContext createAccessibleContext() { return null; }
-     */
-}
diff --git a/awt/java/awt/MenuContainer.java b/awt/java/awt/MenuContainer.java
deleted file mode 100644
index e509a1b..0000000
--- a/awt/java/awt/MenuContainer.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * The MenuContainer interface represents all menu containers.
- * 
- * @since Android 1.0
- */
-public interface MenuContainer {
-
-    /**
-     * Removes the specified MenuComponent from the MenuContainer.
-     * 
-     * @param c
-     *            the MenuComponent.
-     */
-    public void remove(MenuComponent c);
-
-    /**
-     * Gets the Font of the MenuContainer.
-     * 
-     * @return the font of the MenuContainer.
-     */
-    public Font getFont();
-
-    /**
-     * Posts an Event.
-     * 
-     * @param e
-     *            the Event.
-     * @return true if the event is posted successfully, false otherwise.
-     * @deprecated Replaced by dispatchEvent method.
-     */
-    @Deprecated
-    public boolean postEvent(Event e);
-
-}
diff --git a/awt/java/awt/ModalContext.java b/awt/java/awt/ModalContext.java
deleted file mode 100644
index 32a5912..0000000
--- a/awt/java/awt/ModalContext.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt;
-
-/**
- *
- * The context for nested event loop. It can be dialog, popup menu etc.
- */
-class ModalContext {
-
-    private boolean running = false;
-
-    private final Toolkit toolkit;
-
-    ModalContext() {
-        toolkit = Toolkit.getDefaultToolkit();
-    }
-
-    /**
-     * Set up and run modal loop in this context
-     *
-     */
-    void runModalLoop() {
-        running = true;
-        toolkit.dispatchThread.runModalLoop(this);
-    }
-
-    /**
-     * Leave the modal loop running in this context
-     * This method doesn't stops the loop immediately,
-     * it just sets the flag that says the modal loop to stop
-     *
-     */
-    void endModalLoop() {
-        running = false;
-    }
-
-    /**
-     *
-     * @return modal loop is currently running in this context
-     */
-    boolean isModalLoopRunning() {
-        return running;
-    }
-
-}
diff --git a/awt/java/awt/MouseDispatcher.java b/awt/java/awt/MouseDispatcher.java
deleted file mode 100644
index df48f9d..0000000
--- a/awt/java/awt/MouseDispatcher.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev, Michael Danilov, Pavel Dolgov
- * @version $Revision$
- */
-package java.awt;
-
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
-import java.awt.Dispatcher.MouseGrabManager;
-import java.util.EventListener;
-
-import org.apache.harmony.awt.wtk.NativeEvent;
-import org.apache.harmony.awt.wtk.NativeWindow;
-
-
-class MouseDispatcher {
-
-    // Fields for synthetic mouse click events generation
-    private static final int clickDelta = 5;
-    private final long[] lastPressTime = new long[] {0l, 0l, 0l};
-    private final Point[] lastPressPos = new Point[] {null, null, null};
-    private final boolean[] buttonPressed = new boolean[] {false, false, false};
-    private final int[] clickCount = new int[] {0, 0, 0};
-
-    // Fields for mouse entered/exited support
-    private Component lastUnderPointer = null;
-    private final Point lastScreenPos = new Point(-1, -1);
-
-    // Fields for redundant mouse moved/dragged filtering
-    private Component lastUnderMotion = null;
-    private Point lastLocalPos = new Point(-1, -1);
-
-    private final MouseGrabManager mouseGrabManager;
-    private final Toolkit toolkit;
-
-    static Point convertPoint(Component src, int x, int y, Component dest) {
-        Point srcPoint = getAbsLocation(src);
-        Point destPoint = getAbsLocation(dest);
-
-        return new Point(x + (srcPoint.x - destPoint.x),
-                         y + (srcPoint.y - destPoint.y));
-    }
-
-    static Point convertPoint(Component src, Point p, Component dst) {
-        return convertPoint(src, p.x, p.y, dst);
-    }
-
-    private static Point getAbsLocation(Component comp) {
-        Point location = new Point(0, 0);
-// BEGIN android-changed: AWT components not supported
-//        for (Component parent = comp; parent != null; parent = parent.parent) {
-//            Point parentPos = (parent instanceof EmbeddedWindow ?
-//                               parent.getNativeWindow().getScreenPos() :
-//                               parent.getLocation());
-//
-//            location.translate(parentPos.x, parentPos.y);
-//
-//            if (parent instanceof Window) {
-//                break;
-//            }
-//        }
-// END android-changed
-
-        return location;
-    }
-
-    MouseDispatcher(MouseGrabManager mouseGrabManager,
-                    Toolkit toolkit) {
-        this.mouseGrabManager = mouseGrabManager;
-        this.toolkit = toolkit;
-    }
-
-    Point getPointerPos() {
-        return lastScreenPos;
-    }
-
-    boolean dispatch(Component src, NativeEvent event) {
-        int id = event.getEventId();
-
-        lastScreenPos.setLocation(event.getScreenPos());
-        checkMouseEnterExit(event.getInputModifiers(), event.getTime());
-
-        if (id == MouseEvent.MOUSE_WHEEL) {
-// BEGIN android-changed: AWT components not supported
-//            dispatchWheelEvent(src, event);
-// END android-changed
-        } else if ((id != MouseEvent.MOUSE_ENTERED) &&
-                   (id != MouseEvent.MOUSE_EXITED)) {
-            PointerInfo info = new PointerInfo(src, event.getLocalPos());
-
-            mouseGrabManager.preprocessEvent(event);
-            findEventSource(info);
-            if ((id == MouseEvent.MOUSE_PRESSED) ||
-                (id == MouseEvent.MOUSE_RELEASED)) {
-
-                dispatchButtonEvent(info, event);
-            } else if ((id == MouseEvent.MOUSE_MOVED) ||
-                       (id == MouseEvent.MOUSE_DRAGGED)) {
-
-                dispatchMotionEvent(info, event);
-            }
-        }
-
-        return false;
-    }
-
-    private void checkMouseEnterExit(int modifiers, long when) {
-// BEGIN android-changed: AWT components not supported
-//        PointerInfo info = findComponentUnderPointer();
-//        Component curUnderPointer =
-//                propagateEvent(info, AWTEvent.MOUSE_EVENT_MASK,
-//                               MouseListener.class, false).src;
-//
-//        if (curUnderPointer != lastUnderPointer) {
-//            Point pos = info.position;
-//            if ((lastUnderPointer != null) &&
-//                 lastUnderPointer.isMouseExitedExpected()) {
-//
-//                Point exitPos = convertPoint(null, lastScreenPos.x,
-//                                             lastScreenPos.y, lastUnderPointer);
-//
-//                postMouseEnterExit(MouseEvent.MOUSE_EXITED, modifiers, when,
-//                                   exitPos.x, exitPos.y, lastUnderPointer);
-//            }
-//            setCursor(curUnderPointer);
-//            if (curUnderPointer != null) {
-//                postMouseEnterExit(MouseEvent.MOUSE_ENTERED, modifiers, when,
-//                                   pos.x, pos.y, curUnderPointer);
-//            }
-//            lastUnderPointer = curUnderPointer;
-//        }
-// END android-changed
-    }
-
-    private void setCursor(Component comp) {
-        if (comp == null) {
-            return;
-        }
-        Component grabOwner = mouseGrabManager.getSyntheticGrabOwner();
-        Component cursorComp = ((grabOwner != null) &&
-                                 grabOwner.isShowing() ? grabOwner : comp);
-        cursorComp.setCursor();
-    }
-
-    private void postMouseEnterExit(int id, int mod, long when,
-                                    int x, int y, Component comp) {
-        if (comp.isIndirectlyEnabled()) {
-            toolkit.getSystemEventQueueImpl().postEvent(
-                    new MouseEvent(comp, id, when, mod, x, y, 0, false));
-            comp.setMouseExitedExpected(id == MouseEvent.MOUSE_ENTERED);
-        } else {
-            comp.setMouseExitedExpected(false);
-        }
-    }
-
- // BEGIN android-changed: AWT components not supported
-//    private PointerInfo findComponentUnderPointer() {
-//        NativeWindow nativeWindow = toolkit.getWindowFactory().
-//        getWindowFromPoint(lastScreenPos);
-//
-//        if (nativeWindow != null) {
-//            Component comp = toolkit.getComponentById(nativeWindow.getId());
-//
-//            if (comp != null) {
-//                Window window = comp.getWindowAncestor();
-//                Point pointerPos = convertPoint(null, lastScreenPos.x,
-//                                                lastScreenPos.y, window);
-//
-//                if (window.getClient().contains(pointerPos)) {
-//                    PointerInfo info = new PointerInfo(window, pointerPos);
-//
-//                    fall2Child(info);
-//
-//                    return info;
-//                }
-//            }
-//        }
-//
-//        return new PointerInfo(null, null);
-//    }
-// END android-changed
-    
-    private void findEventSource(PointerInfo info) {
-        Component grabOwner = mouseGrabManager.getSyntheticGrabOwner();
-
-        if (grabOwner != null && grabOwner.isShowing()) {
-            info.position = convertPoint(info.src, info.position, grabOwner);
-            info.src = grabOwner;
-        } else {
-            //???AWT: rise2TopLevel(info);
-            //???AWT: fall2Child(info);
-        }
-    }
-
- // BEGIN android-changed: AWT components not supported
-//    private void rise2TopLevel(PointerInfo info) {
-//        while (!(info.src instanceof Window)) {
-//            info.position.translate(info.src.x, info.src.y);
-//            info.src = info.src.parent;
-//        }
-//    }
-//
-//    private void fall2Child(PointerInfo info) {
-//        Insets insets = info.src.getInsets();
-//
-//        final Point pos = info.position;
-//        final int x = pos.x;
-//        final int y = pos.y;
-//        if ((x >= insets.left) && (y >= insets.top) &&
-//                (x < (info.src.w - insets.right)) &&
-//                (y < (info.src.h - insets.bottom)))
-//        {
-//            Component[] children = ((Container) info.src).getComponents();
-//
-//            for (Component child : children) {
-//                if (child.isShowing()) {
-//                    if (child.contains(x - child.getX(),
-//                            y - child.getY()))
-//                    {
-//                        info.src = child;
-//                        pos.translate(-child.x, -child.y);
-//
-//                        if (child instanceof Container) {
-//                            fall2Child(info);
-//                        }
-//
-//                        return;
-//                    }
-//                }
-//            }
-//        }
-//    }
-// END android-changed
-
-    private void dispatchButtonEvent(PointerInfo info, NativeEvent event) {
-        int button = event.getMouseButton();
-        long time = event.getTime();
-        int id = event.getEventId();
-        int index = button - 1;
-        boolean clickRequired = false;
-
-        propagateEvent(info, AWTEvent.MOUSE_EVENT_MASK,
-                       MouseListener.class, false);
-        if (id == MouseEvent.MOUSE_PRESSED) {
-            int clickInterval = toolkit.dispatcher.clickInterval;
-            mouseGrabManager.onMousePressed(info.src);
-            buttonPressed[index] = true;
-            clickCount[index] = (!deltaExceeded(index, info) &&
-                    ((time - lastPressTime[index]) <= clickInterval)) ?
-                    clickCount[index] + 1 : 1;
-            lastPressTime[index] = time;
-            lastPressPos[index] = info.position;
-        } else {
-            mouseGrabManager.onMouseReleased(info.src);
-            // set cursor back on synthetic mouse grab end:
-// BEGIN android-changed: AWT components not supported
-//            setCursor(findComponentUnderPointer().src);
-// END android-changed
-            if (buttonPressed[index]) {
-                buttonPressed[index] = false;
-                clickRequired = !deltaExceeded(index, info);
-            } else {
-                clickCount[index] = 0;
-            }
-        }
-        if (info.src.isIndirectlyEnabled()) {
-            final Point pos = info.position;
-            final int mod = event.getInputModifiers();
-            toolkit.getSystemEventQueueImpl().postEvent(
-                            new MouseEvent(info.src, id, time, mod, pos.x,
-                            pos.y, clickCount[index],
-                            event.getTrigger(), button));
-            if (clickRequired) {
-                toolkit.getSystemEventQueueImpl().postEvent(
-                            new MouseEvent(info.src,
-                            MouseEvent.MOUSE_CLICKED,
-                            time, mod, pos.x, pos.y,
-                            clickCount[index], false,
-                            button));
-            }
-        }
-    }
-
-    private boolean deltaExceeded(int index, PointerInfo info) {
-        final Point lastPos = lastPressPos[index];
-        if (lastPos == null) {
-            return true;
-        }
-        return ((Math.abs(lastPos.x - info.position.x) > clickDelta) ||
-                (Math.abs(lastPos.y - info.position.y) > clickDelta));
-    }
-
-    private void dispatchMotionEvent(PointerInfo info, NativeEvent event) {
-        propagateEvent(info, AWTEvent.MOUSE_MOTION_EVENT_MASK,
-                       MouseMotionListener.class, false);
-        final Point pos = info.position;
-        if ((lastUnderMotion != info.src) ||
-            !lastLocalPos.equals(pos)) {
-
-            lastUnderMotion = info.src;
-            lastLocalPos = pos;
-
-            if (info.src.isIndirectlyEnabled()) {
-                toolkit.getSystemEventQueueImpl().postEvent(
-                            new MouseEvent(info.src, event.getEventId(),
-                            event.getTime(),
-                            event.getInputModifiers(),
-                            pos.x, pos.y, 0, false));
-            }
-        }
-    }
-
-    MouseWheelEvent createWheelEvent(Component src, NativeEvent event,
-                                     Point where) {
-
-        Integer scrollAmountProperty =
-            (Integer)toolkit.getDesktopProperty("awt.wheelScrollingSize"); //$NON-NLS-1$
-        int amount = 1;
-        int type = MouseWheelEvent.WHEEL_UNIT_SCROLL;
-
-        if (scrollAmountProperty != null) {
-            amount = scrollAmountProperty.intValue();
-            if (amount == -1) {
-                type = MouseWheelEvent.WHEEL_BLOCK_SCROLL;
-                amount = 1;
-            }
-        }
-        return new MouseWheelEvent(src, event.getEventId(),
-                event.getTime(), event.getInputModifiers(),
-                where.x, where.y, 0, false, type, amount,
-                event.getWheelRotation());
-    }
-
-// BEGIN android-changed: AWT components not supported
-//    private void dispatchWheelEvent(Component src, NativeEvent event) {
-//        PointerInfo info = findComponentUnderPointer();
-//
-//        if (info.src == null) {
-//            info.src = src;
-//            info.position = event.getLocalPos();
-//        }
-//
-//        propagateEvent(info, AWTEvent.MOUSE_WHEEL_EVENT_MASK,
-//                       MouseWheelListener.class, true);
-//        if ((info.src != null) && info.src.isIndirectlyEnabled()) {
-//            toolkit.getSystemEventQueueImpl().postEvent(
-//                    createWheelEvent(info.src, event, info.position));
-//        }
-//    }
-// END android-changed
-
-    private PointerInfo propagateEvent(PointerInfo info, long mask,
-                                       Class<? extends EventListener> type, boolean pierceHW) {
-        Component src = info.src;
-        while ((src != null) &&
-               (src.isLightweight() || pierceHW) &&
-              !(src.isMouseEventEnabled(mask) ||
-               (src.getListeners(type).length > 0))) {
-
-            info.position.translate(src.x, src.y);
-// BEGIN android-changed: AWT components not supported
-//            src = src.parent;
-// END android-changed
-            info.src = src;
-        }
-
-        return info;
-    }
-
-// BEGIN android-changed: AWT components not supported
-//    Window findWindowAt(Point p) {
-//        NativeWindow nativeWindow =
-//            toolkit.getWindowFactory().getWindowFromPoint(p);
-//
-//        Window window = null;
-//        if (nativeWindow != null) {
-//            Component comp = toolkit.getComponentById(nativeWindow.getId());
-//
-//            if (comp != null) {
-//                window = comp.getWindowAncestor();
-//            }
-//        }
-//        return window;
-//    }
-// END android-changed
-
-    private class PointerInfo {
-
-        Component src;
-        Point position;
-
-        PointerInfo(Component src, Point position) {
-            this.src = src;
-            this.position = position;
-        }
-
-    }
-
-}
diff --git a/awt/java/awt/Paint.java b/awt/java/awt/Paint.java
deleted file mode 100644
index dfea3a7..0000000
--- a/awt/java/awt/Paint.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.ColorModel;
-
-/**
- * The Paint interface provides possibility of generating color patterns in
- * device space for fill, draw, or stroke operations in a Graphics2D.
- * 
- * @since Android 1.0
- */
-public interface Paint extends Transparency {
-
-    /**
-     * Creates the PaintContext which is used to generate color patterns for
-     * rendering operations of Graphics2D.
-     * 
-     * @param cm
-     *            the ColorModel object, or null.
-     * @param deviceBounds
-     *            the Rectangle represents the bounding box of device space for
-     *            the graphics rendering operations.
-     * @param userBounds
-     *            the Rectangle represents bounding box of user space for the
-     *            graphics rendering operations.
-     * @param xform
-     *            the AffineTransform for translation from user space to device
-     *            space.
-     * @param hints
-     *            the RenderingHints preferences.
-     * @return the PaintContext for generating color patterns.
-     */
-    PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds,
-            AffineTransform xform, RenderingHints hints);
-}
diff --git a/awt/java/awt/PaintContext.java b/awt/java/awt/PaintContext.java
deleted file mode 100644
index 966b6ca..0000000
--- a/awt/java/awt/PaintContext.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.image.ColorModel;
-import java.awt.image.Raster;
-
-/**
- * The PaintContext interface determines the specific environment for generating
- * color patterns in device space for fill, draw, or stroke rendering operations
- * using Graphics2D. This interface provides colors through the Raster object
- * associated with the specific ColorModel for Graphics2D rendering operations.
- * 
- * @since Android 1.0
- */
-public interface PaintContext {
-
-    /**
-     * Releases the resources allocated for the operation.
-     */
-    void dispose();
-
-    /**
-     * Gets the color model.
-     * 
-     * @return the ColorModel object.
-     */
-    ColorModel getColorModel();
-
-    /**
-     * Gets the Raster which defines the colors of the specified rectangular
-     * area for Graphics2D rendering operations.
-     * 
-     * @param x
-     *            the X coordinate of the device space area for which colors are
-     *            generated.
-     * @param y
-     *            the Y coordinate of the device space area for which colors are
-     *            generated.
-     * @param w
-     *            the width of the device space area for which colors are
-     *            generated.
-     * @param h
-     *            the height of the device space area for which colors are
-     *            generated.
-     * @return the Raster object which contains the colors of the specified
-     *         rectangular area for Graphics2D rendering operations.
-     */
-    Raster getRaster(int x, int y, int w, int h);
-}
diff --git a/awt/java/awt/Point.java b/awt/java/awt/Point.java
deleted file mode 100644
index 8ec4241..0000000
--- a/awt/java/awt/Point.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.geom.Point2D;
-import java.io.Serializable;
-
-/**
- * The Point class represents a point location with coordinates X, Y in current
- * coordinate system.
- * 
- * @since Android 1.0
- */
-public class Point extends Point2D implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -5276940640259749850L;
-
-    /**
-     * The X coordinate of Point.
-     */
-    public int x;
-
-    /**
-     * The Y coordinate of Point.
-     */
-    public int y;
-
-    /**
-     * Instantiates a new point with (0, O) coordinates, the origin of
-     * coordinate system.
-     */
-    public Point() {
-        setLocation(0, 0);
-    }
-
-    /**
-     * Instantiates a new point with (x, y) coordinates.
-     * 
-     * @param x
-     *            the X coordinate of Point.
-     * @param y
-     *            the Y coordinate of Point.
-     */
-    public Point(int x, int y) {
-        setLocation(x, y);
-    }
-
-    /**
-     * Instantiates a new point, giving it the same location as the parameter p.
-     * 
-     * @param p
-     *            the Point object giving the coordinates of the new point.
-     */
-    public Point(Point p) {
-        setLocation(p.x, p.y);
-    }
-
-    /**
-     * Compares current Point with the specified object.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if the Object being compared is a Point whose coordinates
-     *         are equal to the coordinates of this Point, false otherwise.
-     * @see java.awt.geom.Point2D#equals(Object)
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (obj instanceof Point) {
-            Point p = (Point)obj;
-            return x == p.x && y == p.y;
-        }
-        return false;
-    }
-
-    /**
-     * Returns string representation of the current Point object.
-     * 
-     * @return a string representation of the current Point object.
-     */
-    @Override
-    public String toString() {
-        return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    }
-
-    /**
-     * Gets X coordinate of Point as a double.
-     * 
-     * @return X coordinate of the point as a double.
-     * @see java.awt.geom.Point2D#getX()
-     */
-    @Override
-    public double getX() {
-        return x;
-    }
-
-    /**
-     * Gets Y coordinate of Point as a double.
-     * 
-     * @return Y coordinate of the point as a double.
-     * @see java.awt.geom.Point2D#getY()
-     */
-    @Override
-    public double getY() {
-        return y;
-    }
-
-    /**
-     * Gets the location of the Point as a new Point object.
-     * 
-     * @return a copy of the Point.
-     */
-    public Point getLocation() {
-        return new Point(x, y);
-    }
-
-    /**
-     * Sets the location of the Point to the same coordinates as p.
-     * 
-     * @param p
-     *            the Point that gives the new location.
-     */
-    public void setLocation(Point p) {
-        setLocation(p.x, p.y);
-    }
-
-    /**
-     * Sets the location of the Point to the coordinates X, Y.
-     * 
-     * @param x
-     *            the X coordinate of the Point's new location.
-     * @param y
-     *            the Y coordinate of the Point's new location.
-     */
-    public void setLocation(int x, int y) {
-        this.x = x;
-        this.y = y;
-    }
-
-    /**
-     * Sets the location of Point to the specified double coordinates.
-     * 
-     * @param x
-     *            the X the Point's new location.
-     * @param y
-     *            the Y the Point's new location.
-     * @see java.awt.geom.Point2D#setLocation(double, double)
-     */
-    @Override
-    public void setLocation(double x, double y) {
-        x = x < Integer.MIN_VALUE ? Integer.MIN_VALUE : x > Integer.MAX_VALUE ? Integer.MAX_VALUE
-                : x;
-        y = y < Integer.MIN_VALUE ? Integer.MIN_VALUE : y > Integer.MAX_VALUE ? Integer.MAX_VALUE
-                : y;
-        setLocation((int)Math.round(x), (int)Math.round(y));
-    }
-
-    /**
-     * Moves the Point to the specified (x, y) location.
-     * 
-     * @param x
-     *            the X coordinate of the new location.
-     * @param y
-     *            the Y coordinate of the new location.
-     */
-    public void move(int x, int y) {
-        setLocation(x, y);
-    }
-
-    /**
-     * Translates current Point moving it from the position (x, y) to the new
-     * position given by (x+dx, x+dy) coordinates.
-     * 
-     * @param dx
-     *            the horizontal delta - the Point is moved to this distance
-     *            along X axis.
-     * @param dy
-     *            the vertical delta - the Point is moved to this distance along
-     *            Y axis.
-     */
-    public void translate(int dx, int dy) {
-        x += dx;
-        y += dy;
-    }
-
-}
diff --git a/awt/java/awt/Polygon.java b/awt/java/awt/Polygon.java
deleted file mode 100644
index de31eb9..0000000
--- a/awt/java/awt/Polygon.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.io.Serializable;
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.gl.*;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Polygon class defines an closed area specified by n vertices and n edges.
- * The coordinates of the vertices are specified by x, y arrays. The edges are
- * the line segments from the point (x[i], y[i]) to the point (x[i+1], y[i+1]),
- * for -1 < i < (n-1) plus the line segment from the point (x[n-1], y[n-1]) to
- * the point (x[0], y[0]) point. The Polygon is empty if the number of vertices
- * is zero.
- * 
- * @since Android 1.0
- */
-public class Polygon implements Shape, Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -6460061437900069969L;
-
-    /**
-     * The points buffer capacity.
-     */
-    private static final int BUFFER_CAPACITY = 4;
-
-    /**
-     * The number of Polygon vertices.
-     */
-    public int npoints;
-
-    /**
-     * The array of X coordinates of the vertices.
-     */
-    public int[] xpoints;
-
-    /**
-     * The array of Y coordinates of the vertices.
-     */
-    public int[] ypoints;
-
-    /**
-     * The smallest Rectangle that completely contains this Polygon.
-     */
-    protected Rectangle bounds;
-
-    /*
-     * Polygon path iterator
-     */
-    /**
-     * The internal Class Iterator.
-     */
-    class Iterator implements PathIterator {
-
-        /**
-         * The source Polygon object.
-         */
-        public Polygon p;
-
-        /**
-         * The path iterator transformation.
-         */
-        public AffineTransform t;
-
-        /**
-         * The current segment index.
-         */
-        public int index;
-
-        /**
-         * Constructs a new Polygon.Iterator for the given polygon and
-         * transformation
-         * 
-         * @param at
-         *            the AffineTransform object to apply rectangle path.
-         * @param p
-         *            the p.
-         */
-        public Iterator(AffineTransform at, Polygon p) {
-            this.p = p;
-            this.t = at;
-            if (p.npoints == 0) {
-                index = 1;
-            }
-        }
-
-        public int getWindingRule() {
-            return WIND_EVEN_ODD;
-        }
-
-        public boolean isDone() {
-            return index > p.npoints;
-        }
-
-        public void next() {
-            index++;
-        }
-
-        public int currentSegment(double[] coords) {
-            if (isDone()) {
-                // awt.110=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
-            }
-            if (index == p.npoints) {
-                return SEG_CLOSE;
-            }
-            coords[0] = p.xpoints[index];
-            coords[1] = p.ypoints[index];
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, 1);
-            }
-            return index == 0 ? SEG_MOVETO : SEG_LINETO;
-        }
-
-        public int currentSegment(float[] coords) {
-            if (isDone()) {
-                // awt.110=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
-            }
-            if (index == p.npoints) {
-                return SEG_CLOSE;
-            }
-            coords[0] = p.xpoints[index];
-            coords[1] = p.ypoints[index];
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, 1);
-            }
-            return index == 0 ? SEG_MOVETO : SEG_LINETO;
-        }
-    }
-
-    /**
-     * Instantiates a new empty polygon.
-     */
-    public Polygon() {
-        xpoints = new int[BUFFER_CAPACITY];
-        ypoints = new int[BUFFER_CAPACITY];
-    }
-
-    /**
-     * Instantiates a new polygon with the specified number of vertices, and the
-     * given arrays of x, y vertex coordinates. The length of each coordinate
-     * array may not be less than the specified number of vertices but may be
-     * greater. Only the first n elements are used from each coordinate array.
-     * 
-     * @param xpoints
-     *            the array of X vertex coordinates.
-     * @param ypoints
-     *            the array of Y vertex coordinates.
-     * @param npoints
-     *            the number vertices of the polygon.
-     * @throws IndexOutOfBoundsException
-     *             if the length of xpoints or ypoints is less than n.
-     * @throws NegativeArraySizeException
-     *             if n is negative.
-     */
-    public Polygon(int[] xpoints, int[] ypoints, int npoints) {
-        if (npoints > xpoints.length || npoints > ypoints.length) {
-            // awt.111=Parameter npoints is greater than array length
-            throw new IndexOutOfBoundsException(Messages.getString("awt.111")); //$NON-NLS-1$
-        }
-        if (npoints < 0) {
-            // awt.112=Negative number of points
-            throw new NegativeArraySizeException(Messages.getString("awt.112")); //$NON-NLS-1$
-        }
-        this.npoints = npoints;
-        this.xpoints = new int[npoints];
-        this.ypoints = new int[npoints];
-        System.arraycopy(xpoints, 0, this.xpoints, 0, npoints);
-        System.arraycopy(ypoints, 0, this.ypoints, 0, npoints);
-    }
-
-    /**
-     * Resets the current Polygon to an empty Polygon. More precisely, the
-     * number of Polygon vertices is set to zero, but x, y coordinates arrays
-     * are not affected.
-     */
-    public void reset() {
-        npoints = 0;
-        bounds = null;
-    }
-
-    /**
-     * Invalidates the data that depends on the vertex coordinates. This method
-     * should be called after direct manipulations of the x, y vertex
-     * coordinates arrays to avoid unpredictable results of methods which rely
-     * on the bounding box.
-     */
-    public void invalidate() {
-        bounds = null;
-    }
-
-    /**
-     * Adds the point to the Polygon and updates the bounding box accordingly.
-     * 
-     * @param px
-     *            the X coordinate of the added vertex.
-     * @param py
-     *            the Y coordinate of the added vertex.
-     */
-    public void addPoint(int px, int py) {
-        if (npoints == xpoints.length) {
-            int[] tmp;
-
-            tmp = new int[xpoints.length + BUFFER_CAPACITY];
-            System.arraycopy(xpoints, 0, tmp, 0, xpoints.length);
-            xpoints = tmp;
-
-            tmp = new int[ypoints.length + BUFFER_CAPACITY];
-            System.arraycopy(ypoints, 0, tmp, 0, ypoints.length);
-            ypoints = tmp;
-        }
-
-        xpoints[npoints] = px;
-        ypoints[npoints] = py;
-        npoints++;
-
-        if (bounds != null) {
-            bounds.setFrameFromDiagonal(Math.min(bounds.getMinX(), px), Math.min(bounds.getMinY(),
-                    py), Math.max(bounds.getMaxX(), px), Math.max(bounds.getMaxY(), py));
-        }
-    }
-
-    /**
-     * Gets the bounding rectangle of the Polygon. The bounding rectangle is the
-     * smallest rectangle which contains the Polygon.
-     * 
-     * @return the bounding rectangle of the Polygon.
-     * @see java.awt.Shape#getBounds()
-     */
-    public Rectangle getBounds() {
-        if (bounds != null) {
-            return bounds;
-        }
-        if (npoints == 0) {
-            return new Rectangle();
-        }
-
-        int bx1 = xpoints[0];
-        int by1 = ypoints[0];
-        int bx2 = bx1;
-        int by2 = by1;
-
-        for (int i = 1; i < npoints; i++) {
-            int x = xpoints[i];
-            int y = ypoints[i];
-            if (x < bx1) {
-                bx1 = x;
-            } else if (x > bx2) {
-                bx2 = x;
-            }
-            if (y < by1) {
-                by1 = y;
-            } else if (y > by2) {
-                by2 = y;
-            }
-        }
-
-        return bounds = new Rectangle(bx1, by1, bx2 - bx1, by2 - by1);
-    }
-
-    /**
-     * Gets the bounding rectangle of the Polygon. The bounding rectangle is the
-     * smallest rectangle which contains the Polygon.
-     * 
-     * @return the bounding rectangle of the Polygon.
-     * @deprecated Use getBounds() method.
-     */
-    @Deprecated
-    public Rectangle getBoundingBox() {
-        return getBounds();
-    }
-
-    /**
-     * Gets the Rectangle2D which represents Polygon bounds. The bounding
-     * rectangle is the smallest rectangle which contains the Polygon.
-     * 
-     * @return the bounding rectangle of the Polygon.
-     * @see java.awt.Shape#getBounds2D()
-     */
-    public Rectangle2D getBounds2D() {
-        return getBounds().getBounds2D();
-    }
-
-    /**
-     * Translates all vertices of Polygon the specified distances along X, Y
-     * axis.
-     * 
-     * @param mx
-     *            the distance to translate horizontally.
-     * @param my
-     *            the distance to translate vertically.
-     */
-    public void translate(int mx, int my) {
-        for (int i = 0; i < npoints; i++) {
-            xpoints[i] += mx;
-            ypoints[i] += my;
-        }
-        if (bounds != null) {
-            bounds.translate(mx, my);
-        }
-    }
-
-    /**
-     * Checks whether or not the point given by the coordinates x, y lies inside
-     * the Polygon.
-     * 
-     * @param x
-     *            the X coordinate of the point to check.
-     * @param y
-     *            the Y coordinate of the point to check.
-     * @return true, if the specified point lies inside the Polygon, false
-     *         otherwise.
-     * @deprecated Use contains(int, int) method.
-     */
-    @Deprecated
-    public boolean inside(int x, int y) {
-        return contains((double)x, (double)y);
-    }
-
-    /**
-     * Checks whether or not the point given by the coordinates x, y lies inside
-     * the Polygon.
-     * 
-     * @param x
-     *            the X coordinate of the point to check.
-     * @param y
-     *            the Y coordinate of the point to check.
-     * @return true, if the specified point lies inside the Polygon, false
-     *         otherwise.
-     */
-    public boolean contains(int x, int y) {
-        return contains((double)x, (double)y);
-    }
-
-    /**
-     * Checks whether or not the point with specified double coordinates lies
-     * inside the Polygon.
-     * 
-     * @param x
-     *            the X coordinate of the point to check.
-     * @param y
-     *            the Y coordinate of the point to check.
-     * @return true, if the point given by the double coordinates lies inside
-     *         the Polygon, false otherwise.
-     * @see java.awt.Shape#contains(double, double)
-     */
-    public boolean contains(double x, double y) {
-        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, x, y));
-    }
-
-    /**
-     * Checks whether or not the rectangle determined by the parameters [x, y,
-     * width, height] lies inside the Polygon.
-     * 
-     * @param x
-     *            the X coordinate of the rectangles's left upper corner as a
-     *            double.
-     * @param y
-     *            the Y coordinate of the rectangles's left upper corner as a
-     *            double.
-     * @param width
-     *            the width of rectangle as a double.
-     * @param height
-     *            the height of rectangle as a double.
-     * @return true, if the specified rectangle lies inside the Polygon, false
-     *         otherwise.
-     * @see java.awt.Shape#contains(double, double, double, double)
-     */
-    public boolean contains(double x, double y, double width, double height) {
-        int cross = Crossing.intersectShape(this, x, y, width, height);
-        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
-    }
-
-    /**
-     * Checks whether or not the rectangle determined by the parameters [x, y,
-     * width, height] intersects the interior of the Polygon.
-     * 
-     * @param x
-     *            the X coordinate of the rectangles's left upper corner as a
-     *            double.
-     * @param y
-     *            the Y coordinate of the rectangles's left upper corner as a
-     *            double.
-     * @param width
-     *            the width of rectangle as a double.
-     * @param height
-     *            the height of rectangle as a double.
-     * @return true, if the specified rectangle intersects the interior of the
-     *         Polygon, false otherwise.
-     * @see java.awt.Shape#intersects(double, double, double, double)
-     */
-    public boolean intersects(double x, double y, double width, double height) {
-        int cross = Crossing.intersectShape(this, x, y, width, height);
-        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
-    }
-
-    /**
-     * Checks whether or not the specified rectangle lies inside the Polygon.
-     * 
-     * @param rect
-     *            the Rectangle2D object.
-     * @return true, if the specified rectangle lies inside the Polygon, false
-     *         otherwise.
-     * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D)
-     */
-    public boolean contains(Rectangle2D rect) {
-        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
-    }
-
-    /**
-     * Checks whether or not the specified Point lies inside the Polygon.
-     * 
-     * @param point
-     *            the Point object.
-     * @return true, if the specified Point lies inside the Polygon, false
-     *         otherwise.
-     */
-    public boolean contains(Point point) {
-        return contains(point.getX(), point.getY());
-    }
-
-    /**
-     * Checks whether or not the specified Point2D lies inside the Polygon.
-     * 
-     * @param point
-     *            the Point2D object.
-     * @return true, if the specified Point2D lies inside the Polygon, false
-     *         otherwise.
-     * @see java.awt.Shape#contains(java.awt.geom.Point2D)
-     */
-    public boolean contains(Point2D point) {
-        return contains(point.getX(), point.getY());
-    }
-
-    /**
-     * Checks whether or not the interior of rectangle specified by the
-     * Rectangle2D object intersects the interior of the Polygon.
-     * 
-     * @param rect
-     *            the Rectangle2D object.
-     * @return true, if the Rectangle2D intersects the interior of the Polygon,
-     *         false otherwise.
-     * @see java.awt.Shape#intersects(java.awt.geom.Rectangle2D)
-     */
-    public boolean intersects(Rectangle2D rect) {
-        return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
-    }
-
-    /**
-     * Gets the PathIterator object which gives the coordinates of the polygon,
-     * transformed according to the specified AffineTransform.
-     * 
-     * @param t
-     *            the specified AffineTransform object or null.
-     * @return PathIterator object for the Polygon.
-     * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform)
-     */
-    public PathIterator getPathIterator(AffineTransform t) {
-        return new Iterator(t, this);
-    }
-
-    /**
-     * Gets the PathIterator object which gives the coordinates of the polygon,
-     * transformed according to the specified AffineTransform. The flatness
-     * parameter is ignored.
-     * 
-     * @param t
-     *            the specified AffineTransform object or null.
-     * @param flatness
-     *            the maximum number of the control points for a given curve
-     *            which varies from colinear before a subdivided curve is
-     *            replaced by a straight line connecting the endpoints. This
-     *            parameter is ignored for the Polygon class.
-     * @return PathIterator object for the Polygon.
-     * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform,
-     *      double)
-     */
-    public PathIterator getPathIterator(AffineTransform t, double flatness) {
-        return new Iterator(t, this);
-    }
-
-}
diff --git a/awt/java/awt/Rectangle.java b/awt/java/awt/Rectangle.java
deleted file mode 100644
index d8ebb3a..0000000
--- a/awt/java/awt/Rectangle.java
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.geom.Rectangle2D;
-import java.io.Serializable;
-
-/**
- * The Rectangle class defines the rectangular area in terms of its upper left
- * corner coordinates [x,y], its width, and its height. A Rectangle specified by
- * [x, y, width, height] parameters has an outline path with corners at [x, y],
- * [x + width,y], [x + width,y + height], and [x, y + height]. <br>
- * <br>
- * The rectangle is empty if the width or height is negative or zero. In this
- * case the isEmpty method returns true.
- * 
- * @since Android 1.0
- */
-public class Rectangle extends Rectangle2D implements Shape, Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -4345857070255674764L;
-
-    /**
-     * The X coordinate of the rectangle's left upper corner.
-     */
-    public int x;
-
-    /**
-     * The Y coordinate of the rectangle's left upper corner.
-     */
-    public int y;
-
-    /**
-     * The width of rectangle.
-     */
-    public int width;
-
-    /**
-     * The height of rectangle.
-     */
-    public int height;
-
-    /**
-     * Instantiates a new rectangle with [0, 0] upper left corner coordinates,
-     * the width and the height are zero.
-     */
-    public Rectangle() {
-        setBounds(0, 0, 0, 0);
-    }
-
-    /**
-     * Instantiates a new rectangle whose upper left corner coordinates are
-     * given by the Point object (p.X and p.Y), and the width and the height are
-     * zero.
-     * 
-     * @param p
-     *            the Point specifies the upper left corner coordinates of the
-     *            rectangle.
-     */
-    public Rectangle(Point p) {
-        setBounds(p.x, p.y, 0, 0);
-    }
-
-    /**
-     * Instantiates a new rectangle whose upper left corner coordinates are
-     * given by the Point object (p.X and p.Y), and the width and the height are
-     * given by Dimension object (d.width and d.height).
-     * 
-     * @param p
-     *            the point specifies the upper left corner coordinates of the
-     *            rectangle.
-     * @param d
-     *            the dimension specifies the width and the height of the
-     *            rectangle.
-     */
-    public Rectangle(Point p, Dimension d) {
-        setBounds(p.x, p.y, d.width, d.height);
-    }
-
-    /**
-     * Instantiates a new rectangle determined by the upper left corner
-     * coordinates (x, y), width and height.
-     * 
-     * @param x
-     *            the X upper left corner coordinate of the rectangle.
-     * @param y
-     *            the Y upper left corner coordinate of the rectangle.
-     * @param width
-     *            the width of rectangle.
-     * @param height
-     *            the height of rectangle.
-     */
-    public Rectangle(int x, int y, int width, int height) {
-        setBounds(x, y, width, height);
-    }
-
-    /**
-     * Instantiates a new rectangle with [0, 0] as its upper left corner
-     * coordinates and the specified width and height.
-     * 
-     * @param width
-     *            the width of rectangle.
-     * @param height
-     *            the height of rectangle.
-     */
-    public Rectangle(int width, int height) {
-        setBounds(0, 0, width, height);
-    }
-
-    /**
-     * Instantiates a new rectangle with the same coordinates as the given
-     * source rectangle.
-     * 
-     * @param r
-     *            the Rectangle object which parameters will be used for
-     *            instantiating a new Rectangle.
-     */
-    public Rectangle(Rectangle r) {
-        setBounds(r.x, r.y, r.width, r.height);
-    }
-
-    /*
-     * public Rectangle(Dimension d) { setBounds(0, 0, d.width, d.height); }
-     */
-    /**
-     * Gets the X coordinate of bound as a double.
-     * 
-     * @return the X coordinate of bound as a double.
-     * @see java.awt.geom.RectangularShape#getX()
-     */
-    @Override
-    public double getX() {
-        return x;
-    }
-
-    /**
-     * Gets the Y coordinate of bound as a double.
-     * 
-     * @return the Y coordinate of bound as a double.
-     * @see java.awt.geom.RectangularShape#getY()
-     */
-    @Override
-    public double getY() {
-        return y;
-    }
-
-    /**
-     * Gets the height of the rectangle as a double.
-     * 
-     * @return the height of the rectangle as a double.
-     * @see java.awt.geom.RectangularShape#getHeight()
-     */
-    @Override
-    public double getHeight() {
-        return height;
-    }
-
-    /**
-     * Gets the width of the rectangle as a double.
-     * 
-     * @return the width of the rectangle as a double.
-     * @see java.awt.geom.RectangularShape#getWidth()
-     */
-    @Override
-    public double getWidth() {
-        return width;
-    }
-
-    /**
-     * Determines whether or not the rectangle is empty. The rectangle is empty
-     * if its width or height is negative or zero.
-     * 
-     * @return true, if the rectangle is empty, otherwise false.
-     * @see java.awt.geom.RectangularShape#isEmpty()
-     */
-    @Override
-    public boolean isEmpty() {
-        return width <= 0 || height <= 0;
-    }
-
-    /**
-     * Gets the size of a Rectangle as Dimension object.
-     * 
-     * @return a Dimension object which represents size of the rectangle.
-     */
-    public Dimension getSize() {
-        return new Dimension(width, height);
-    }
-
-    /**
-     * Sets the size of the Rectangle.
-     * 
-     * @param width
-     *            the new width of the rectangle.
-     * @param height
-     *            the new height of the rectangle.
-     */
-    public void setSize(int width, int height) {
-        this.width = width;
-        this.height = height;
-    }
-
-    /**
-     * Sets the size of a Rectangle specified as Dimension object.
-     * 
-     * @param d
-     *            a Dimension object which represents new size of a rectangle.
-     */
-    public void setSize(Dimension d) {
-        setSize(d.width, d.height);
-    }
-
-    /**
-     * Gets the location of a rectangle's upper left corner as a Point object.
-     * 
-     * @return the Point object with coordinates equal to the upper left corner
-     *         of the rectangle.
-     */
-    public Point getLocation() {
-        return new Point(x, y);
-    }
-
-    /**
-     * Sets the location of the rectangle in terms of its upper left corner
-     * coordinates X and Y.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle's upper left corner.
-     * @param y
-     *            the Y coordinate of the rectangle's upper left corner.
-     */
-    public void setLocation(int x, int y) {
-        this.x = x;
-        this.y = y;
-    }
-
-    /**
-     * Sets the location of a rectangle using a Point object to give the
-     * coordinates of the upper left corner.
-     * 
-     * @param p
-     *            the Point object which represents the new upper left corner
-     *            coordinates of rectangle.
-     */
-    public void setLocation(Point p) {
-        setLocation(p.x, p.y);
-    }
-
-    /**
-     * Moves a rectangle to the new location by moving its upper left corner to
-     * the point with coordinates X and Y.
-     * 
-     * @param x
-     *            the new X coordinate of the rectangle's upper left corner.
-     * @param y
-     *            the new Y coordinate of the rectangle's upper left corner.
-     * @deprecated Use setLocation(int, int) method.
-     */
-    @Deprecated
-    public void move(int x, int y) {
-        setLocation(x, y);
-    }
-
-    /**
-     * Sets the rectangle to be the nearest rectangle with integer coordinates
-     * bounding the rectangle defined by the double-valued parameters.
-     * 
-     * @param x
-     *            the X coordinate of the upper left corner of the double-valued
-     *            rectangle to be bounded.
-     * @param y
-     *            the Y coordinate of the upper left corner of the double-valued
-     *            rectangle to be bounded.
-     * @param width
-     *            the width of the rectangle to be bounded.
-     * @param height
-     *            the height of the rectangle to be bounded.
-     * @see java.awt.geom.Rectangle2D#setRect(double, double, double, double)
-     */
-    @Override
-    public void setRect(double x, double y, double width, double height) {
-        int x1 = (int)Math.floor(x);
-        int y1 = (int)Math.floor(y);
-        int x2 = (int)Math.ceil(x + width);
-        int y2 = (int)Math.ceil(y + height);
-        setBounds(x1, y1, x2 - x1, y2 - y1);
-    }
-
-    /**
-     * Sets a new size for the rectangle.
-     * 
-     * @param width
-     *            the rectangle's new width.
-     * @param height
-     *            the rectangle's new height.
-     * @deprecated use the setSize(int, int) method.
-     */
-    @Deprecated
-    public void resize(int width, int height) {
-        setBounds(x, y, width, height);
-    }
-
-    /**
-     * Resets the bounds of a rectangle to the specified x, y, width and height
-     * parameters.
-     * 
-     * @param x
-     *            the new X coordinate of the upper left corner.
-     * @param y
-     *            the new Y coordinate of the upper left corner.
-     * @param width
-     *            the new width of rectangle.
-     * @param height
-     *            the new height of rectangle.
-     * @deprecated use setBounds(int, int, int, int) method
-     */
-    @Deprecated
-    public void reshape(int x, int y, int width, int height) {
-        setBounds(x, y, width, height);
-    }
-
-    /**
-     * Gets bounds of the rectangle as a new Rectangle object.
-     * 
-     * @return the Rectangle object with the same bounds as the original
-     *         rectangle.
-     * @see java.awt.geom.RectangularShape#getBounds()
-     */
-    @Override
-    public Rectangle getBounds() {
-        return new Rectangle(x, y, width, height);
-    }
-
-    /**
-     * Gets the bounds of the original rectangle as a Rectangle2D object.
-     * 
-     * @return the Rectangle2D object which represents the bounds of the
-     *         original rectangle.
-     * @see java.awt.geom.Rectangle2D#getBounds2D()
-     */
-    @Override
-    public Rectangle2D getBounds2D() {
-        return getBounds();
-    }
-
-    /**
-     * Sets the bounds of a rectangle to the specified x, y, width, and height
-     * parameters.
-     * 
-     * @param x
-     *            the X coordinate of the upper left corner.
-     * @param y
-     *            the Y coordinate of the upper left corner.
-     * @param width
-     *            the width of rectangle.
-     * @param height
-     *            the height of rectangle.
-     */
-    public void setBounds(int x, int y, int width, int height) {
-        this.x = x;
-        this.y = y;
-        this.height = height;
-        this.width = width;
-    }
-
-    /**
-     * Sets the bounds of the rectangle to match the bounds of the Rectangle
-     * object sent as a parameter.
-     * 
-     * @param r
-     *            the Rectangle object which specifies the new bounds.
-     */
-    public void setBounds(Rectangle r) {
-        setBounds(r.x, r.y, r.width, r.height);
-    }
-
-    /**
-     * Enlarges the rectangle by moving each corner outward from the center by a
-     * distance of dx horizonally and a distance of dy vertically. Specifically,
-     * changes a rectangle with [x, y, width, height] parameters to a rectangle
-     * with [x-dx, y-dy, width+2*dx, height+2*dy] parameters.
-     * 
-     * @param dx
-     *            the horizontal distance to move each corner coordinate.
-     * @param dy
-     *            the vertical distance to move each corner coordinate.
-     */
-    public void grow(int dx, int dy) {
-        x -= dx;
-        y -= dy;
-        width += dx + dx;
-        height += dy + dy;
-    }
-
-    /**
-     * Moves a rectangle a distance of mx along the x coordinate axis and a
-     * distance of my along y coordinate axis.
-     * 
-     * @param mx
-     *            the horizontal translation increment.
-     * @param my
-     *            the vertical translation increment.
-     */
-    public void translate(int mx, int my) {
-        x += mx;
-        y += my;
-    }
-
-    /**
-     * Enlarges the rectangle to cover the specified point.
-     * 
-     * @param px
-     *            the X coordinate of the new point to be covered by the
-     *            rectangle.
-     * @param py
-     *            the Y coordinate of the new point to be covered by the
-     *            rectangle.
-     */
-    public void add(int px, int py) {
-        int x1 = Math.min(x, px);
-        int x2 = Math.max(x + width, px);
-        int y1 = Math.min(y, py);
-        int y2 = Math.max(y + height, py);
-        setBounds(x1, y1, x2 - x1, y2 - y1);
-    }
-
-    /**
-     * Enlarges the rectangle to cover the specified point with the new point
-     * given as a Point object.
-     * 
-     * @param p
-     *            the Point object that specifies the new point to be covered by
-     *            the rectangle.
-     */
-    public void add(Point p) {
-        add(p.x, p.y);
-    }
-
-    /**
-     * Adds a new rectangle to the original rectangle, the result is an union of
-     * the specified specified rectangle and original rectangle.
-     * 
-     * @param r
-     *            the Rectangle which is added to the original rectangle.
-     */
-    public void add(Rectangle r) {
-        int x1 = Math.min(x, r.x);
-        int x2 = Math.max(x + width, r.x + r.width);
-        int y1 = Math.min(y, r.y);
-        int y2 = Math.max(y + height, r.y + r.height);
-        setBounds(x1, y1, x2 - x1, y2 - y1);
-    }
-
-    /**
-     * Determines whether or not the point with specified coordinates [px, py]
-     * is within the bounds of the rectangle.
-     * 
-     * @param px
-     *            the X coordinate of point.
-     * @param py
-     *            the Y coordinate of point.
-     * @return true, if the point with specified coordinates [px, py] is within
-     *         the bounds of the rectangle, false otherwise.
-     */
-    public boolean contains(int px, int py) {
-        if (isEmpty()) {
-            return false;
-        }
-        if (px < x || py < y) {
-            return false;
-        }
-        px -= x;
-        py -= y;
-        return px < width && py < height;
-    }
-
-    /**
-     * Determines whether or not the point given as a Point object is within the
-     * bounds of the rectangle.
-     * 
-     * @param p
-     *            the Point object
-     * @return true, if the point p is within the bounds of the rectangle,
-     *         otherwise false.
-     */
-    public boolean contains(Point p) {
-        return contains(p.x, p.y);
-    }
-
-    /**
-     * Determines whether or not the rectangle specified by [rx, ry, rw, rh]
-     * parameters is located inside the original rectangle.
-     * 
-     * @param rx
-     *            the X coordinate of the rectangle to compare.
-     * @param ry
-     *            the Y coordinate of the rectangle to compare.
-     * @param rw
-     *            the width of the rectangle to compare.
-     * @param rh
-     *            the height of the rectangle to compare.
-     * @return true, if a rectangle with [rx, ry, rw, rh] parameters is entirely
-     *         contained in the original rectangle, false otherwise.
-     */
-    public boolean contains(int rx, int ry, int rw, int rh) {
-        return contains(rx, ry) && contains(rx + rw - 1, ry + rh - 1);
-    }
-
-    /**
-     * Compares whether or not the rectangle specified by the Rectangle object
-     * is located inside the original rectangle.
-     * 
-     * @param r
-     *            the Rectangle object.
-     * @return true, if the rectangle specified by Rectangle object is entirely
-     *         contained in the original rectangle, false otherwise.
-     */
-    public boolean contains(Rectangle r) {
-        return contains(r.x, r.y, r.width, r.height);
-    }
-
-    /**
-     * Compares whether or not a point with specified coordinates [px, py]
-     * belongs to a rectangle.
-     * 
-     * @param px
-     *            the X coordinate of a point.
-     * @param py
-     *            the Y coordinate of a point.
-     * @return true, if a point with specified coordinates [px, py] belongs to a
-     *         rectangle, otherwise false.
-     * @deprecated use contains(int, int) method.
-     */
-    @Deprecated
-    public boolean inside(int px, int py) {
-        return contains(px, py);
-    }
-
-    /**
-     * Returns the intersection of the original rectangle with the specified
-     * Rectangle2D.
-     * 
-     * @param r
-     *            the Rectangle2D object.
-     * @return the Rectangle2D object that is the result of intersecting the
-     *         original rectangle with the specified Rectangle2D.
-     * @see java.awt.geom.Rectangle2D#createIntersection(java.awt.geom.Rectangle2D)
-     */
-    @Override
-    public Rectangle2D createIntersection(Rectangle2D r) {
-        if (r instanceof Rectangle) {
-            return intersection((Rectangle)r);
-        }
-        Rectangle2D dst = new Rectangle2D.Double();
-        Rectangle2D.intersect(this, r, dst);
-        return dst;
-    }
-
-    /**
-     * Returns the intersection of the original rectangle with the specified
-     * rectangle. An empty rectangle is returned if there is no intersection.
-     * 
-     * @param r
-     *            the Rectangle object.
-     * @return the Rectangle object is result of the original rectangle with the
-     *         specified rectangle.
-     */
-    public Rectangle intersection(Rectangle r) {
-        int x1 = Math.max(x, r.x);
-        int y1 = Math.max(y, r.y);
-        int x2 = Math.min(x + width, r.x + r.width);
-        int y2 = Math.min(y + height, r.y + r.height);
-        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
-    }
-
-    /**
-     * Determines whether or not the original rectangle intersects the specified
-     * rectangle.
-     * 
-     * @param r
-     *            the Rectangle object.
-     * @return true, if the two rectangles overlap, false otherwise.
-     */
-    public boolean intersects(Rectangle r) {
-        return !intersection(r).isEmpty();
-    }
-
-    /**
-     * Determines where the specified Point is located with respect to the
-     * rectangle. This method computes whether the point is to the right or to
-     * the left of the rectangle and whether it is above or below the rectangle,
-     * and packs the result into an integer by using a binary OR operation with
-     * the following masks:
-     * <ul>
-     *<li>Rectangle2D.OUT_LEFT</li>
-     *<li>Rectangle2D.OUT_TOP</li>
-     *<li>Rectangle2D.OUT_RIGHT</li>
-     *<li>Rectangle2D.OUT_BOTTOM</li>
-     *</ul>
-     * If the rectangle is empty, all masks are set, and if the point is inside
-     * the rectangle, none are set.
-     * 
-     * @param px
-     *            the X coordinate of the specified point.
-     * @param py
-     *            the Y coordinate of the specified point.
-     * @return the location of the Point relative to the rectangle as the result
-     *         of logical OR operation with all out masks.
-     * @see java.awt.geom.Rectangle2D#outcode(double, double)
-     */
-    @Override
-    public int outcode(double px, double py) {
-        int code = 0;
-
-        if (width <= 0) {
-            code |= OUT_LEFT | OUT_RIGHT;
-        } else if (px < x) {
-            code |= OUT_LEFT;
-        } else if (px > x + width) {
-            code |= OUT_RIGHT;
-        }
-
-        if (height <= 0) {
-            code |= OUT_TOP | OUT_BOTTOM;
-        } else if (py < y) {
-            code |= OUT_TOP;
-        } else if (py > y + height) {
-            code |= OUT_BOTTOM;
-        }
-
-        return code;
-    }
-
-    /**
-     * Enlarges the rectangle to cover the specified Rectangle2D.
-     * 
-     * @param r
-     *            the Rectangle2D object.
-     * @return the union of the original and the specified Rectangle2D.
-     * @see java.awt.geom.Rectangle2D#createUnion(java.awt.geom.Rectangle2D)
-     */
-    @Override
-    public Rectangle2D createUnion(Rectangle2D r) {
-        if (r instanceof Rectangle) {
-            return union((Rectangle)r);
-        }
-        Rectangle2D dst = new Rectangle2D.Double();
-        Rectangle2D.union(this, r, dst);
-        return dst;
-    }
-
-    /**
-     * Enlarges the rectangle to cover the specified rectangle.
-     * 
-     * @param r
-     *            the Rectangle.
-     * @return the union of the original and the specified rectangle.
-     */
-    public Rectangle union(Rectangle r) {
-        Rectangle dst = new Rectangle(this);
-        dst.add(r);
-        return dst;
-    }
-
-    /**
-     * Compares the original Rectangle with the specified object.
-     * 
-     * @param obj
-     *            the specified Object for comparison.
-     * @return true, if the specified Object is a rectangle with the same
-     *         dimensions as the original rectangle, false otherwise.
-     * @see java.awt.geom.Rectangle2D#equals(Object)
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (obj instanceof Rectangle) {
-            Rectangle r = (Rectangle)obj;
-            return r.x == x && r.y == y && r.width == width && r.height == height;
-        }
-        return false;
-    }
-
-    /**
-     * Returns a string representation of the rectangle; the string contains [x,
-     * y, width, height] parameters of the rectangle.
-     * 
-     * @return the string representation of the rectangle.
-     */
-    @Override
-    public String toString() {
-        // The output format based on 1.5 release behaviour. It could be
-        // obtained in the following way
-        // System.out.println(new Rectangle().toString())
-        return getClass().getName() + "[x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$
-                ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    }
-
-}
diff --git a/awt/java/awt/RenderingHints.java b/awt/java/awt/RenderingHints.java
deleted file mode 100644
index acf6fa1..0000000
--- a/awt/java/awt/RenderingHints.java
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * The RenderingHints class represents preferences for the rendering algorithms.
- * The preferences are arbitrary and can be specified by Map objects or by
- * key-value pairs.
- * 
- * @since Android 1.0
- */
-public class RenderingHints implements Map<Object, Object>, Cloneable {
-
-    /**
-     * The Constant KEY_ALPHA_INTERPOLATION - alpha interpolation rendering hint
-     * key.
-     */
-    public static final Key KEY_ALPHA_INTERPOLATION = new KeyImpl(1);
-
-    /**
-     * The Constant VALUE_ALPHA_INTERPOLATION_DEFAULT - alpha interpolation
-     * rendering hint value.
-     */
-    public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT = new KeyValue(
-            KEY_ALPHA_INTERPOLATION);
-
-    /**
-     * The Constant VALUE_ALPHA_INTERPOLATION_SPEED - alpha interpolation
-     * rendering hint value.
-     */
-    public static final Object VALUE_ALPHA_INTERPOLATION_SPEED = new KeyValue(
-            KEY_ALPHA_INTERPOLATION);
-
-    /**
-     * The Constant VALUE_ALPHA_INTERPOLATION_QUALITY - alpha interpolation
-     * rendering hint value.
-     */
-    public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY = new KeyValue(
-            KEY_ALPHA_INTERPOLATION);
-
-    /**
-     * The Constant KEY_ANTIALIASING - antialiasing rendering hint key.
-     */
-    public static final Key KEY_ANTIALIASING = new KeyImpl(2);
-
-    /**
-     * The Constant VALUE_ANTIALIAS_DEFAULT - antialiasing rendering hint value.
-     */
-    public static final Object VALUE_ANTIALIAS_DEFAULT = new KeyValue(KEY_ANTIALIASING);
-
-    /**
-     * The Constant VALUE_ANTIALIAS_ON - antialiasing rendering hint value.
-     */
-    public static final Object VALUE_ANTIALIAS_ON = new KeyValue(KEY_ANTIALIASING);
-
-    /**
-     * The Constant VALUE_ANTIALIAS_OFF - antialiasing rendering hint value.
-     */
-    public static final Object VALUE_ANTIALIAS_OFF = new KeyValue(KEY_ANTIALIASING);
-
-    /**
-     * The Constant KEY_COLOR_RENDERING - color rendering hint key.
-     */
-    public static final Key KEY_COLOR_RENDERING = new KeyImpl(3);
-
-    /**
-     * The Constant VALUE_COLOR_RENDER_DEFAULT - color rendering hint value.
-     */
-    public static final Object VALUE_COLOR_RENDER_DEFAULT = new KeyValue(KEY_COLOR_RENDERING);
-
-    /**
-     * The Constant VALUE_COLOR_RENDER_SPEED - color rendering hint value.
-     */
-    public static final Object VALUE_COLOR_RENDER_SPEED = new KeyValue(KEY_COLOR_RENDERING);
-
-    /**
-     * The Constant VALUE_COLOR_RENDER_QUALITY - color rendering hint value.
-     */
-    public static final Object VALUE_COLOR_RENDER_QUALITY = new KeyValue(KEY_COLOR_RENDERING);
-
-    /**
-     * The Constant KEY_DITHERING - dithering rendering hint key.
-     */
-    public static final Key KEY_DITHERING = new KeyImpl(4);
-
-    /**
-     * The Constant VALUE_DITHER_DEFAULT - dithering rendering hint value.
-     */
-    public static final Object VALUE_DITHER_DEFAULT = new KeyValue(KEY_DITHERING);
-
-    /**
-     * The Constant VALUE_DITHER_DISABLE - dithering rendering hint value.
-     */
-    public static final Object VALUE_DITHER_DISABLE = new KeyValue(KEY_DITHERING);
-
-    /**
-     * The Constant VALUE_DITHER_DISABLE - dithering rendering hint value.
-     */
-    public static final Object VALUE_DITHER_ENABLE = new KeyValue(KEY_DITHERING);
-
-    /**
-     * The Constant KEY_FRACTIONALMETRICS - fractional metrics rendering hint
-     * key.
-     */
-    public static final Key KEY_FRACTIONALMETRICS = new KeyImpl(5);
-
-    /**
-     * The Constant VALUE_FRACTIONALMETRICS_DEFAULT - fractional metrics
-     * rendering hint value.
-     */
-    public static final Object VALUE_FRACTIONALMETRICS_DEFAULT = new KeyValue(KEY_FRACTIONALMETRICS);
-
-    /**
-     * The Constant VALUE_FRACTIONALMETRICS_ON - fractional metrics rendering
-     * hint value.
-     */
-    public static final Object VALUE_FRACTIONALMETRICS_ON = new KeyValue(KEY_FRACTIONALMETRICS);
-
-    /**
-     * The Constant VALUE_FRACTIONALMETRICS_OFF - fractional metrics rendering
-     * hint value.
-     */
-    public static final Object VALUE_FRACTIONALMETRICS_OFF = new KeyValue(KEY_FRACTIONALMETRICS);
-
-    /**
-     * The Constant KEY_INTERPOLATION - interpolation rendering hint key.
-     */
-    public static final Key KEY_INTERPOLATION = new KeyImpl(6);
-
-    /**
-     * The Constant VALUE_INTERPOLATION_BICUBIC - interpolation rendering hint
-     * value.
-     */
-    public static final Object VALUE_INTERPOLATION_BICUBIC = new KeyValue(KEY_INTERPOLATION);
-
-    /**
-     * The Constant VALUE_INTERPOLATION_BILINEAR - interpolation rendering hint
-     * value.
-     */
-    public static final Object VALUE_INTERPOLATION_BILINEAR = new KeyValue(KEY_INTERPOLATION);
-
-    /**
-     * The Constant VALUE_INTERPOLATION_NEAREST_NEIGHBOR - interpolation
-     * rendering hint value.
-     */
-    public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR = new KeyValue(
-            KEY_INTERPOLATION);
-
-    /**
-     * The Constant KEY_RENDERING - rendering hint key.
-     */
-    public static final Key KEY_RENDERING = new KeyImpl(7);
-
-    /**
-     * The Constant VALUE_RENDER_DEFAULT - rendering hint value.
-     */
-    public static final Object VALUE_RENDER_DEFAULT = new KeyValue(KEY_RENDERING);
-
-    /**
-     * The Constant VALUE_RENDER_SPEED - rendering hint value.
-     */
-    public static final Object VALUE_RENDER_SPEED = new KeyValue(KEY_RENDERING);
-
-    /**
-     * The Constant VALUE_RENDER_QUALITY - rendering hint value.
-     */
-    public static final Object VALUE_RENDER_QUALITY = new KeyValue(KEY_RENDERING);
-
-    /**
-     * The Constant KEY_STROKE_CONTROL - stroke control hint key.
-     */
-    public static final Key KEY_STROKE_CONTROL = new KeyImpl(8);
-
-    /**
-     * The Constant VALUE_STROKE_DEFAULT - stroke hint value.
-     */
-    public static final Object VALUE_STROKE_DEFAULT = new KeyValue(KEY_STROKE_CONTROL);
-
-    /**
-     * The Constant VALUE_STROKE_NORMALIZE - stroke hint value.
-     */
-    public static final Object VALUE_STROKE_NORMALIZE = new KeyValue(KEY_STROKE_CONTROL);
-
-    /**
-     * The Constant VALUE_STROKE_PURE - stroke hint value.
-     */
-    public static final Object VALUE_STROKE_PURE = new KeyValue(KEY_STROKE_CONTROL);
-
-    /**
-     * The Constant KEY_TEXT_ANTIALIASING - text antialiasing hint key.
-     */
-    public static final Key KEY_TEXT_ANTIALIASING = new KeyImpl(9);
-
-    /**
-     * The Constant VALUE_TEXT_ANTIALIAS_DEFAULT - text antialiasing hint key.
-     */
-    public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT = new KeyValue(KEY_TEXT_ANTIALIASING);
-
-    /**
-     * The Constant VALUE_TEXT_ANTIALIAS_ON - text antialiasing hint key.
-     */
-    public static final Object VALUE_TEXT_ANTIALIAS_ON = new KeyValue(KEY_TEXT_ANTIALIASING);
-
-    /**
-     * The Constant VALUE_TEXT_ANTIALIAS_OFF - text antialiasing hint key.
-     */
-    public static final Object VALUE_TEXT_ANTIALIAS_OFF = new KeyValue(KEY_TEXT_ANTIALIASING);
-
-    /** The map. */
-    private HashMap<Object, Object> map = new HashMap<Object, Object>();
-
-    /**
-     * Instantiates a new rendering hints object from specified Map object with
-     * defined key/value pairs or null for empty RenderingHints.
-     * 
-     * @param map
-     *            the Map object with defined key/value pairs or null for empty
-     *            RenderingHints.
-     */
-    public RenderingHints(Map<Key, ?> map) {
-        super();
-        if (map != null) {
-            putAll(map);
-        }
-    }
-
-    /**
-     * Instantiates a new rendering hints object with the specified key/value
-     * pair.
-     * 
-     * @param key
-     *            the key of hint property.
-     * @param value
-     *            the value of hint property.
-     */
-    public RenderingHints(Key key, Object value) {
-        super();
-        put(key, value);
-    }
-
-    /**
-     * Adds the properties represented by key/value pairs from the specified
-     * RenderingHints object to current object.
-     * 
-     * @param hints
-     *            the RenderingHints to be added.
-     */
-    public void add(RenderingHints hints) {
-        map.putAll(hints.map);
-    }
-
-    /**
-     * Puts the specified value to the specified key. Neither the key nor the
-     * value can be null.
-     * 
-     * @param key
-     *            the rendering hint key.
-     * @param value
-     *            the rendering hint value.
-     * @return the previous rendering hint value assigned to the key or null.
-     */
-    public Object put(Object key, Object value) {
-        if (!((Key)key).isCompatibleValue(value)) {
-            throw new IllegalArgumentException();
-        }
-
-        return map.put(key, value);
-    }
-
-    /**
-     * Removes the specified key and corresponding value from the RenderingHints
-     * object.
-     * 
-     * @param key
-     *            the specified hint key to be removed.
-     * @return the object of previous rendering hint value which is assigned to
-     *         the specified key, or null.
-     */
-    public Object remove(Object key) {
-        return map.remove(key);
-    }
-
-    /**
-     * Gets the value assigned to the specified key.
-     * 
-     * @param key
-     *            the rendering hint key.
-     * @return the object assigned to the specified key.
-     */
-    public Object get(Object key) {
-        return map.get(key);
-    }
-
-    /**
-     * Returns a set of rendering hints keys for current RenderingHints object.
-     * 
-     * @return the set of rendering hints keys.
-     */
-    public Set<Object> keySet() {
-        return map.keySet();
-    }
-
-    /**
-     * Returns a set of Map.Entry objects which contain current RenderingHint
-     * key/value pairs.
-     * 
-     * @return the a set of mapped RenderingHint key/value pairs.
-     */
-    public Set<Map.Entry<Object, Object>> entrySet() {
-        return map.entrySet();
-    }
-
-    /**
-     * Puts all of the preferences from the specified Map into the current
-     * RenderingHints object. These mappings replace all existing preferences.
-     * 
-     * @param m
-     *            the specified Map of preferences.
-     */
-    public void putAll(Map<?, ?> m) {
-        if (m instanceof RenderingHints) {
-            map.putAll(((RenderingHints)m).map);
-        } else {
-            Set<?> entries = m.entrySet();
-
-            if (entries != null) {
-                Iterator<?> it = entries.iterator();
-                while (it.hasNext()) {
-                    Map.Entry<?, ?> entry = (Map.Entry<?, ?>)it.next();
-                    Key key = (Key)entry.getKey();
-                    Object val = entry.getValue();
-                    put(key, val);
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns a Collection of values contained in current RenderingHints
-     * object.
-     * 
-     * @return the Collection of RenderingHints's values.
-     */
-    public Collection<Object> values() {
-        return map.values();
-    }
-
-    /**
-     * Checks whether or not current RenderingHints object contains at least one
-     * the value which is equal to the specified Object.
-     * 
-     * @param value
-     *            the specified Object.
-     * @return true, if the specified object is assigned to at least one
-     *         RenderingHint's key, false otherwise.
-     */
-    public boolean containsValue(Object value) {
-        return map.containsValue(value);
-    }
-
-    /**
-     * Checks whether or not current RenderingHints object contains the key
-     * which is equal to the specified Object.
-     * 
-     * @param key
-     *            the specified Object.
-     * @return true, if the RenderingHints object contains the specified Object
-     *         as a key, false otherwise.
-     */
-    public boolean containsKey(Object key) {
-        if (key == null) {
-            throw new NullPointerException();
-        }
-
-        return map.containsKey(key);
-    }
-
-    /**
-     * Checks whether or not the RenderingHints object contains any key/value
-     * pairs.
-     * 
-     * @return true, if the RenderingHints object is empty, false otherwise.
-     */
-    public boolean isEmpty() {
-        return map.isEmpty();
-    }
-
-    /**
-     * Clears the RenderingHints of all key/value pairs.
-     */
-    public void clear() {
-        map.clear();
-    }
-
-    /**
-     * Returns the number of key/value pairs in the RenderingHints.
-     * 
-     * @return the number of key/value pairs.
-     */
-    public int size() {
-        return map.size();
-    }
-
-    /**
-     * Compares the RenderingHints object with the specified object.
-     * 
-     * @param o
-     *            the specified Object to be compared.
-     * @return true, if the Object is a Map whose key/value pairs match this
-     *         RenderingHints' key/value pairs, false otherwise.
-     */
-    @Override
-    public boolean equals(Object o) {
-        if (!(o instanceof Map)) {
-            return false;
-        }
-
-        Map<?, ?> m = (Map<?, ?>)o;
-        Set<?> keys = keySet();
-        if (!keys.equals(m.keySet())) {
-            return false;
-        }
-
-        Iterator<?> it = keys.iterator();
-        while (it.hasNext()) {
-            Key key = (Key)it.next();
-            Object v1 = get(key);
-            Object v2 = m.get(key);
-            if (!(v1 == null ? v2 == null : v1.equals(v2))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Returns the hash code for this RenderingHints object.
-     * 
-     * @return the hash code for this RenderingHints object.
-     */
-    @Override
-    public int hashCode() {
-        return map.hashCode();
-    }
-
-    /**
-     * Returns the clone of the RenderingHints object with the same contents.
-     * 
-     * @return the clone of the RenderingHints instance.
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public Object clone() {
-        RenderingHints clone = new RenderingHints(null);
-        clone.map = (HashMap<Object, Object>)this.map.clone();
-        return clone;
-    }
-
-    /**
-     * Returns the string representation of the RenderingHints object.
-     * 
-     * @return the String object which represents RenderingHints object.
-     */
-    @Override
-    public String toString() {
-        return "RenderingHints[" + map.toString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    /**
-     * The RenderingHints.Key class is abstract and defines a base type for all
-     * RenderingHints keys.
-     * 
-     * @since Android 1.0
-     */
-    public abstract static class Key {
-
-        /** The key. */
-        private final int key;
-
-        /**
-         * Instantiates a new key with unique integer identifier. No two objects
-         * of the same subclass with the same integer key can be instantiated.
-         * 
-         * @param key
-         *            the unique key.
-         */
-        protected Key(int key) {
-            this.key = key;
-        }
-
-        /**
-         * Compares the Key object with the specified object.
-         * 
-         * @param o
-         *            the specified Object to be compared.
-         * @return true, if the Key is equal to the specified object, false
-         *         otherwise.
-         */
-        @Override
-        public final boolean equals(Object o) {
-            return this == o;
-        }
-
-        /**
-         * Returns the hash code for this Key object.
-         * 
-         * @return the hash code for this Key object.
-         */
-        @Override
-        public final int hashCode() {
-            return System.identityHashCode(this);
-        }
-
-        /**
-         * Returns integer unique key with which this Key object has been
-         * instantiated.
-         * 
-         * @return the integer unique key with which this Key object has been
-         *         instantiated.
-         */
-        protected final int intKey() {
-            return key;
-        }
-
-        /**
-         * Checks whether or not specified value is compatible with the Key.
-         * 
-         * @param val
-         *            the Object.
-         * @return true, if the specified value is compatible with the Key,
-         *         false otherwise.
-         */
-        public abstract boolean isCompatibleValue(Object val);
-    }
-
-    /**
-     * Private implementation of Key class.
-     */
-    private static class KeyImpl extends Key {
-
-        /**
-         * Instantiates a new key implementation.
-         * 
-         * @param key
-         *            the key.
-         */
-        protected KeyImpl(int key) {
-            super(key);
-        }
-
-        @Override
-        public boolean isCompatibleValue(Object val) {
-            if (!(val instanceof KeyValue)) {
-                return false;
-            }
-
-            return ((KeyValue)val).key == this;
-        }
-    }
-
-    /**
-     * Private class KeyValue is used as value for Key class instance.
-     */
-    private static class KeyValue {
-
-        /**
-         * The key.
-         */
-        private final Key key;
-
-        /**
-         * Instantiates a new key value.
-         * 
-         * @param key
-         *            the key.
-         */
-        protected KeyValue(Key key) {
-            this.key = key;
-        }
-    }
-}
diff --git a/awt/java/awt/Shape.java b/awt/java/awt/Shape.java
deleted file mode 100644
index 59bc623..0000000
--- a/awt/java/awt/Shape.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-
-/**
- * The Shape interface defines a geometric shape defined by a boundary (outline)
- * path. The path outline can be accessed through a PathIterator object. The
- * Shape interface provides methods for obtaining the bounding box (which is the
- * smallest rectangle containing the shape and for obtaining a PathIterator
- * object for current Shape, as well as utility methods which determine if the
- * Shape contains or intersects a Rectangle or contains a Point.
- * 
- * @since Android 1.0
- */
-public interface Shape {
-
-    /**
-     * Checks whether or not the point with specified coordinates lies inside
-     * the Shape.
-     * 
-     * @param x
-     *            the X coordinate.
-     * @param y
-     *            the Y coordinate.
-     * @return true, if the specified coordinates lie inside the Shape, false
-     *         otherwise.
-     */
-    public boolean contains(double x, double y);
-
-    /**
-     * Checks whether or not the rectangle with specified [x, y, width, height]
-     * parameters lies inside the Shape.
-     * 
-     * @param x
-     *            the X double coordinate of the rectangle's upper left corner.
-     * @param y
-     *            the Y double coordinate of the rectangle's upper left corner.
-     * @param w
-     *            the width of rectangle.
-     * @param h
-     *            the height of rectangle.
-     * @return true, if the specified rectangle lies inside the Shape, false
-     *         otherwise.
-     */
-    public boolean contains(double x, double y, double w, double h);
-
-    /**
-     * Checks whether or not the specified Point2D lies inside the Shape.
-     * 
-     * @param point
-     *            the Point2D object.
-     * @return true, if the specified Point2D lies inside the Shape, false
-     *         otherwise.
-     */
-    public boolean contains(Point2D point);
-
-    /**
-     * Checks whether or not the specified rectangle lies inside the Shape.
-     * 
-     * @param r
-     *            the Rectangle2D object.
-     * @return true, if the specified rectangle lies inside the Shape, false
-     *         otherwise.
-     */
-    public boolean contains(Rectangle2D r);
-
-    /**
-     * Gets the bounding rectangle of the Shape. The bounding rectangle is the
-     * smallest rectangle which contains the Shape.
-     * 
-     * @return the bounding rectangle of the Shape.
-     */
-    public Rectangle getBounds();
-
-    /**
-     * Gets the Rectangle2D which represents Shape bounds. The bounding
-     * rectangle is the smallest rectangle which contains the Shape.
-     * 
-     * @return the bounding rectangle of the Shape.
-     */
-    public Rectangle2D getBounds2D();
-
-    /**
-     * Gets the PathIterator object of the Shape which provides access to the
-     * shape's boundary modified by the specified AffineTransform.
-     * 
-     * @param at
-     *            the specified AffineTransform object or null.
-     * @return PathIterator object for the Shape.
-     */
-    public PathIterator getPathIterator(AffineTransform at);
-
-    /**
-     * Gets the PathIterator object of the Shape which provides access to the
-     * coordinates of the shapes boundary modified by the specified
-     * AffineTransform. The flatness parameter defines the amount of subdivision
-     * of the curved segments and specifies the maximum distance which every
-     * point on the unflattened transformed curve can deviate from the returned
-     * flattened path segments.
-     * 
-     * @param at
-     *            the specified AffineTransform object or null.
-     * @param flatness
-     *            the maximum number of the control points for a given curve
-     *            which varies from colinear before a subdivided curve is
-     *            replaced by a straight line connecting the endpoints.
-     * @return PathIterator object for the Shape.
-     */
-    public PathIterator getPathIterator(AffineTransform at, double flatness);
-
-    /**
-     * Checks whether or not the interior of rectangular specified by [x, y,
-     * width, height] parameters intersects the interior of the Shape.
-     * 
-     * @param x
-     *            the X double coordinate of the rectangle's upper left corner.
-     * @param y
-     *            the Y double coordinate of the rectangle's upper left corner.
-     * @param w
-     *            the width of rectangle.
-     * @param h
-     *            the height of rectangle.
-     * @return true, if the rectangle specified by [x, y, width, height]
-     *         parameters intersects the interior of the Shape, false otherwise.
-     */
-    public boolean intersects(double x, double y, double w, double h);
-
-    /**
-     * Checks whether or not the interior of rectangle specified by Rectangle2D
-     * object intersects the interior of the Shape.
-     * 
-     * @param r
-     *            the Rectangle2D object.
-     * @return true, if the Rectangle2D intersects the interior of the Shape,
-     *         otherwise false.
-     */
-    public boolean intersects(Rectangle2D r);
-}
diff --git a/awt/java/awt/Stroke.java b/awt/java/awt/Stroke.java
deleted file mode 100644
index 6d17a23..0000000
--- a/awt/java/awt/Stroke.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * The Stroke interface gives a pen style to be used by the Graphics2D
- * interface. It provides a means for getting a stroked version of a shape,
- * which is the version that is suitable for drawing via the Graphics2D
- * interface. Stroking a shape gives the shape's outline a width or drawing
- * style.
- * <p>
- * The Draw methods from Graphics2D interface should use the Stroke object for
- * rendering the shape's outline. The stroke should be set by
- * setStroke(java.awt.Stroke) method of the Graphics2D interface.
- * 
- * @see java.awt.Graphics2D#setStroke(java.awt.Stroke)
- * @since Android 1.0
- */
-public interface Stroke {
-
-    /**
-     * Creates the stroked shape, which is the version that is suitable for
-     * drawing via the Graphics2D interface. Stroking a shape gives the shape's
-     * outline a width or drawing style.
-     * 
-     * @param p
-     *            the original shape.
-     * @return the stroked shape.
-     */
-    public Shape createStrokedShape(Shape p);
-}
diff --git a/awt/java/awt/Toolkit.java b/awt/java/awt/Toolkit.java
deleted file mode 100644
index e38d524..0000000
--- a/awt/java/awt/Toolkit.java
+++ /dev/null
@@ -1,1444 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.awt;
-
-import java.awt.event.AWTEventListener;
-import java.awt.event.AWTEventListenerProxy;
-import java.awt.event.InputEvent;
-import java.awt.im.InputMethodHighlight;
-import java.awt.image.ColorModel;
-import java.awt.image.ImageObserver;
-import java.awt.image.ImageProducer;
-import java.awt.peer.FontPeer;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-
-import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Collections;
-import java.util.EventListener;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.MissingResourceException;
-import java.util.Properties;
-import java.util.ResourceBundle;
-
-import org.apache.harmony.awt.ChoiceStyle;
-import org.apache.harmony.awt.ComponentInternals;
-import org.apache.harmony.awt.ContextStorage;
-import org.apache.harmony.awt.ReadOnlyIterator;
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.awt.wtk.CreationParams;
-import org.apache.harmony.awt.wtk.GraphicsFactory;
-import org.apache.harmony.awt.wtk.NativeCursor;
-
-import org.apache.harmony.awt.wtk.NativeEventQueue;
-import org.apache.harmony.awt.wtk.NativeEventThread;
-import org.apache.harmony.awt.wtk.ShutdownWatchdog;
-import org.apache.harmony.awt.wtk.Synchronizer;
-import org.apache.harmony.awt.wtk.WTK;
-import org.apache.harmony.luni.util.NotImplementedException;
-
-/**
- * The Toolkit class is the representation of the platform-specific Abstract
- * Window Toolkit implementation. Toolkit's subclasses are used to bind the
- * various components to particular native toolkit implementations.
- * 
- * @since Android 1.0
- */
-public abstract class Toolkit {
-
-    /**
-     * The Constant RECOURCE_PATH.
-     */
-    private static final String RECOURCE_PATH = "org.apache.harmony.awt.resources.AWTProperties"; //$NON-NLS-1$
-
-    /**
-     * The Constant properties.
-     */
-    private static final ResourceBundle properties = loadResources(RECOURCE_PATH);
-
-    /**
-     * The dispatcher.
-     */
-    Dispatcher dispatcher;
-
-    /**
-     * The system event queue core.
-     */
-    private EventQueueCore systemEventQueueCore;
-
-    /**
-     * The dispatch thread.
-     */
-    EventDispatchThread dispatchThread;
-
-    /**
-     * The native thread.
-     */
-    NativeEventThread nativeThread;
-
-    /**
-     * The AWT events manager.
-     */
-    protected AWTEventsManager awtEventsManager;
-
-    /**
-     * The Class AWTTreeLock.
-     */
-    private class AWTTreeLock {
-    }
-
-    /**
-     * The AWT tree lock.
-     */
-    final Object awtTreeLock = new AWTTreeLock();
-
-    /**
-     * The synchronizer.
-     */
-    private final Synchronizer synchronizer = ContextStorage.getSynchronizer();
-
-    /**
-     * The shutdown watchdog.
-     */
-    final ShutdownWatchdog shutdownWatchdog = new ShutdownWatchdog();
-
-    /**
-     * The auto number.
-     */
-    final AutoNumber autoNumber = new AutoNumber();
-
-    /**
-     * The event type lookup.
-     */
-    final AWTEvent.EventTypeLookup eventTypeLookup = new AWTEvent.EventTypeLookup();
-
-    /**
-     * The b dynamic layout set.
-     */
-    private boolean bDynamicLayoutSet = true;
-
-    /**
-     * The set of desktop properties that user set directly.
-     */
-    private final HashSet<String> userPropSet = new HashSet<String>();
-
-    /**
-     * The desktop properties.
-     */
-    protected Map<String, Object> desktopProperties;
-
-    /**
-     * The desktop props support.
-     */
-    protected PropertyChangeSupport desktopPropsSupport;
-
-    /**
-     * For this component the native window is being created It is used in the
-     * callback-driven window creation (e.g. on Windows in the handler of
-     * WM_CREATE event) to establish the connection between this component and
-     * its native window.
-     */
-    private Object recentNativeWindowComponent;
-
-    /**
-     * The wtk.
-     */
-    private WTK wtk;
-
-    /**
-     * The Class ComponentInternalsImpl.
-     * 
-     * @since Android 1.0
-     */
-    protected final class ComponentInternalsImpl extends ComponentInternals {
-
-        /**
-         * Shutdown.
-         */
-        @Override
-        public void shutdown() {
-            dispatchThread.shutdown();
-        }
-
-        /**
-         * Sets the desktop property to the specified value and fires a property
-         * change event.
-         * 
-         * @param name
-         *            the name of property.
-         * @param value
-         *            the new value of property.
-         */
-        @Override
-        public void setDesktopProperty(String name, Object value) {
-            Toolkit.this.setDesktopProperty(name, value);
-        }
-    }
-
-    /**
-     * A lot of methods must throw HeadlessException if
-     * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
-     * 
-     * @throws HeadlessException
-     *             the headless exception.
-     */
-    static void checkHeadless() throws HeadlessException {
-        if (GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance())
-            throw new HeadlessException();
-    }
-
-    /**
-     * Lock AWT.
-     */
-    final void lockAWT() {
-        synchronizer.lock();
-    }
-
-    /**
-     * Static lock AWT.
-     */
-    static final void staticLockAWT() {
-        ContextStorage.getSynchronizer().lock();
-    }
-
-    /**
-     * Unlock AWT.
-     */
-    final void unlockAWT() {
-        synchronizer.unlock();
-    }
-
-    /**
-     * Static unlock AWT.
-     */
-    static final void staticUnlockAWT() {
-        ContextStorage.getSynchronizer().unlock();
-    }
-
-    /**
-     * InvokeAndWait under AWT lock. W/o this method system can hang up. Added
-     * to support modality (Dialog.show() & PopupMenu.show()) from not event
-     * dispatch thread. Use in other cases is not recommended. Still can be
-     * called only for whole API methods that cannot be called from other
-     * classes API methods. Examples: show() for modal dialogs - correct, only
-     * user can call it, directly or through setVisible(true) setBounds() for
-     * components - incorrect, setBounds() can be called from layoutContainer()
-     * for layout managers
-     * 
-     * @param runnable
-     *            the runnable.
-     * @throws InterruptedException
-     *             the interrupted exception.
-     * @throws InvocationTargetException
-     *             the invocation target exception.
-     */
-    final void unsafeInvokeAndWait(Runnable runnable) throws InterruptedException,
-            InvocationTargetException {
-        synchronizer.storeStateAndFree();
-        try {
-            EventQueue.invokeAndWait(runnable);
-        } finally {
-            synchronizer.lockAndRestoreState();
-        }
-    }
-
-    /**
-     * Gets the synchronizer.
-     * 
-     * @return the synchronizer.
-     */
-    final Synchronizer getSynchronizer() {
-        return synchronizer;
-    }
-
-    /**
-     * Gets the wTK.
-     * 
-     * @return the wTK.
-     */
-    final WTK getWTK() {
-        return wtk;
-    }
-
-    /**
-     * Gets the property with the specified key and default value. This method
-     * returns the defValue if the property is not found.
-     * 
-     * @param propName
-     *            the name of property.
-     * @param defVal
-     *            the default value.
-     * @return the property value.
-     */
-    public static String getProperty(String propName, String defVal) {
-        if (propName == null) {
-            // awt.7D=Property name is null
-            throw new NullPointerException(Messages.getString("awt.7D")); //$NON-NLS-1$
-        }
-        staticLockAWT();
-        try {
-            String retVal = null;
-            if (properties != null) {
-                try {
-                    retVal = properties.getString(propName);
-                } catch (MissingResourceException e) {
-                } catch (ClassCastException e) {
-                }
-            }
-            return (retVal == null) ? defVal : retVal;
-        } finally {
-            staticUnlockAWT();
-        }
-    }
-
-    /**
-     * Gets the default Toolkit.
-     * 
-     * @return the default Toolkit.
-     */
-    public static Toolkit getDefaultToolkit() {
-        synchronized (ContextStorage.getContextLock()) {
-            if (ContextStorage.shutdownPending()) {
-                return null;
-            }
-            Toolkit defToolkit = ContextStorage.getDefaultToolkit();
-            if (defToolkit != null) {
-                return defToolkit;
-            }
-            staticLockAWT();
-            try {
-                defToolkit = GraphicsEnvironment.isHeadless() ? new HeadlessToolkit()
-                        : new ToolkitImpl();
-                ContextStorage.setDefaultToolkit(defToolkit);
-                return defToolkit;
-            } finally {
-                staticUnlockAWT();
-            }
-            // TODO: read system property named awt.toolkit
-            // and create an instance of the specified class,
-            // by default use ToolkitImpl
-        }
-    }
-
-    /**
-     * Gets the default Font.
-     * 
-     * @return the default Font for Toolkit.
-     */
-    Font getDefaultFont() {
-        return wtk.getSystemProperties().getDefaultFont();
-    }
-
-    /**
-     * Load resources.
-     * 
-     * @param path
-     *            the path.
-     * @return the resource bundle.
-     */
-    private static ResourceBundle loadResources(String path) {
-        try {
-            return ResourceBundle.getBundle(path);
-        } catch (MissingResourceException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Gets the wTK class name.
-     * 
-     * @return the wTK class name.
-     */
-    private static String getWTKClassName() {
-        return "com.android.internal.awt.AndroidWTK";
-    }
-
-    /**
-     * Gets the component by id.
-     * 
-     * @param id
-     *            the id.
-     * @return the component by id.
-     */
-    Component getComponentById(long id) {
-        if (id == 0) {
-            return null;
-        }
-        return null;
-    }
-
-    /**
-     * Gets the GraphicsFactory.
-     * 
-     * @return the GraphicsFactory object.
-     */
-    public GraphicsFactory getGraphicsFactory() {
-        return wtk.getGraphicsFactory();
-    }
-
-    /**
-     * Instantiates a new toolkit.
-     */
-    public Toolkit() {
-        init();
-    }
-
-    /**
-     * Initiates AWT.
-     */
-    protected void init() {
-        lockAWT();
-        try {
-            ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
-            new EventQueue(this); // create the system EventQueue
-            dispatcher = new Dispatcher(this);
-            final String className = getWTKClassName();
-            desktopProperties = new HashMap<String, Object>();
-            desktopPropsSupport = new PropertyChangeSupport(this);
-            awtEventsManager = new AWTEventsManager();
-            dispatchThread = new EventDispatchThread(this, dispatcher);
-            nativeThread = new NativeEventThread();
-            NativeEventThread.Init init = new NativeEventThread.Init() {
-                public WTK init() {
-                    wtk = createWTK(className);
-                    wtk.getNativeEventQueue().setShutdownWatchdog(shutdownWatchdog);
-                    synchronizer.setEnvironment(wtk, dispatchThread);
-                    ContextStorage.setWTK(wtk);
-                    return wtk;
-                }
-            };
-            nativeThread.start(init);
-            dispatchThread.start();
-            wtk.getNativeEventQueue().awake();
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Synchronizes this toolkit's graphics.
-     */
-    public abstract void sync();
-
-    /**
-     * Returns the construction status of a specified image that is being
-     * created.
-     * 
-     * @param a0
-     *            the image to be checked.
-     * @param a1
-     *            the width of scaled image for which the status is being
-     *            checked or -1.
-     * @param a2
-     *            the height of scaled image for which the status is being
-     *            checked or -1.
-     * @param a3
-     *            the ImageObserver object to be notified while the image is
-     *            being prepared.
-     * @return the ImageObserver flags which give the current state of the image
-     *         data.
-     */
-    public abstract int checkImage(Image a0, int a1, int a2, ImageObserver a3);
-
-    /**
-     * Creates the image with the specified ImageProducer.
-     * 
-     * @param a0
-     *            the ImageProducer to be used for image creation.
-     * @return the image with the specified ImageProducer.
-     */
-    public abstract Image createImage(ImageProducer a0);
-
-    /**
-     * Creates the image from the specified byte array, offset and length. The
-     * byte array should contain data with image format supported by Toolkit
-     * such as JPEG, GIF, or PNG.
-     * 
-     * @param a0
-     *            the byte array with the image data.
-     * @param a1
-     *            the offset of the beginning the image data in the byte array.
-     * @param a2
-     *            the length of the image data in the byte array.
-     * @return the created Image.
-     */
-    public abstract Image createImage(byte[] a0, int a1, int a2);
-
-    /**
-     * Creates the image using image data from the specified URL.
-     * 
-     * @param a0
-     *            the URL for extracting image data.
-     * @return the Image.
-     */
-    public abstract Image createImage(URL a0);
-
-    /**
-     * Creates the image using image data from the specified file.
-     * 
-     * @param a0
-     *            the file name which contains image data of supported format.
-     * @return the Image.
-     */
-    public abstract Image createImage(String a0);
-
-    /**
-     * Gets the color model.
-     * 
-     * @return the ColorModel of Toolkit's screen.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    public abstract ColorModel getColorModel() throws HeadlessException;
-
-    /**
-     * Gets the screen device metrics for the specified font.
-     * 
-     * @param font
-     *            the Font.
-     * @return the FontMetrics for the specified Font.
-     * @deprecated Use getLineMetrics method from Font class.
-     */
-
-    @Deprecated
-    public abstract FontMetrics getFontMetrics(Font font);
-
-    /**
-     * Prepares the specified image for rendering on the screen with the
-     * specified size.
-     * 
-     * @param a0
-     *            the Image to be prepared.
-     * @param a1
-     *            the width of the screen representation or -1 for the current
-     *            screen.
-     * @param a2
-     *            the height of the screen representation or -1 for the current
-     *            screen.
-     * @param a3
-     *            the ImageObserver object to be notified as soon as the image
-     *            is prepared.
-     * @return true, if image is fully prepared, false otherwise.
-     */
-    public abstract boolean prepareImage(Image a0, int a1, int a2, ImageObserver a3);
-
-    /**
-     * Creates an audio beep.
-     */
-    public abstract void beep();
-
-    /**
-     * Returns the array of font names which are available in this Toolkit.
-     * 
-     * @return the array of font names which are available in this Toolkit.
-     * @deprecated use GraphicsEnvironment.getAvailableFontFamilyNames() method.
-     */
-    @Deprecated
-    public abstract String[] getFontList();
-
-    /**
-     * Gets the the Font implementation using the specified peer interface.
-     * 
-     * @param a0
-     *            the Font name to be implemented.
-     * @param a1
-     *            the the font style: PLAIN, BOLD, ITALIC.
-     * @return the FontPeer implementation of the specified Font.
-     * @deprecated use java.awt.GraphicsEnvironment.getAllFonts method.
-     */
-
-    @Deprecated
-    protected abstract FontPeer getFontPeer(String a0, int a1);
-
-    /**
-     * Gets the image from the specified file which contains image data in a
-     * supported image format (such as JPEG, GIF, or PNG); this method should
-     * return the same Image for multiple calls of this method with the same
-     * image file name.
-     * 
-     * @param a0
-     *            the file name which contains image data in a supported image
-     *            format (such as JPEG, GIF, or PNG).
-     * @return the Image.
-     */
-    public abstract Image getImage(String a0);
-
-    /**
-     * Gets the image from the specified URL which contains image data in a
-     * supported image format (such as JPEG, GIF, or PNG); this method should
-     * return the same Image for multiple calls of this method with the same
-     * image URL.
-     * 
-     * @param a0
-     *            the URL which contains image data in a supported image format
-     *            (such as JPEG, GIF, or PNG).
-     * @return the Image.
-     */
-    public abstract Image getImage(URL a0);
-
-    /**
-     * Gets the screen resolution.
-     * 
-     * @return the screen resolution.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    public abstract int getScreenResolution() throws HeadlessException;
-
-    /**
-     * Gets the screen size.
-     * 
-     * @return a Dimension object containing the width and height of the screen.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    public abstract Dimension getScreenSize() throws HeadlessException;
-
-    /**
-     * Gets the EventQueue instance without checking access.
-     * 
-     * @return the system EventQueue.
-     */
-    protected abstract EventQueue getSystemEventQueueImpl();
-
-    /**
-     * Returns a map of text attributes for the abstract level description of
-     * the specified input method highlight, or null if no mapping is found.
-     * 
-     * @param highlight
-     *            the InputMethodHighlight.
-     * @return the Map<java.awt.font. text attribute,?>.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    public abstract Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
-            InputMethodHighlight highlight) throws HeadlessException;
-
-    /**
-     * Map input method highlight impl.
-     * 
-     * @param highlight
-     *            the highlight.
-     * @return the map<java.awt.font. text attribute,?>.
-     * @throws HeadlessException
-     *             the headless exception.
-     */
-    Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(InputMethodHighlight highlight)
-            throws HeadlessException {
-        HashMap<java.awt.font.TextAttribute, ?> map = new HashMap<java.awt.font.TextAttribute, Object>();
-        wtk.getSystemProperties().mapInputMethodHighlight(highlight, map);
-        return Collections.<java.awt.font.TextAttribute, Object> unmodifiableMap(map);
-    }
-
-    /**
-     * Adds the specified PropertyChangeListener listener for the specified
-     * property.
-     * 
-     * @param propName
-     *            the property name for which the specified
-     *            PropertyChangeListener will be added.
-     * @param l
-     *            the PropertyChangeListener object.
-     */
-    public void addPropertyChangeListener(String propName, PropertyChangeListener l) {
-        lockAWT();
-        try {
-            if (desktopProperties.isEmpty()) {
-                initializeDesktopProperties();
-            }
-        } finally {
-            unlockAWT();
-        }
-        if (l != null) { // there is no guarantee that null listener will not be
-            // added
-            desktopPropsSupport.addPropertyChangeListener(propName, l);
-        }
-    }
-
-    /**
-     * Returns an array of the property change listeners registered with this
-     * Toolkit.
-     * 
-     * @return an array of the property change listeners registered with this
-     *         Toolkit.
-     */
-    public PropertyChangeListener[] getPropertyChangeListeners() {
-        return desktopPropsSupport.getPropertyChangeListeners();
-    }
-
-    /**
-     * Returns an array of the property change listeners registered with this
-     * Toolkit for notification regarding the specified property.
-     * 
-     * @param propName
-     *            the property name for which the PropertyChangeListener was
-     *            registered.
-     * @return the array of PropertyChangeListeners registered for the specified
-     *         property name.
-     */
-    public PropertyChangeListener[] getPropertyChangeListeners(String propName) {
-        return desktopPropsSupport.getPropertyChangeListeners(propName);
-    }
-
-    /**
-     * Removes the specified property change listener registered for the
-     * specified property name.
-     * 
-     * @param propName
-     *            the property name.
-     * @param l
-     *            the PropertyChangeListener registered for the specified
-     *            property name.
-     */
-    public void removePropertyChangeListener(String propName, PropertyChangeListener l) {
-        desktopPropsSupport.removePropertyChangeListener(propName, l);
-    }
-
-    /**
-     * Creates a custom cursor with the specified Image, hot spot, and cursor
-     * description.
-     * 
-     * @param img
-     *            the image of activated cursor.
-     * @param hotSpot
-     *            the Point giving the coordinates of the cursor's hot spot.
-     * @param name
-     *            the cursor description.
-     * @return the cursor with the specified Image, hot spot, and cursor
-     *         description.
-     * @throws IndexOutOfBoundsException
-     *             if the hot spot values are outside the bounds of the cursor.
-     * @throws HeadlessException
-     *             if isHeadless() method of GraphicsEnvironment class returns
-     *             true.
-     */
-    public Cursor createCustomCursor(Image img, Point hotSpot, String name)
-            throws IndexOutOfBoundsException, HeadlessException {
-        lockAWT();
-        try {
-            int w = img.getWidth(null), x = hotSpot.x;
-            int h = img.getHeight(null), y = hotSpot.y;
-            if (x < 0 || x >= w || y < 0 || y >= h) {
-                // awt.7E=invalid hotSpot
-                throw new IndexOutOfBoundsException(Messages.getString("awt.7E")); //$NON-NLS-1$
-            }
-            return new Cursor(name, img, hotSpot);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Returns the supported cursor dimension which is closest to the specified
-     * width and height. If the Toolkit only supports a single cursor size, this
-     * method should return the supported cursor size. If custom cursor is not
-     * supported, a dimension of 0, 0 should be returned.
-     * 
-     * @param prefWidth
-     *            the preferred cursor width.
-     * @param prefHeight
-     *            the preferred cursor height.
-     * @return the supported cursor dimension which is closest to the specified
-     *         width and height.
-     * @throws HeadlessException
-     *             if GraphicsEnvironment.isHeadless() returns true.
-     */
-    public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
-        lockAWT();
-        try {
-            return wtk.getCursorFactory().getBestCursorSize(prefWidth, prefHeight);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the value for the specified desktop property.
-     * 
-     * @param propName
-     *            the property name.
-     * @return the Object that is the property's value.
-     */
-    public final Object getDesktopProperty(String propName) {
-        lockAWT();
-        try {
-            if (desktopProperties.isEmpty()) {
-                initializeDesktopProperties();
-            }
-            if (propName.equals("awt.dynamicLayoutSupported")) { //$NON-NLS-1$
-                // dynamicLayoutSupported is special case
-                return Boolean.valueOf(isDynamicLayoutActive());
-            }
-            Object val = desktopProperties.get(propName);
-            if (val == null) {
-                // try to lazily load prop value
-                // just for compatibility, our lazilyLoad is empty
-                val = lazilyLoadDesktopProperty(propName);
-            }
-            return val;
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Returns the locking key state for the specified key.
-     * 
-     * @param a0
-     *            the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, or
-     *            VK_KANA_LOCK.
-     * @return true if the specified key code is in the locked state, false
-     *         otherwise.
-     * @throws UnsupportedOperationException
-     *             if the state of this key can't be retrieved, or if the
-     *             keyboard doesn't have this key.
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public boolean getLockingKeyState(int a0) throws UnsupportedOperationException,
-            org.apache.harmony.luni.util.NotImplementedException {
-        lockAWT();
-        try {
-        } finally {
-            unlockAWT();
-        }
-        if (true) {
-            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
-        }
-        return true;
-    }
-
-    /**
-     * Returns the maximum number of colors which the Toolkit supports for
-     * custom cursor.
-     * 
-     * @return the maximum cursor colors.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    public int getMaximumCursorColors() throws HeadlessException {
-        lockAWT();
-        try {
-            return wtk.getCursorFactory().getMaximumCursorColors();
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the menu shortcut key mask.
-     * 
-     * @return the menu shortcut key mask.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    public int getMenuShortcutKeyMask() throws HeadlessException {
-        lockAWT();
-        try {
-            return InputEvent.CTRL_MASK;
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the screen insets.
-     * 
-     * @param gc
-     *            the GraphicsConfiguration.
-     * @return the insets of this toolkit.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
-        if (gc == null) {
-            throw new NullPointerException();
-        }
-        lockAWT();
-        try {
-            return new Insets(0, 0, 0, 0); // TODO: get real screen insets
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the system EventQueue instance. If the default implementation of
-     * checkAwtEventQueueAccess is used, then this results of a call to the
-     * security manager's checkPermission method with an
-     * AWTPermission("accessEventQueue") permission.
-     * 
-     * @return the system EventQueue instance.
-     */
-    public final EventQueue getSystemEventQueue() {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkAwtEventQueueAccess();
-        }
-        return getSystemEventQueueImpl();
-    }
-
-    /**
-     * Gets the system event queue core.
-     * 
-     * @return the system event queue core.
-     */
-    EventQueueCore getSystemEventQueueCore() {
-        return systemEventQueueCore;
-    }
-
-    /**
-     * Sets the system event queue core.
-     * 
-     * @param core
-     *            the new system event queue core.
-     */
-    void setSystemEventQueueCore(EventQueueCore core) {
-        systemEventQueueCore = core;
-    }
-
-    /**
-     * Initialize the desktop properties.
-     */
-    protected void initializeDesktopProperties() {
-        lockAWT();
-        try {
-            wtk.getSystemProperties().init(desktopProperties);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Checks if dynamic layout of Containers is active or not.
-     * 
-     * @return true, if is dynamic layout of Containers is active, false
-     *         otherwise.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    public boolean isDynamicLayoutActive() throws HeadlessException {
-        lockAWT();
-        try {
-            // always return true
-            return true;
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Returns if the layout of Containers is checked dynamically during
-     * resizing, or statically after resizing is completed.
-     * 
-     * @return true, if if the layout of Containers is checked dynamically
-     *         during resizing; false, if the layout of Containers is checked
-     *         statically after resizing is completed.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    protected boolean isDynamicLayoutSet() throws HeadlessException {
-        lockAWT();
-        try {
-            return bDynamicLayoutSet;
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Checks if the specified frame state is supported by Toolkit or not.
-     * 
-     * @param state
-     *            the frame state.
-     * @return true, if frame state is supported, false otherwise.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    public boolean isFrameStateSupported(int state) throws HeadlessException {
-        lockAWT();
-        try {
-            return wtk.getWindowFactory().isWindowStateSupported(state);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Loads the value of the desktop property with the specified property name.
-     * 
-     * @param propName
-     *            the property name.
-     * @return the desktop property values.
-     */
-    protected Object lazilyLoadDesktopProperty(String propName) {
-        return null;
-    }
-
-    /**
-     * Loads the current system color values to the specified array.
-     * 
-     * @param colors
-     *            the array where the current system color values are written by
-     *            this method.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    protected void loadSystemColors(int[] colors) throws HeadlessException {
-        lockAWT();
-        try {
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the value of the desktop property with the specified name.
-     * 
-     * @param propName
-     *            the property's name.
-     * @param value
-     *            the property's value.
-     */
-    protected final void setDesktopProperty(String propName, Object value) {
-        Object oldVal;
-        lockAWT();
-        try {
-            oldVal = getDesktopProperty(propName);
-            userPropSet.add(propName);
-            desktopProperties.put(propName, value);
-        } finally {
-            unlockAWT();
-        }
-        desktopPropsSupport.firePropertyChange(propName, oldVal, value);
-    }
-
-    /**
-     * Sets the layout state, whether the Container layout is checked
-     * dynamically during resizing, or statically after resizing is completed.
-     * 
-     * @param dynamic
-     *            the new dynamic layout state - if true the layout of
-     *            Containers is checked dynamically during resizing, if false -
-     *            statically after resizing is completed.
-     * @throws HeadlessException
-     *             if the GraphicsEnvironment.isHeadless() method returns true.
-     */
-    public void setDynamicLayout(boolean dynamic) throws HeadlessException {
-        lockAWT();
-        try {
-            bDynamicLayoutSet = dynamic;
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Sets the locking key state for the specified key code.
-     * 
-     * @param a0
-     *            the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, or
-     *            VK_KANA_LOCK.
-     * @param a1
-     *            the state - true to set the specified key code to the locked
-     *            state, false - to unlock it.
-     * @throws UnsupportedOperationException
-     *             if the state of this key can't be set, or if the keyboard
-     *             doesn't have this key.
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public void setLockingKeyState(int a0, boolean a1) throws UnsupportedOperationException,
-            org.apache.harmony.luni.util.NotImplementedException {
-        lockAWT();
-        try {
-        } finally {
-            unlockAWT();
-        }
-        if (true) {
-            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
-        }
-        return;
-    }
-
-    /**
-     * On queue empty.
-     */
-    void onQueueEmpty() {
-        throw new RuntimeException("Not implemented!");
-    }
-
-    /**
-     * Creates the wtk.
-     * 
-     * @param clsName
-     *            the cls name.
-     * @return the wTK.
-     */
-    private WTK createWTK(String clsName) {
-        WTK newWTK = null;
-        try {
-            newWTK = (WTK)Class.forName(clsName).newInstance();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        return newWTK;
-    }
-
-    /**
-     * Connect the component to its native window
-     * 
-     * @param winId
-     *            the id of native window just created.
-     */
-    boolean onWindowCreated(long winId) {
-        return false;
-    }
-
-    /**
-     * Gets the native event queue.
-     * 
-     * @return the native event queue.
-     */
-    NativeEventQueue getNativeEventQueue() {
-        return wtk.getNativeEventQueue();
-    }
-
-    /**
-     * Returns a shared instance of implementation of
-     * org.apache.harmony.awt.wtk.NativeCursor for current platform for.
-     * 
-     * @param type
-     *            the Java Cursor type.
-     * @return new instance of implementation of NativeCursor.
-     */
-    NativeCursor createNativeCursor(int type) {
-        return wtk.getCursorFactory().getCursor(type);
-    }
-
-    /**
-     * Returns a shared instance of implementation of
-     * org.apache.harmony.awt.wtk.NativeCursor for current platform for custom
-     * cursor
-     * 
-     * @param img
-     *            the img.
-     * @param hotSpot
-     *            the hot spot.
-     * @param name
-     *            the name.
-     * @return new instance of implementation of NativeCursor.
-     */
-    NativeCursor createCustomNativeCursor(Image img, Point hotSpot, String name) {
-        return wtk.getCursorFactory().createCustomCursor(img, hotSpot.x, hotSpot.y);
-    }
-
-    /**
-     * Adds an AWTEventListener to the Toolkit to listen for events of types
-     * corresponding to bits in the specified event mask. Event masks are
-     * defined in AWTEvent class.
-     * 
-     * @param listener
-     *            the AWTEventListener.
-     * @param eventMask
-     *            the bitmask of event types.
-     */
-    public void addAWTEventListener(AWTEventListener listener, long eventMask) {
-        lockAWT();
-        try {
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                security.checkPermission(awtEventsManager.permission);
-            }
-            awtEventsManager.addAWTEventListener(listener, eventMask);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Removes the specified AWT event listener.
-     * 
-     * @param listener
-     *            the AWTEventListener to be removed.
-     */
-    public void removeAWTEventListener(AWTEventListener listener) {
-        lockAWT();
-        try {
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                security.checkPermission(awtEventsManager.permission);
-            }
-            awtEventsManager.removeAWTEventListener(listener);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Gets the array of all AWT event listeners registered with this Toolkit.
-     * 
-     * @return the array of all AWT event listeners registered with this
-     *         Toolkit.
-     */
-    public AWTEventListener[] getAWTEventListeners() {
-        lockAWT();
-        try {
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                security.checkPermission(awtEventsManager.permission);
-            }
-            return awtEventsManager.getAWTEventListeners();
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Returns the array of the AWT event listeners registered with this Toolkit
-     * for the event types corresponding to the specified event mask.
-     * 
-     * @param eventMask
-     *            the bit mask of event type.
-     * @return the array of the AWT event listeners registered in this Toolkit
-     *         for the event types corresponding to the specified event mask.
-     */
-    public AWTEventListener[] getAWTEventListeners(long eventMask) {
-        lockAWT();
-        try {
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                security.checkPermission(awtEventsManager.permission);
-            }
-            return awtEventsManager.getAWTEventListeners(eventMask);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    /**
-     * Dispatch AWT event.
-     * 
-     * @param event
-     *            the event.
-     */
-    void dispatchAWTEvent(AWTEvent event) {
-        awtEventsManager.dispatchAWTEvent(event);
-    }
-
-    /**
-     * The Class AWTEventsManager.
-     */
-    final class AWTEventsManager {
-
-        /**
-         * The permission.
-         */
-        AWTPermission permission = new AWTPermission("listenToAllAWTEvents"); //$NON-NLS-1$
-
-        /**
-         * The listeners.
-         */
-        private final AWTListenerList<AWTEventListenerProxy> listeners = new AWTListenerList<AWTEventListenerProxy>();
-
-        /**
-         * Adds the AWT event listener.
-         * 
-         * @param listener
-         *            the listener.
-         * @param eventMask
-         *            the event mask.
-         */
-        void addAWTEventListener(AWTEventListener listener, long eventMask) {
-            if (listener != null) {
-                listeners.addUserListener(new AWTEventListenerProxy(eventMask, listener));
-            }
-        }
-
-        /**
-         * Removes the AWT event listener.
-         * 
-         * @param listener
-         *            the listener.
-         */
-        void removeAWTEventListener(AWTEventListener listener) {
-            if (listener != null) {
-                for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
-                    if (listener == proxy.getListener()) {
-                        listeners.removeUserListener(proxy);
-                        return;
-                    }
-                }
-            }
-        }
-
-        /**
-         * Gets the AWT event listeners.
-         * 
-         * @return the AWT event listeners.
-         */
-        AWTEventListener[] getAWTEventListeners() {
-            HashSet<EventListener> listenersSet = new HashSet<EventListener>();
-            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
-                listenersSet.add(proxy.getListener());
-            }
-            return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
-        }
-
-        /**
-         * Gets the AWT event listeners.
-         * 
-         * @param eventMask
-         *            the event mask.
-         * @return the AWT event listeners.
-         */
-        AWTEventListener[] getAWTEventListeners(long eventMask) {
-            HashSet<EventListener> listenersSet = new HashSet<EventListener>();
-            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
-                if ((proxy.getEventMask() & eventMask) == eventMask) {
-                    listenersSet.add(proxy.getListener());
-                }
-            }
-            return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
-        }
-
-        /**
-         * Dispatch AWT event.
-         * 
-         * @param event
-         *            the event.
-         */
-        void dispatchAWTEvent(AWTEvent event) {
-            AWTEvent.EventDescriptor descriptor = eventTypeLookup.getEventDescriptor(event);
-            if (descriptor == null) {
-                return;
-            }
-            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
-                if ((proxy.getEventMask() & descriptor.eventMask) != 0) {
-                    proxy.eventDispatched(event);
-                }
-            }
-        }
-    }
-
-    /**
-     * The Class AutoNumber.
-     */
-    static final class AutoNumber {
-
-        /**
-         * The next component.
-         */
-        int nextComponent = 0;
-
-        /**
-         * The next canvas.
-         */
-        int nextCanvas = 0;
-
-        /**
-         * The next panel.
-         */
-        int nextPanel = 0;
-
-        /**
-         * The next window.
-         */
-        int nextWindow = 0;
-
-        /**
-         * The next frame.
-         */
-        int nextFrame = 0;
-
-        /**
-         * The next dialog.
-         */
-        int nextDialog = 0;
-
-        /**
-         * The next button.
-         */
-        int nextButton = 0;
-
-        /**
-         * The next menu component.
-         */
-        int nextMenuComponent = 0;
-
-        /**
-         * The next label.
-         */
-        int nextLabel = 0;
-
-        /**
-         * The next check box.
-         */
-        int nextCheckBox = 0;
-
-        /**
-         * The next scrollbar.
-         */
-        int nextScrollbar = 0;
-
-        /**
-         * The next scroll pane.
-         */
-        int nextScrollPane = 0;
-
-        /**
-         * The next list.
-         */
-        int nextList = 0;
-
-        /**
-         * The next choice.
-         */
-        int nextChoice = 0;
-
-        /**
-         * The next file dialog.
-         */
-        int nextFileDialog = 0;
-
-        /**
-         * The next text area.
-         */
-        int nextTextArea = 0;
-
-        /**
-         * The next text field.
-         */
-        int nextTextField = 0;
-    }
-
-    private class Lock {
-    }
-
-    /**
-     * The lock.
-     */
-    private final Object lock = new Lock();
-
-}
diff --git a/awt/java/awt/ToolkitImpl.java b/awt/java/awt/ToolkitImpl.java
deleted file mode 100644
index 5015aef..0000000
--- a/awt/java/awt/ToolkitImpl.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.awt;
-
-import java.awt.im.InputMethodHighlight;
-import java.awt.image.ColorModel;
-import java.awt.image.ImageObserver;
-import java.awt.image.ImageProducer;
-import java.awt.peer.*;
-import java.io.Serializable;
-import java.net.URL;
-import java.util.Hashtable;
-import java.util.Map;
-import org.apache.harmony.awt.gl.image.*;
-import org.apache.harmony.awt.wtk.GraphicsFactory;
-
-class ToolkitImpl extends Toolkit {
-	
-    static final Hashtable<Serializable, Image> imageCache = new Hashtable<Serializable, Image>();
-
-    @Override
-    public void sync() {
-        lockAWT();
-        try {
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public int checkImage(Image image, int width, int height, ImageObserver observer) {
-        lockAWT();
-        try {
-            if (width == 0 || height == 0) {
-                return ImageObserver.ALLBITS;
-            }
-            if (!(image instanceof OffscreenImage)) {
-                return ImageObserver.ALLBITS;
-            }
-            OffscreenImage oi = (OffscreenImage) image;
-            return oi.checkImage(observer);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public Image createImage(ImageProducer producer) {
-        lockAWT();
-        try {
-            return new OffscreenImage(producer);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public Image createImage(byte[] imagedata, int imageoffset, int imagelength) {
-        lockAWT();
-        try {
-            return new OffscreenImage(new ByteArrayDecodingImageSource(imagedata, imageoffset,
-                    imagelength));
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public Image createImage(URL url) {
-        lockAWT();
-        try {
-            return new OffscreenImage(new URLDecodingImageSource(url));
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public Image createImage(String filename) {
-        lockAWT();
-        try {
-            return new OffscreenImage(new FileDecodingImageSource(filename));
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public ColorModel getColorModel() {
-        lockAWT();
-        try {
-            return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()
-                    .getDefaultConfiguration().getColorModel();
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    @Deprecated
-    public FontMetrics getFontMetrics(Font font) {
-        lockAWT();
-        try {
-        	GraphicsFactory gf = getGraphicsFactory();
-            return gf.getFontMetrics(font);
-        } finally {
-            unlockAWT();
-        }
-    }
-    
-    @Override
-    public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
-        lockAWT();
-        try {
-            if (width == 0 || height == 0) {
-                return true;
-            }
-            if (!(image instanceof OffscreenImage)) {
-                return true;
-            }
-            OffscreenImage oi = (OffscreenImage) image;
-            return oi.prepareImage(observer);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public void beep() {
-        lockAWT();
-        try {
-        	// ???AWT: is there nothing to be implemented here?
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    @Deprecated
-    public String[] getFontList() {
-        lockAWT();
-        try {
-        } finally {
-            unlockAWT();
-        }
-        return null;
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    @Deprecated
-    protected FontPeer getFontPeer(String a0, int a1) {
-        lockAWT();
-        try {
-            return null;
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public Image getImage(String filename) {
-        return getImage(filename, this);
-    }
-
-    static Image getImage(String filename, Toolkit toolkit) {
-        synchronized (imageCache) {
-            Image im = (filename == null ? null : imageCache.get(filename));
-
-            if (im == null) {
-                try {
-                    im = toolkit.createImage(filename);
-                    imageCache.put(filename, im);
-                } catch (Exception e) {
-                }
-            }
-
-            return im;
-        }
-    }
-
-    @Override
-    public Image getImage(URL url) {
-        return getImage(url, this);
-    }
-
-    static Image getImage(URL url, Toolkit toolkit) {
-        synchronized (imageCache) {
-            Image im = imageCache.get(url);
-            if (im == null) {
-                try {
-                    im = toolkit.createImage(url);
-                    imageCache.put(url, im);
-                } catch (Exception e) {
-                }
-            }
-            return im;
-        }
-    }
-
-    @Override
-    public int getScreenResolution() throws HeadlessException {
-        lockAWT();
-        try {
-        	return 62;
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public Dimension getScreenSize() {
-        lockAWT();
-        try {
-            DisplayMode dm = GraphicsEnvironment.getLocalGraphicsEnvironment()
-                    .getDefaultScreenDevice().getDisplayMode();
-            return new Dimension(dm.getWidth(), dm.getHeight());
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    public Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
-            InputMethodHighlight highlight) throws HeadlessException {
-        lockAWT();
-        try {
-            return mapInputMethodHighlightImpl(highlight);
-        } finally {
-            unlockAWT();
-        }
-    }
-
-    @Override
-    protected EventQueue getSystemEventQueueImpl() {
-        return getSystemEventQueueCore().getActiveEventQueue();
-    }
-}
diff --git a/awt/java/awt/Transparency.java b/awt/java/awt/Transparency.java
deleted file mode 100644
index 44a1e7f..0000000
--- a/awt/java/awt/Transparency.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-
-package java.awt;
-
-/**
- * The Transparency interface defines transparency's general modes.
- * 
- * @since Android 1.0
- */
-public interface Transparency {
-
-    /**
-     * The Constant OPAQUE represents completely opaque data, all pixels have an
-     * alpha value of 1.0.
-     */
-    public static final int OPAQUE = 1;
-
-    /**
-     * The Constant BITMASK represents data which can be either completely
-     * opaque, with an alpha value of 1.0, or completely transparent, with an
-     * alpha value of 0.0.
-     */
-    public static final int BITMASK = 2;
-
-    /**
-     * The Constant TRANSLUCENT represents data which alpha value can vary
-     * between and including 0.0 and 1.0.
-     */
-    public static final int TRANSLUCENT = 3;
-
-    /**
-     * Gets the transparency mode.
-     * 
-     * @return the transparency mode: OPAQUE, BITMASK or TRANSLUCENT.
-     */
-    public int getTransparency();
-
-}
diff --git a/awt/java/awt/color/CMMException.java b/awt/java/awt/color/CMMException.java
deleted file mode 100644
index 18b9a7e..0000000
--- a/awt/java/awt/color/CMMException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package java.awt.color;
-
-/**
- * The CMMException is thrown as soon as a native CMM error occurs.
- * 
- * @since Android 1.0
- */
-public class CMMException extends java.lang.RuntimeException {
-    
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 5775558044142994965L;
-
-    /**
-     * Instantiates a new CMM exception with detail message.
-     * 
-     * @param s
-     *            the detail message of the exception.
-     */
-    public CMMException (String s) {
-        super (s);
-    }
-}
diff --git a/awt/java/awt/color/ColorSpace.java b/awt/java/awt/color/ColorSpace.java
deleted file mode 100644
index 44c491b..0000000
--- a/awt/java/awt/color/ColorSpace.java
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package java.awt.color;
-
-import java.io.Serializable;
-
-import org.apache.harmony.awt.gl.color.LUTColorConverter;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The ColorSpace class defines a color space type for a Color and provides
- * methods for arrays of color component operations.
- * 
- * @since Android 1.0
- */
-public abstract class ColorSpace implements Serializable {
-
-    /** The Constant serialVersionUID. */
-    private static final long serialVersionUID = -409452704308689724L;
-
-    /**
-     * The Constant TYPE_XYZ indicates XYZ color space type.
-     */
-    public static final int TYPE_XYZ = 0;
-
-    /**
-     * The Constant TYPE_Lab indicates Lab color space type.
-     */
-    public static final int TYPE_Lab = 1;
-
-    /**
-     * The Constant TYPE_Luv indicates Luv color space type.
-     */
-    public static final int TYPE_Luv = 2;
-
-    /**
-     * The Constant TYPE_YCbCr indicates YCbCr color space type.
-     */
-    public static final int TYPE_YCbCr = 3;
-
-    /**
-     * The Constant TYPE_Yxy indicates Yxy color space type.
-     */
-    public static final int TYPE_Yxy = 4;
-
-    /**
-     * The Constant TYPE_RGB indicates RGB color space type.
-     */
-    public static final int TYPE_RGB = 5;
-
-    /**
-     * The Constant TYPE_GRAY indicates Gray color space type.
-     */
-    public static final int TYPE_GRAY = 6;
-
-    /**
-     * The Constant TYPE_HSV indicates HSV color space type.
-     */
-    public static final int TYPE_HSV = 7;
-
-    /**
-     * The Constant TYPE_HLS indicates HLS color space type.
-     */
-    public static final int TYPE_HLS = 8;
-
-    /**
-     * The Constant TYPE_CMYK indicates CMYK color space type.
-     */
-    public static final int TYPE_CMYK = 9;
-
-    /**
-     * The Constant TYPE_CMY indicates CMY color space type.
-     */
-    public static final int TYPE_CMY = 11;
-
-    /**
-     * The Constant TYPE_2CLR indicates color spaces with 2 components.
-     */
-    public static final int TYPE_2CLR = 12;
-
-    /**
-     * The Constant TYPE_3CLR indicates color spaces with 3 components.
-     */
-    public static final int TYPE_3CLR = 13;
-
-    /**
-     * The Constant TYPE_4CLR indicates color spaces with 4 components.
-     */
-    public static final int TYPE_4CLR = 14;
-
-    /**
-     * The Constant TYPE_5CLR indicates color spaces with 5 components.
-     */
-    public static final int TYPE_5CLR = 15;
-
-    /**
-     * The Constant TYPE_6CLR indicates color spaces with 6 components.
-     */
-    public static final int TYPE_6CLR = 16;
-
-    /**
-     * The Constant TYPE_7CLR indicates color spaces with 7 components.
-     */
-    public static final int TYPE_7CLR = 17;
-
-    /**
-     * The Constant TYPE_8CLR indicates color spaces with 8 components.
-     */
-    public static final int TYPE_8CLR = 18;
-
-    /**
-     * The Constant TYPE_9CLR indicates color spaces with 9 components.
-     */
-    public static final int TYPE_9CLR = 19;
-
-    /**
-     * The Constant TYPE_ACLR indicates color spaces with 10 components.
-     */
-    public static final int TYPE_ACLR = 20;
-
-    /**
-     * The Constant TYPE_BCLR indicates color spaces with 11 components.
-     */
-    public static final int TYPE_BCLR = 21;
-
-    /**
-     * The Constant TYPE_CCLR indicates color spaces with 12 components.
-     */
-    public static final int TYPE_CCLR = 22;
-
-    /**
-     * The Constant TYPE_DCLR indicates color spaces with 13 components.
-     */
-    public static final int TYPE_DCLR = 23;
-
-    /**
-     * The Constant TYPE_ECLR indicates color spaces with 14 components.
-     */
-    public static final int TYPE_ECLR = 24;
-
-    /**
-     * The Constant TYPE_FCLR indicates color spaces with 15 components.
-     */
-    public static final int TYPE_FCLR = 25;
-
-    /**
-     * The Constant CS_sRGB indicates standard RGB color space.
-     */
-    public static final int CS_sRGB = 1000;
-
-    /**
-     * The Constant CS_LINEAR_RGB indicates linear RGB color space.
-     */
-    public static final int CS_LINEAR_RGB = 1004;
-
-    /**
-     * The Constant CS_CIEXYZ indicates CIEXYZ conversion color space.
-     */
-    public static final int CS_CIEXYZ = 1001;
-
-    /**
-     * The Constant CS_PYCC indicates Photo YCC conversion color space.
-     */
-    public static final int CS_PYCC = 1002;
-
-    /**
-     * The Constant CS_GRAY indicates linear gray scale color space.
-     */
-    public static final int CS_GRAY = 1003;
-
-    /**
-     * The cs_ gray.
-     */
-    private static ColorSpace cs_Gray = null;
-    
-    /**
-     * The cs_ pycc.
-     */
-    private static ColorSpace cs_PYCC = null;
-    
-    /**
-     * The cs_ ciexyz.
-     */
-    private static ColorSpace cs_CIEXYZ = null;
-    
-    /**
-     * The cs_ lrgb.
-     */
-    private static ColorSpace cs_LRGB = null;
-    
-    /**
-     * The cs_s rgb.
-     */
-    private static ColorSpace cs_sRGB = null;
-
-    /**
-     * The type.
-     */
-    private int type;
-    
-    /**
-     * The num components.
-     */
-    private int numComponents;
-
-    /**
-     * Instantiates a ColorSpace with the specified ColorSpace type and number
-     * of components.
-     * 
-     * @param type
-     *            the type of color space.
-     * @param numcomponents
-     *            the number of components.
-     */
-    protected ColorSpace(int type, int numcomponents) {
-        this.numComponents = numcomponents;
-        this.type = type;
-    }
-
-    /**
-     * Gets the name of the component for the specified component index.
-     * 
-     * @param idx
-     *            the index of the component.
-     * @return the name of the component.
-     */
-    public String getName(int idx) {
-        if (idx < 0 || idx > numComponents - 1) {
-            // awt.16A=Invalid component index: {0}
-            throw new IllegalArgumentException(Messages.getString("awt.16A", idx)); //$NON-NLS-1$
-        }
-
-      return "Unnamed color component #" + idx; //$NON-NLS-1$
-    }
-
-    /**
-     * Performs the transformation of a color from this ColorSpace into the RGB
-     * color space.
-     * 
-     * @param colorvalue
-     *            the color value in this ColorSpace.
-     * @return the float array with color components in the RGB color space.
-     */
-    public abstract float[] toRGB(float[] colorvalue);
-
-    /**
-     * Performs the transformation of a color from this ColorSpace into the
-     * CS_CIEXYZ color space.
-     * 
-     * @param colorvalue
-     *            the color value in this ColorSpace.
-     * @return the float array with color components in the CS_CIEXYZ color
-     *         space.
-     */
-    public abstract float[] toCIEXYZ(float[] colorvalue);
-
-    /**
-     * Performs the transformation of a color from the RGB color space into this
-     * ColorSpace.
-     * 
-     * @param rgbvalue
-     *            the float array representing a color in the RGB color space.
-     * @return the float array with the transformed color components.
-     */
-    public abstract float[] fromRGB(float[] rgbvalue);
-
-    /**
-     * Performs the transformation of a color from the CS_CIEXYZ color space
-     * into this ColorSpace.
-     * 
-     * @param colorvalue
-     *            the float array representing a color in the CS_CIEXYZ color
-     *            space.
-     * @return the float array with the transformed color components.
-     */
-    public abstract float[] fromCIEXYZ(float[] colorvalue);
-
-    /**
-     * Gets the minimum normalized color component value for the specified
-     * component.
-     * 
-     * @param component
-     *            the component to determine the minimum value.
-     * @return the minimum normalized value of the component.
-     */
-    public float getMinValue(int component) {
-        if (component < 0 || component > numComponents - 1) {
-            // awt.16A=Invalid component index: {0}
-            throw new IllegalArgumentException(Messages.getString("awt.16A", component)); //$NON-NLS-1$
-        }
-        return 0;
-    }
-
-    /**
-     * Gets the maximum normalized color component value for the specified
-     * component.
-     * 
-     * @param component
-     *            the component to determine the maximum value.
-     * @return the maximum normalized value of the component.
-     */
-    public float getMaxValue(int component) {
-        if (component < 0 || component > numComponents - 1) {
-            // awt.16A=Invalid component index: {0}
-            throw new IllegalArgumentException(Messages.getString("awt.16A", component)); //$NON-NLS-1$
-        }
-        return 1;
-    }
-
-    /**
-     * Checks if this ColorSpace has CS_sRGB type or not.
-     * 
-     * @return true, if this ColorSpace has CS_sRGB type, false otherwise.
-     */
-    public boolean isCS_sRGB() {
-        // If our color space is sRGB, then cs_sRGB
-        // is already initialized
-        return (this == cs_sRGB);
-    }
-
-    /**
-     * Gets the type of the ColorSpace.
-     * 
-     * @return the type of the ColorSpace.
-     */
-    public int getType() {
-        return type;
-    }
-
-    /**
-     * Gets the number of components for this ColorSpace.
-     * 
-     * @return the number of components.
-     */
-    public int getNumComponents() {
-        return numComponents;
-    }
-
-
-    /**
-     * Gets the single instance of ColorSpace with the specified ColorSpace:
-     * CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ, CS_GRAY, or CS_PYCC.
-     * 
-     * @param colorspace
-     *            the identifier of the specified Colorspace.
-     * @return the single instance of the desired ColorSpace.
-     */
-    public static ColorSpace getInstance(int colorspace) {
-        switch (colorspace) {
-            case CS_sRGB:
-                if (cs_sRGB == null) {
-                    cs_sRGB = new ICC_ColorSpace(
-                            new ICC_ProfileStub(CS_sRGB));
-                    LUTColorConverter.sRGB_CS = cs_sRGB;
-                            //ICC_Profile.getInstance (CS_sRGB));
-                }
-                return cs_sRGB;
-            case CS_CIEXYZ:
-                if (cs_CIEXYZ == null) {
-                    cs_CIEXYZ = new ICC_ColorSpace(
-                            new ICC_ProfileStub(CS_CIEXYZ));
-                            //ICC_Profile.getInstance (CS_CIEXYZ));
-                }
-                return cs_CIEXYZ;
-            case CS_GRAY:
-                if (cs_Gray == null) {
-                    cs_Gray = new ICC_ColorSpace(
-                            new ICC_ProfileStub(CS_GRAY));
-                    LUTColorConverter.LINEAR_GRAY_CS = cs_Gray;
-                            //ICC_Profile.getInstance (CS_GRAY));
-                }
-                return cs_Gray;
-            case CS_PYCC:
-                if (cs_PYCC == null) {
-                    cs_PYCC = new ICC_ColorSpace(
-                            new ICC_ProfileStub(CS_PYCC));
-                            //ICC_Profile.getInstance (CS_PYCC));
-                }
-                return cs_PYCC;
-            case CS_LINEAR_RGB:
-                if (cs_LRGB == null) {
-                    cs_LRGB = new ICC_ColorSpace(
-                            new ICC_ProfileStub(CS_LINEAR_RGB));
-                    LUTColorConverter.LINEAR_GRAY_CS = cs_Gray;
-                            //ICC_Profile.getInstance (CS_LINEAR_RGB));
-                }
-                return cs_LRGB;
-            default:
-        }
-
-        // Unknown argument passed
-        // awt.16B=Not a predefined colorspace
-        throw new IllegalArgumentException(Messages.getString("Not a predefined colorspace")); //$NON-NLS-1$
-    }
-
-}
\ No newline at end of file
diff --git a/awt/java/awt/color/ICC_ColorSpace.java b/awt/java/awt/color/ICC_ColorSpace.java
deleted file mode 100644
index 5b4d7e9..0000000
--- a/awt/java/awt/color/ICC_ColorSpace.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package java.awt.color;
-
-import org.apache.harmony.awt.gl.color.ColorConverter;
-import org.apache.harmony.awt.gl.color.ColorScaler;
-import org.apache.harmony.awt.gl.color.ICC_Transform;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-import java.io.*;
-
-/**
- * This class implements the abstract class ColorSpace and represents device
- * independent and device dependent color spaces. This color space is based on
- * the International Color Consortium Specification (ICC) File Format for Color
- * Profiles: <a href="http://www.color.org">http://www.color.org</a>
- * 
- * @since Android 1.0
- */
-public class ICC_ColorSpace extends ColorSpace {
-    
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 3455889114070431483L;
-
-    // Need to keep compatibility with serialized form
-    /**
-     * The Constant serialPersistentFields.
-     */
-    private static final ObjectStreamField[]
-      serialPersistentFields = {
-        new ObjectStreamField("thisProfile", ICC_Profile.class), //$NON-NLS-1$
-        new ObjectStreamField("minVal", float[].class), //$NON-NLS-1$
-        new ObjectStreamField("maxVal", float[].class), //$NON-NLS-1$
-        new ObjectStreamField("diffMinMax", float[].class), //$NON-NLS-1$
-        new ObjectStreamField("invDiffMinMax", float[].class), //$NON-NLS-1$
-        new ObjectStreamField("needScaleInit", Boolean.TYPE) //$NON-NLS-1$
-    };
-
-
-   /**
-     * According to ICC specification (from http://www.color.org) "For the
-     * CIEXYZ encoding, each component (X, Y, and Z) is encoded as a
-     * u1Fixed15Number". This means that max value for this encoding is 1 +
-     * (32767/32768)
-     */
-    private static final float MAX_XYZ = 1f + (32767f/32768f);
-    
-    /**
-     * The Constant MAX_SHORT.
-     */
-    private static final float MAX_SHORT = 65535f;
-    
-    /**
-     * The Constant INV_MAX_SHORT.
-     */
-    private static final float INV_MAX_SHORT = 1f/MAX_SHORT;
-    
-    /**
-     * The Constant SHORT2XYZ_FACTOR.
-     */
-    private static final float SHORT2XYZ_FACTOR = MAX_XYZ/MAX_SHORT;
-    
-    /**
-     * The Constant XYZ2SHORT_FACTOR.
-     */
-    private static final float XYZ2SHORT_FACTOR = MAX_SHORT/MAX_XYZ;
-
-    /**
-     * The profile.
-     */
-    private ICC_Profile profile = null;
-    
-    /**
-     * The min values.
-     */
-    private float minValues[] = null;
-    
-    /**
-     * The max values.
-     */
-    private float maxValues[] = null;
-
-    // cache transforms here - performance gain
-    /**
-     * The to rgb transform.
-     */
-    private ICC_Transform toRGBTransform = null;
-    
-    /**
-     * The from rgb transform.
-     */
-    private ICC_Transform fromRGBTransform = null;
-    
-    /**
-     * The to xyz transform.
-     */
-    private ICC_Transform toXYZTransform = null;
-    
-    /**
-     * The from xyz transform.
-     */
-    private ICC_Transform fromXYZTransform = null;
-
-    /**
-     * The converter.
-     */
-    private final ColorConverter converter = new ColorConverter();
-    
-    /**
-     * The scaler.
-     */
-    private final ColorScaler scaler = new ColorScaler();
-    
-    /**
-     * The scaling data loaded.
-     */
-    private boolean scalingDataLoaded = false;
-
-    /**
-     * The resolved deserialized inst.
-     */
-    private ICC_ColorSpace resolvedDeserializedInst;
-
-    /**
-     * Instantiates a new ICC color space from an ICC_Profile object.
-     * 
-     * @param pf
-     *            the ICC_Profile object.
-     */
-    public ICC_ColorSpace(ICC_Profile pf) {
-        super(pf.getColorSpaceType(), pf.getNumComponents());
-
-        int pfClass = pf.getProfileClass();
-
-        switch (pfClass) {
-            case ICC_Profile.CLASS_COLORSPACECONVERSION:
-            case ICC_Profile.CLASS_DISPLAY:
-            case ICC_Profile.CLASS_OUTPUT:
-            case ICC_Profile.CLASS_INPUT:
-                break; // OK, it is color conversion profile
-            default:
-                // awt.168=Invalid profile class.
-                throw new IllegalArgumentException(Messages.getString("awt.168")); //$NON-NLS-1$
-        }
-
-        profile = pf;
-        fillMinMaxValues();
-    }
-
-    /**
-     * Gets the ICC_Profile for this ICC_ColorSpace.
-     * 
-     * @return the ICC_Profile for this ICC_ColorSpace.
-     */
-    public ICC_Profile getProfile() {
-        if (profile instanceof ICC_ProfileStub) {
-            profile = ((ICC_ProfileStub) profile).loadProfile();
-        }
-
-        return profile;
-    }
-
-    /**
-     * Performs the transformation of a color from this ColorSpace into the RGB
-     * color space.
-     * 
-     * @param colorvalue
-     *            the color value in this ColorSpace.
-     * @return the float array with color components in the RGB color space.
-     */
-    @Override
-    public float[] toRGB(float[] colorvalue) {
-        if (toRGBTransform == null) {
-            ICC_Profile sRGBProfile =
-                ((ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB)).getProfile();
-            ICC_Profile[] profiles = {getProfile(), sRGBProfile};
-            toRGBTransform = new ICC_Transform(profiles);
-            if (!scalingDataLoaded) {
-                scaler.loadScalingData(this);
-                scalingDataLoaded = true;
-            }
-        }
-
-        short[] data = new short[getNumComponents()];
-
-        scaler.scale(colorvalue, data, 0);
-
-        short[] converted =
-            converter.translateColor(toRGBTransform, data, null);
-
-        // unscale to sRGB
-        float[] res = new float[3];
-
-        res[0] = ((converted[0] & 0xFFFF)) * INV_MAX_SHORT;
-        res[1] = ((converted[1] & 0xFFFF)) * INV_MAX_SHORT;
-        res[2] = ((converted[2] & 0xFFFF)) * INV_MAX_SHORT;
-
-        return res;
-    }
-
-    /**
-     * Performs the transformation of a color from this ColorSpace into the
-     * CS_CIEXYZ color space.
-     * 
-     * @param colorvalue
-     *            the color value in this ColorSpace.
-     * @return the float array with color components in the CS_CIEXYZ color
-     *         space.
-     */
-    @Override
-    public float[] toCIEXYZ(float[] colorvalue) {
-        if (toXYZTransform == null) {
-            ICC_Profile xyzProfile =
-                ((ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ)).getProfile();
-            ICC_Profile[] profiles = {getProfile(), xyzProfile};
-            try {
-                int[] intents = {
-                        ICC_Profile.icRelativeColorimetric,
-                        ICC_Profile.icPerceptual};
-                toXYZTransform = new ICC_Transform(profiles, intents);
-            } catch (CMMException e) { // No such tag, use what we can
-                toXYZTransform = new ICC_Transform(profiles);
-            }
-
-            if (!scalingDataLoaded) {
-                scaler.loadScalingData(this);
-                scalingDataLoaded = true;
-            }
-        }
-
-        short[] data = new short[getNumComponents()];
-
-        scaler.scale(colorvalue, data, 0);
-
-        short[] converted =
-            converter.translateColor(toXYZTransform, data, null);
-
-        // unscale to XYZ
-        float[] res = new float[3];
-
-        res[0] = ((converted[0] & 0xFFFF)) * SHORT2XYZ_FACTOR;
-        res[1] = ((converted[1] & 0xFFFF)) * SHORT2XYZ_FACTOR;
-        res[2] = ((converted[2] & 0xFFFF)) * SHORT2XYZ_FACTOR;
-
-        return res;
-    }
-
-    /**
-     * Performs the transformation of a color from the RGB color space into this
-     * ColorSpace.
-     * 
-     * @param rgbvalue
-     *            the float array representing a color in the RGB color space.
-     * @return the float array with the transformed color components.
-     */
-    @Override
-    public float[] fromRGB(float[] rgbvalue) {
-        if (fromRGBTransform == null) {
-            ICC_Profile sRGBProfile =
-                ((ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB)).getProfile();
-            ICC_Profile[] profiles = {sRGBProfile, getProfile()};
-            fromRGBTransform = new ICC_Transform(profiles);
-            if (!scalingDataLoaded) {
-                scaler.loadScalingData(this);
-                scalingDataLoaded = true;
-            }
-        }
-
-        // scale rgb value to short
-        short[] scaledRGBValue = new short[3];
-        scaledRGBValue[0] = (short)(rgbvalue[0] * MAX_SHORT + 0.5f);
-        scaledRGBValue[1] = (short)(rgbvalue[1] * MAX_SHORT + 0.5f);
-        scaledRGBValue[2] = (short)(rgbvalue[2] * MAX_SHORT + 0.5f);
-
-        short[] converted =
-            converter.translateColor(fromRGBTransform, scaledRGBValue, null);
-
-        float[] res = new float[getNumComponents()];
-
-        scaler.unscale(res, converted, 0);
-
-        return res;
-    }
-
-    /**
-     * Performs the transformation of a color from the CS_CIEXYZ color space
-     * into this ColorSpace.
-     * 
-     * @param xyzvalue
-     *            the float array representing a color in the CS_CIEXYZ color
-     *            space.
-     * @return the float array with the transformed color components.
-     */
-    @Override
-    public float[] fromCIEXYZ(float[] xyzvalue) {
-        if (fromXYZTransform == null) {
-            ICC_Profile xyzProfile =
-                ((ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ)).getProfile();
-            ICC_Profile[] profiles = {xyzProfile, getProfile()};
-            try {
-                int[] intents = {
-                        ICC_Profile.icPerceptual,
-                        ICC_Profile.icRelativeColorimetric};
-                fromXYZTransform = new ICC_Transform(profiles, intents);
-            } catch (CMMException e) { // No such tag, use what we can
-                fromXYZTransform = new ICC_Transform(profiles);
-            }
-
-            if (!scalingDataLoaded) {
-                scaler.loadScalingData(this);
-                scalingDataLoaded = true;
-            }
-
-        }
-
-        // scale xyz value to short
-        short[] scaledXYZValue = new short[3];
-        scaledXYZValue[0] = (short)(xyzvalue[0] * XYZ2SHORT_FACTOR + 0.5f);
-        scaledXYZValue[1] = (short)(xyzvalue[1] * XYZ2SHORT_FACTOR + 0.5f);
-        scaledXYZValue[2] = (short)(xyzvalue[2] * XYZ2SHORT_FACTOR + 0.5f);
-
-        short[] converted =
-            converter.translateColor(fromXYZTransform, scaledXYZValue, null);
-
-        float[] res = new float[getNumComponents()];
-
-        scaler.unscale(res, converted, 0);
-
-        return res;
-    }
-
-    /**
-     * Gets the minimum normalized color component value for the specified
-     * component.
-     * 
-     * @param component
-     *            the component to determine the minimum value.
-     * @return the minimum normalized value of the component.
-     */
-    @Override
-    public float getMinValue(int component) {
-        if ((component < 0) || (component > this.getNumComponents() - 1)) {
-            // awt.169=Component index out of range
-            throw new IllegalArgumentException(Messages.getString("awt.169")); //$NON-NLS-1$
-        }
-
-        return minValues[component];
-    }
-
-    /**
-     * Gets the maximum normalized color component value for the specified
-     * component.
-     * 
-     * @param component
-     *            the component to determine the maximum value.
-     * @return the maximum normalized value of the component.
-     */
-    @Override
-    public float getMaxValue(int component) {
-        if ((component < 0) || (component > this.getNumComponents() - 1)) {
-            // awt.169=Component index out of range
-            throw new IllegalArgumentException(Messages.getString("awt.169")); //$NON-NLS-1$
-        }
-
-        return maxValues[component];
-    }
-
-    /**
-     * Fill min max values.
-     */
-    private void fillMinMaxValues() {
-        int n = getNumComponents();
-        maxValues = new float[n];
-        minValues = new float[n];
-        switch (getType()) {
-            case ColorSpace.TYPE_XYZ:
-                minValues[0] = 0;
-                minValues[1] = 0;
-                minValues[2] = 0;
-                maxValues[0] = MAX_XYZ;
-                maxValues[1] = MAX_XYZ;
-                maxValues[2] = MAX_XYZ;
-                break;
-            case ColorSpace.TYPE_Lab:
-                minValues[0] = 0;
-                minValues[1] = -128;
-                minValues[2] = -128;
-                maxValues[0] = 100;
-                maxValues[1] = 127;
-                maxValues[2] = 127;
-                break;
-            default:
-                for(int i=0; i<n; i++) {
-                    minValues[i] = 0;
-                    maxValues[i] = 1;
-                }
-        }
-    }
-
-    /**
-     * Write object.
-     * 
-     * @param out
-     *            the out
-     * @throws IOException
-     *             Signals that an I/O exception has occurred.
-     */
-    private void writeObject(ObjectOutputStream out) throws IOException {
-        ObjectOutputStream.PutField fields = out.putFields();
-
-        fields.put("thisProfile", profile); //$NON-NLS-1$
-        fields.put("minVal", null); //$NON-NLS-1$
-        fields.put("maxVal", null); //$NON-NLS-1$
-        fields.put("diffMinMax", null); //$NON-NLS-1$
-        fields.put("invDiffMinMax", null); //$NON-NLS-1$
-        fields.put("needScaleInit", true); //$NON-NLS-1$
-
-        out.writeFields();
-    }
-
-    /**
-     * Read object.
-     * 
-     * @param in
-     *            the in
-     * @throws IOException
-     *             Signals that an I/O exception has occurred.
-     * @throws ClassNotFoundException
-     *             the class not found exception
-     */
-    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-        ObjectInputStream.GetField fields = in.readFields();
-        resolvedDeserializedInst =
-                new ICC_ColorSpace((ICC_Profile) fields.get("thisProfile", null)); //$NON-NLS-1$
-    }
-
-    /**
-     * Read resolve.
-     * 
-     * @return the object
-     * @throws ObjectStreamException
-     *             the object stream exception
-     */
-    Object readResolve() throws ObjectStreamException {
-        return resolvedDeserializedInst;
-    }
-}
-
diff --git a/awt/java/awt/color/ICC_Profile.java b/awt/java/awt/color/ICC_Profile.java
deleted file mode 100644
index 8ffee6c..0000000
--- a/awt/java/awt/color/ICC_Profile.java
+++ /dev/null
@@ -1,1477 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package java.awt.color;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamException;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.StringTokenizer;
-
-import org.apache.harmony.awt.gl.color.ICC_ProfileHelper;
-import org.apache.harmony.awt.gl.color.NativeCMM;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The ICC_Profile class represents a color profile data for color spaces based
- * on the International Color Consortium Specification ICC.1:2001-12, File
- * Format for Color Profiles.
- * 
- * @since Android 1.0
- */
-public class ICC_Profile implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -3938515861990936766L;
-
-    // NOTE: Constant field values are noted in 1.5 specification.
-
-    /**
-     * The Constant CLASS_INPUT indicates that profile class is input.
-     */
-    public static final int CLASS_INPUT = 0;
-
-    /**
-     * The Constant CLASS_DISPLAY indicates that profile class is display.
-     */
-    public static final int CLASS_DISPLAY = 1;
-
-    /**
-     * The Constant CLASS_OUTPUT indicates that profile class is output.
-     */
-    public static final int CLASS_OUTPUT = 2;
-
-    /**
-     * The Constant CLASS_DEVICELINK indicates that profile class is device
-     * link.
-     */
-    public static final int CLASS_DEVICELINK = 3;
-
-    /**
-     * The Constant CLASS_COLORSPACECONVERSION indicates that profile class is
-     * color space conversion.
-     */
-    public static final int CLASS_COLORSPACECONVERSION = 4;
-
-    /**
-     * The Constant CLASS_ABSTRACT indicates that profile class is abstract.
-     */
-    public static final int CLASS_ABSTRACT = 5;
-
-    /**
-     * The Constant CLASS_NAMEDCOLOR indicates that profile class is named
-     * color.
-     */
-    public static final int CLASS_NAMEDCOLOR = 6;
-
-    /**
-     * The Constant icSigXYZData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigXYZData = 1482250784;
-
-    /**
-     * The Constant icSigLabData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigLabData = 1281450528;
-
-    /**
-     * The Constant icSigLuvData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigLuvData = 1282766368;
-
-    /**
-     * The Constant icSigYCbCrData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigYCbCrData = 1497588338;
-
-    /**
-     * The Constant icSigYxyData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigYxyData = 1501067552;
-
-    /**
-     * The Constant icSigRgbData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigRgbData = 1380401696;
-
-    /**
-     * The Constant icSigGrayData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigGrayData = 1196573017;
-
-    /**
-     * The Constant icSigHsvData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigHsvData = 1213421088;
-
-    /**
-     * The Constant icSigHlsData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigHlsData = 1212961568;
-
-    /**
-     * The Constant icSigCmykData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigCmykData = 1129142603;
-
-    /**
-     * The Constant icSigCmyData - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigCmyData = 1129142560;
-
-    /**
-     * The Constant icSigSpace2CLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpace2CLR = 843271250;
-
-    /**
-     * The Constant icSigSpace3CLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpace3CLR = 860048466;
-
-    /**
-     * The Constant icSigSpace4CLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpace4CLR = 876825682;
-
-    /**
-     * The Constant icSigSpace5CLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpace5CLR = 893602898;
-
-    /**
-     * The Constant icSigSpace6CLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpace6CLR = 910380114;
-
-    /**
-     * The Constant icSigSpace7CLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpace7CLR = 927157330;
-
-    /**
-     * The Constant icSigSpace8CLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpace8CLR = 943934546;
-
-    /**
-     * The Constant icSigSpace9CLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpace9CLR = 960711762;
-
-    /**
-     * The Constant icSigSpaceACLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpaceACLR = 1094929490;
-
-    /**
-     * The Constant icSigSpaceBCLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpaceBCLR = 1111706706;
-
-    /**
-     * The Constant icSigSpaceCCLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpaceCCLR = 1128483922;
-
-    /**
-     * The Constant icSigSpaceDCLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpaceDCLR = 1145261138;
-
-    /**
-     * The Constant icSigSpaceECLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpaceECLR = 1162038354;
-
-    /**
-     * The Constant icSigSpaceFCLR - ICC Profile Color Space Type Signature.
-     */
-    public static final int icSigSpaceFCLR = 1178815570;
-
-    /**
-     * The Constant icSigInputClass - ICC Profile Class Signature.
-     */
-    public static final int icSigInputClass = 1935896178;
-
-    /**
-     * The Constant icSigDisplayClass - ICC Profile Class Signature.
-     */
-    public static final int icSigDisplayClass = 1835955314;
-
-    /**
-     * The Constant icSigOutputClass - ICC Profile Class Signature.
-     */
-    public static final int icSigOutputClass = 1886549106;
-
-    /**
-     * The Constant icSigLinkClass - ICC Profile Class Signature.
-     */
-    public static final int icSigLinkClass = 1818848875;
-
-    /**
-     * The Constant icSigAbstractClass - ICC Profile Class Signature.
-     */
-    public static final int icSigAbstractClass = 1633842036;
-
-    /**
-     * The Constant icSigColorantOrderTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigColorantOrderTag = 1668051567;
-
-    /**
-     * The Constant icSigColorantTableTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigColorantTableTag = 1668051572;
-
-    /**
-     * The Constant icSigColorSpaceClass - ICC Profile Tag Signature.
-     */
-    public static final int icSigColorSpaceClass = 1936744803;
-
-    /**
-     * The Constant icSigNamedColorClass - ICC Profile Tag Signature.
-     */
-    public static final int icSigNamedColorClass = 1852662636;
-
-    /**
-     * The Constant icPerceptual - ICC Profile Rendering Intent.
-     */
-    public static final int icPerceptual = 0;
-
-    /**
-     * The Constant icRelativeColorimetric - ICC Profile Rendering Intent.
-     */
-    public static final int icRelativeColorimetric = 1;
-
-    /**
-     * The Constant icSaturation - ICC Profile Rendering Intent.
-     */
-    public static final int icSaturation = 2;
-
-    /**
-     * The Constant icAbsoluteColorimetric - ICC Profile Rendering Intent.
-     */
-    public static final int icAbsoluteColorimetric = 3;
-
-    /**
-     * The Constant icSigHead - ICC Profile Tag Signature.
-     */
-    public static final int icSigHead = 1751474532;
-
-    /**
-     * The Constant icSigAToB0Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigAToB0Tag = 1093812784;
-
-    /**
-     * The Constant icSigAToB1Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigAToB1Tag = 1093812785;
-
-    /**
-     * The Constant icSigAToB2Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigAToB2Tag = 1093812786;
-
-    /**
-     * The Constant icSigBlueColorantTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigBlueColorantTag = 1649957210;
-
-    /**
-     * The Constant icSigBlueMatrixColumnTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigBlueMatrixColumnTag = 1649957210;
-
-    /**
-     * The Constant icSigBlueTRCTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigBlueTRCTag = 1649693251;
-
-    /**
-     * The Constant icSigBToA0Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigBToA0Tag = 1110589744;
-
-    /**
-     * The Constant icSigBToA1Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigBToA1Tag = 1110589745;
-
-    /**
-     * The Constant icSigBToA2Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigBToA2Tag = 1110589746;
-
-    /**
-     * The Constant icSigCalibrationDateTimeTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigCalibrationDateTimeTag = 1667329140;
-
-    /**
-     * The Constant icSigCharTargetTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigCharTargetTag = 1952543335;
-
-    /**
-     * The Constant icSigCopyrightTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigCopyrightTag = 1668313716;
-
-    /**
-     * The Constant icSigCrdInfoTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigCrdInfoTag = 1668441193;
-
-    /**
-     * The Constant icSigDeviceMfgDescTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigDeviceMfgDescTag = 1684893284;
-
-    /**
-     * The Constant icSigDeviceModelDescTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigDeviceModelDescTag = 1684890724;
-
-    /**
-     * The Constant icSigDeviceSettingsTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigDeviceSettingsTag = 1684371059;
-
-    /**
-     * The Constant icSigGamutTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigGamutTag = 1734438260;
-
-    /**
-     * The Constant icSigGrayTRCTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigGrayTRCTag = 1800688195;
-
-    /**
-     * The Constant icSigGreenColorantTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigGreenColorantTag = 1733843290;
-
-    /**
-     * The Constant icSigGreenMatrixColumnTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigGreenMatrixColumnTag = 1733843290;
-
-    /**
-     * The Constant icSigGreenTRCTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigGreenTRCTag = 1733579331;
-
-    /**
-     * The Constant icSigLuminanceTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigLuminanceTag = 1819635049;
-
-    /**
-     * The Constant icSigMeasurementTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigMeasurementTag = 1835360627;
-
-    /**
-     * The Constant icSigMediaBlackPointTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigMediaBlackPointTag = 1651208308;
-
-    /**
-     * The Constant icSigMediaWhitePointTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigMediaWhitePointTag = 2004119668;
-
-    /**
-     * The Constant icSigNamedColor2Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigNamedColor2Tag = 1852009522;
-
-    /**
-     * The Constant icSigOutputResponseTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigOutputResponseTag = 1919251312;
-
-    /**
-     * The Constant icSigPreview0Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigPreview0Tag = 1886545200;
-
-    /**
-     * The Constant icSigPreview1Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigPreview1Tag = 1886545201;
-
-    /**
-     * The Constant icSigPreview2Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigPreview2Tag = 1886545202;
-
-    /**
-     * The Constant icSigProfileDescriptionTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigProfileDescriptionTag = 1684370275;
-
-    /**
-     * The Constant icSigProfileSequenceDescTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigProfileSequenceDescTag = 1886610801;
-
-    /**
-     * The Constant icSigPs2CRD0Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigPs2CRD0Tag = 1886610480;
-
-    /**
-     * The Constant icSigPs2CRD1Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigPs2CRD1Tag = 1886610481;
-
-    /**
-     * The Constant icSigPs2CRD2Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigPs2CRD2Tag = 1886610482;
-
-    /**
-     * The Constant icSigPs2CRD3Tag - ICC Profile Tag Signature.
-     */
-    public static final int icSigPs2CRD3Tag = 1886610483;
-
-    /**
-     * The Constant icSigPs2CSATag - ICC Profile Tag Signature.
-     */
-    public static final int icSigPs2CSATag = 1886597747;
-
-    /**
-     * The Constant icSigPs2RenderingIntentTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigPs2RenderingIntentTag = 1886597737;
-
-    /**
-     * The Constant icSigRedColorantTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigRedColorantTag = 1918392666;
-
-    /**
-     * The Constant icSigRedMatrixColumnTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigRedMatrixColumnTag = 1918392666;
-
-    /**
-     * The Constant icSigRedTRCTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigRedTRCTag = 1918128707;
-
-    /**
-     * The Constant icSigScreeningDescTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigScreeningDescTag = 1935897188;
-
-    /**
-     * The Constant icSigScreeningTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigScreeningTag = 1935897198;
-
-    /**
-     * The Constant icSigTechnologyTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigTechnologyTag = 1952801640;
-
-    /**
-     * The Constant icSigUcrBgTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigUcrBgTag = 1650877472;
-
-    /**
-     * The Constant icSigViewingCondDescTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigViewingCondDescTag = 1987405156;
-
-    /**
-     * The Constant icSigViewingConditionsTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigViewingConditionsTag = 1986618743;
-
-    /**
-     * The Constant icSigChromaticAdaptationTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigChromaticAdaptationTag = 1667785060;
-
-    /**
-     * The Constant icSigChromaticityTag - ICC Profile Tag Signature.
-     */
-    public static final int icSigChromaticityTag = 1667789421;
-
-    /**
-     * The Constant icHdrSize - ICC Profile Header Location.
-     */
-    public static final int icHdrSize = 0;
-
-    /**
-     * The Constant icHdrCmmId - ICC Profile Header Location.
-     */
-    public static final int icHdrCmmId = 4;
-
-    /**
-     * The Constant icHdrVersion - ICC Profile Header Location.
-     */
-    public static final int icHdrVersion = 8;
-
-    /**
-     * The Constant icHdrDeviceClass - ICC Profile Header Location.
-     */
-    public static final int icHdrDeviceClass = 12;
-
-    /**
-     * The Constant icHdrColorSpace - ICC Profile Header Location.
-     */
-    public static final int icHdrColorSpace = 16;
-
-    /**
-     * The Constant icHdrPcs - ICC Profile Header Location.
-     */
-    public static final int icHdrPcs = 20;
-
-    /**
-     * The Constant icHdrDate - ICC Profile Header Location.
-     */
-    public static final int icHdrDate = 24;
-
-    /**
-     * The Constant icHdrMagic - ICC Profile Header Location.
-     */
-    public static final int icHdrMagic = 36;
-
-    /**
-     * The Constant icHdrPlatform - ICC Profile Header Location.
-     */
-    public static final int icHdrPlatform = 40;
-
-    /**
-     * The Constant icHdrProfileID - ICC Profile Header Location.
-     */
-    public static final int icHdrProfileID = 84;
-
-    /**
-     * The Constant icHdrFlags - ICC Profile Header Location.
-     */
-    public static final int icHdrFlags = 44;
-
-    /**
-     * The Constant icHdrManufacturer - ICC Profile Header Location.
-     */
-    public static final int icHdrManufacturer = 48;
-
-    /**
-     * The Constant icHdrModel - ICC Profile Header Location.
-     */
-    public static final int icHdrModel = 52;
-
-    /**
-     * The Constant icHdrAttributes - ICC Profile Header Location.
-     */
-    public static final int icHdrAttributes = 56;
-
-    /**
-     * The Constant icHdrRenderingIntent - ICC Profile Header Location.
-     */
-    public static final int icHdrRenderingIntent = 64;
-
-    /**
-     * The Constant icHdrIlluminant - ICC Profile Header Location.
-     */
-    public static final int icHdrIlluminant = 68;
-
-    /**
-     * The Constant icHdrCreator - ICC Profile Header Location.
-     */
-    public static final int icHdrCreator = 80;
-
-    /**
-     * The Constant icICCAbsoluteColorimetric - ICC Profile Rendering Intent.
-     */
-    public static final int icICCAbsoluteColorimetric = 3;
-
-    /**
-     * The Constant icMediaRelativeColorimetric - ICC Profile Rendering Intent.
-     */
-    public static final int icMediaRelativeColorimetric = 1;
-
-    /**
-     * The Constant icTagType - ICC Profile Constant.
-     */
-    public static final int icTagType = 0;
-
-    /**
-     * The Constant icTagReserved - ICC Profile Constant.
-     */
-    public static final int icTagReserved = 4;
-
-    /**
-     * The Constant icCurveCount - ICC Profile Constant.
-     */
-    public static final int icCurveCount = 8;
-
-    /**
-     * The Constant icCurveData - ICC Profile Constant.
-     */
-    public static final int icCurveData = 12;
-
-    /**
-     * The Constant icXYZNumberX - ICC Profile Constant.
-     */
-    public static final int icXYZNumberX = 8;
-
-    /**
-     * Size of a profile header.
-     */
-    private static final int headerSize = 128;
-
-    /**
-     * header magic number.
-     */
-    private static final int headerMagicNumber = 0x61637370;
-
-    // Cache of predefined profiles
-    /**
-     * The s rgb profile.
-     */
-    private static ICC_Profile sRGBProfile;
-
-    /**
-     * The xyz profile.
-     */
-    private static ICC_Profile xyzProfile;
-
-    /**
-     * The gray profile.
-     */
-    private static ICC_Profile grayProfile;
-
-    /**
-     * The pycc profile.
-     */
-    private static ICC_Profile pyccProfile;
-
-    /**
-     * The linear rgb profile.
-     */
-    private static ICC_Profile linearRGBProfile;
-
-    /**
-     * Handle to the current profile.
-     */
-    private transient long profileHandle = 0;
-
-    /**
-     * If handle is used by another class this object is not responsible for
-     * closing profile.
-     */
-    private transient boolean handleStolen = false;
-
-    /**
-     * Cached header data.
-     */
-    private transient byte[] headerData = null;
-
-    /**
-     * Serialization support.
-     */
-    private transient ICC_Profile openedProfileObject;
-
-    /**
-     * Instantiates a new ICC profile with the given data.
-     * 
-     * @param data
-     *            the data.
-     */
-    private ICC_Profile(byte[] data) {
-        profileHandle = NativeCMM.cmmOpenProfile(data);
-        NativeCMM.addHandle(this, profileHandle);
-    }
-
-    /**
-     * Used to instantiate dummy ICC_ProfileStub objects.
-     */
-    ICC_Profile() {
-    }
-
-    /**
-     * Used to instantiate subclasses (ICC_ProfileGrey and ICC_ProfileRGB).
-     * 
-     * @param profileHandle
-     *            - should be valid handle to opened color profile
-     */
-    ICC_Profile(long profileHandle) {
-        this.profileHandle = profileHandle;
-        // A new object reference, need to add it.
-        NativeCMM.addHandle(this, profileHandle);
-    }
-
-    /**
-     * Writes the ICC_Profile to a file with the specified name.
-     * 
-     * @param fileName
-     *            the file name.
-     * @throws IOException
-     *             if an I/O exception has occurred during writing or opening
-     *             the file.
-     */
-    public void write(String fileName) throws IOException {
-        FileOutputStream oStream = new FileOutputStream(fileName);
-        oStream.write(getData());
-        oStream.close();
-    }
-
-    /**
-     * Serializable implementation.
-     * 
-     * @param s
-     *            the s
-     * @throws IOException
-     *             Signals that an I/O exception has occurred.
-     */
-    private void writeObject(ObjectOutputStream s) throws IOException {
-        s.defaultWriteObject();
-        s.writeObject(null);
-        s.writeObject(getData());
-    }
-
-    /**
-     * Serializable implementation.
-     * 
-     * @param s
-     *            the s
-     * @throws IOException
-     *             Signals that an I/O exception has occurred.
-     * @throws ClassNotFoundException
-     *             the class not found exception
-     */
-    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
-        String colorSpaceStr = (String)s.readObject();
-        byte[] data = (byte[])s.readObject();
-
-        if (colorSpaceStr != null) {
-            if (colorSpaceStr.equals("CS_sRGB")) { //$NON-NLS-1$
-                openedProfileObject = getInstance(ColorSpace.CS_sRGB);
-            } else if (colorSpaceStr.equals("CS_GRAY")) { //$NON-NLS-1$
-                openedProfileObject = getInstance(ColorSpace.CS_GRAY);
-            } else if (colorSpaceStr.equals("CS_LINEAR_RGB")) { //$NON-NLS-1$
-                openedProfileObject = getInstance(ColorSpace.CS_LINEAR_RGB);
-            } else if (colorSpaceStr.equals("CS_CIEXYZ")) { //$NON-NLS-1$
-                openedProfileObject = getInstance(ColorSpace.CS_CIEXYZ);
-            } else if (colorSpaceStr.equals("CS_PYCC")) { //$NON-NLS-1$
-                openedProfileObject = getInstance(ColorSpace.CS_PYCC);
-            } else {
-                openedProfileObject = ICC_Profile.getInstance(data);
-            }
-        } else {
-            openedProfileObject = ICC_Profile.getInstance(data);
-        }
-    }
-
-    /**
-     * Resolves instances being deserialized into instances registered with CMM.
-     * 
-     * @return ICC_Profile object for profile registered with CMM.
-     * @throws ObjectStreamException
-     *             if there is an error in the serialized files or during the
-     *             process of reading them.
-     */
-    protected Object readResolve() throws ObjectStreamException {
-        return openedProfileObject;
-    }
-
-    /**
-     * Writes the ICC_Profile to an OutputStream.
-     * 
-     * @param s
-     *            the OutputStream.
-     * @throws IOException
-     *             signals that an I/O exception has occurred during writing or
-     *             opening OutputStream.
-     */
-    public void write(OutputStream s) throws IOException {
-        s.write(getData());
-    }
-
-    /**
-     * Sets a tagged data element in the profile from a byte array.
-     * 
-     * @param tagSignature
-     *            the ICC tag signature for the data element to be set.
-     * @param tagData
-     *            the data to be set for the specified tag signature.
-     */
-    public void setData(int tagSignature, byte[] tagData) {
-        NativeCMM.cmmSetProfileElement(profileHandle, tagSignature, tagData);
-        // Remove cached header data if header is modified
-        if (tagSignature == icSigHead) {
-            headerData = null;
-        }
-    }
-
-    /**
-     * Gets a tagged data element from the profile as a byte array. Elements are
-     * identified by tag signatures as defined in the ICC specification.
-     * 
-     * @param tagSignature
-     *            the ICC tag signature for the data element to get.
-     * @return a byte array that contains the tagged data element.
-     */
-    public byte[] getData(int tagSignature) {
-        int tagSize = 0;
-        try {
-            tagSize = NativeCMM.cmmGetProfileElementSize(profileHandle, tagSignature);
-        } catch (CMMException e) {
-            // We'll get this exception if there's no element with
-            // the specified tag signature
-            return null;
-        }
-
-        byte[] data = new byte[tagSize];
-        NativeCMM.cmmGetProfileElement(profileHandle, tagSignature, data);
-        return data;
-    }
-
-    /**
-     * Gets a data byte array of this ICC_Profile.
-     * 
-     * @return a byte array that contains the ICC Profile data.
-     */
-    public byte[] getData() {
-        int profileSize = NativeCMM.cmmGetProfileSize(profileHandle);
-        byte[] data = new byte[profileSize];
-        NativeCMM.cmmGetProfile(profileHandle, data);
-        return data;
-    }
-
-    /**
-     * Frees the resources associated with an ICC_Profile object.
-     */
-    @Override
-    protected void finalize() {
-        if (profileHandle != 0 && !handleStolen) {
-            NativeCMM.cmmCloseProfile(profileHandle);
-        }
-
-        // Always remove because key no more exist
-        // when object is destroyed
-        NativeCMM.removeHandle(this);
-    }
-
-    /**
-     * Gets the profile class.
-     * 
-     * @return the profile class constant.
-     */
-    public int getProfileClass() {
-        int deviceClassSignature = getIntFromHeader(icHdrDeviceClass);
-
-        switch (deviceClassSignature) {
-            case icSigColorSpaceClass:
-                return CLASS_COLORSPACECONVERSION;
-            case icSigDisplayClass:
-                return CLASS_DISPLAY;
-            case icSigOutputClass:
-                return CLASS_OUTPUT;
-            case icSigInputClass:
-                return CLASS_INPUT;
-            case icSigLinkClass:
-                return CLASS_DEVICELINK;
-            case icSigAbstractClass:
-                return CLASS_ABSTRACT;
-            case icSigNamedColorClass:
-                return CLASS_NAMEDCOLOR;
-            default:
-        }
-
-        // Not an ICC profile class
-        // awt.15F=Profile class does not comply with ICC specification
-        throw new IllegalArgumentException(Messages.getString("awt.15F")); //$NON-NLS-1$
-
-    }
-
-    /**
-     * Gets the color space type of the Profile Connection Space (PCS).
-     * 
-     * @return the PCS type.
-     */
-    public int getPCSType() {
-        return csFromSignature(getIntFromHeader(icHdrPcs));
-    }
-
-    /**
-     * Gets the number of components of this ICC Profile.
-     * 
-     * @return the number of components of this ICC Profile.
-     */
-    public int getNumComponents() {
-        switch (getIntFromHeader(icHdrColorSpace)) {
-            // The most common cases go first to increase speed
-            case icSigRgbData:
-            case icSigXYZData:
-            case icSigLabData:
-                return 3;
-            case icSigCmykData:
-                return 4;
-                // Then all other
-            case icSigGrayData:
-                return 1;
-            case icSigSpace2CLR:
-                return 2;
-            case icSigYCbCrData:
-            case icSigLuvData:
-            case icSigYxyData:
-            case icSigHlsData:
-            case icSigHsvData:
-            case icSigCmyData:
-            case icSigSpace3CLR:
-                return 3;
-            case icSigSpace4CLR:
-                return 4;
-            case icSigSpace5CLR:
-                return 5;
-            case icSigSpace6CLR:
-                return 6;
-            case icSigSpace7CLR:
-                return 7;
-            case icSigSpace8CLR:
-                return 8;
-            case icSigSpace9CLR:
-                return 9;
-            case icSigSpaceACLR:
-                return 10;
-            case icSigSpaceBCLR:
-                return 11;
-            case icSigSpaceCCLR:
-                return 12;
-            case icSigSpaceDCLR:
-                return 13;
-            case icSigSpaceECLR:
-                return 14;
-            case icSigSpaceFCLR:
-                return 15;
-            default:
-        }
-
-        // awt.160=Color space doesn't comply with ICC specification
-        throw new ProfileDataException(Messages.getString("awt.160") //$NON-NLS-1$
-        );
-    }
-
-    /**
-     * Gets the minor version of this ICC profile.
-     * 
-     * @return the minor version of this ICC profile.
-     */
-    public int getMinorVersion() {
-        return getByteFromHeader(icHdrVersion + 1);
-    }
-
-    /**
-     * Gets the major version of this ICC profile.
-     * 
-     * @return the major version of this ICC profile.
-     */
-    public int getMajorVersion() {
-        return getByteFromHeader(icHdrVersion);
-    }
-
-    /**
-     * Gets the color space type of this ICC_Profile.
-     * 
-     * @return the color space type.
-     */
-    public int getColorSpaceType() {
-        return csFromSignature(getIntFromHeader(icHdrColorSpace));
-    }
-
-    /**
-     * Tries to open the file at the specified path. Path entries can be divided
-     * by a separator character.
-     * 
-     * @param path
-     *            the path to the file.
-     * @param fileName
-     *            the file name.
-     * @return the input stream to read the file.
-     */
-    private static FileInputStream tryPath(String path, String fileName) {
-        FileInputStream fiStream = null;
-
-        if (path == null) {
-            return null;
-        }
-
-        StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
-
-        while (st.hasMoreTokens()) {
-            String pathEntry = st.nextToken();
-            try {
-                fiStream = new FileInputStream(pathEntry + File.separatorChar + fileName);
-                if (fiStream != null) {
-                    return fiStream;
-                }
-            } catch (FileNotFoundException e) {
-            }
-        }
-
-        return fiStream;
-    }
-
-    /**
-     * Gets the single instance of ICC_Profile from data in the specified file.
-     * 
-     * @param fileName
-     *            the specified name of file with ICC profile data.
-     * @return single instance of ICC_Profile.
-     * @throws IOException
-     *             signals that an I/O error occurred while reading the file or
-     *             the file does not exist.
-     */
-    public static ICC_Profile getInstance(String fileName) throws IOException {
-        final String fName = fileName; // to use in the privileged block
-
-        FileInputStream fiStream = (FileInputStream)AccessController
-                .doPrivileged(new PrivilegedAction<FileInputStream>() {
-                    public FileInputStream run() {
-                        FileInputStream fiStream = null;
-
-                        // Open absolute path
-                        try {
-                            fiStream = new FileInputStream(fName);
-                            if (fiStream != null) {
-                                return fiStream;
-                            }
-                        } catch (FileNotFoundException e) {
-                        }
-
-                        // Check java.iccprofile.path entries
-                        fiStream = tryPath(System.getProperty("java.iccprofile.path"), fName); //$NON-NLS-1$
-                        if (fiStream != null) {
-                            return fiStream;
-                        }
-
-                        // Check java.class.path entries
-                        fiStream = tryPath(System.getProperty("java.class.path"), fName); //$NON-NLS-1$
-                        if (fiStream != null) {
-                            return fiStream;
-                        }
-
-                        // Check directory with java sample profiles
-                        String home = System.getProperty("java.home"); //$NON-NLS-1$
-                        if (home != null) {
-                            fiStream = tryPath(home + File.separatorChar
-                                    + "lib" + File.separatorChar + "cmm", fName //$NON-NLS-1$ //$NON-NLS-2$
-                            );
-                        }
-
-                        return fiStream;
-                    }
-                });
-
-        if (fiStream == null) {
-            // awt.161=Unable to open file {0}
-            throw new IOException(Messages.getString("awt.161", fileName)); //$NON-NLS-1$
-        }
-
-        ICC_Profile pf = getInstance(fiStream);
-        fiStream.close();
-        return pf;
-    }
-
-    /**
-     * Gets the single instance of ICC_Profile with data in the specified
-     * InputStream.
-     * 
-     * @param s
-     *            the InputStream with ICC profile data.
-     * @return single instance of ICC_Profile.
-     * @throws IOException
-     *             if an I/O exception has occurred during reading from
-     *             InputStream.
-     * @throws IllegalArgumentException
-     *             if the file does not contain valid ICC Profile data.
-     */
-    public static ICC_Profile getInstance(InputStream s) throws IOException {
-        byte[] header = new byte[headerSize];
-        // awt.162=Invalid ICC Profile Data
-        String invalidDataMessage = Messages.getString("awt.162"); //$NON-NLS-1$
-
-        // Get header from the input stream
-        if (s.read(header) != headerSize) {
-            throw new IllegalArgumentException(invalidDataMessage);
-        }
-
-        // Check the profile data for consistency
-        if (ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrMagic) != headerMagicNumber) {
-            throw new IllegalArgumentException(invalidDataMessage);
-        }
-
-        // Get profile size from header, create an array for profile data
-        int profileSize = ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrSize);
-        byte[] profileData = new byte[profileSize];
-
-        // Copy header into it
-        System.arraycopy(header, 0, profileData, 0, headerSize);
-
-        // Read the profile itself
-        if (s.read(profileData, headerSize, profileSize - headerSize) != profileSize - headerSize) {
-            throw new IllegalArgumentException(invalidDataMessage);
-        }
-
-        return getInstance(profileData);
-    }
-
-    /**
-     * Gets the single instance of ICC_Profile from the specified data in a byte
-     * array.
-     * 
-     * @param data
-     *            the byte array of ICC profile.
-     * @return single instance of ICC_Profile from the specified data in a byte
-     *         array.
-     * @throws IllegalArgumentException
-     *             if the file does not contain valid ICC Profile data.
-     */
-    public static ICC_Profile getInstance(byte[] data) {
-        ICC_Profile res = null;
-
-        try {
-            res = new ICC_Profile(data);
-        } catch (CMMException e) {
-            // awt.162=Invalid ICC Profile Data
-            throw new IllegalArgumentException(Messages.getString("awt.162")); //$NON-NLS-1$
-        }
-
-        if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) { //$NON-NLS-1$ //$NON-NLS-2$
-            try {
-                if (res.getColorSpaceType() == ColorSpace.TYPE_RGB
-                        && res.getDataSize(icSigMediaWhitePointTag) > 0
-                        && res.getDataSize(icSigRedColorantTag) > 0
-                        && res.getDataSize(icSigGreenColorantTag) > 0
-                        && res.getDataSize(icSigBlueColorantTag) > 0
-                        && res.getDataSize(icSigRedTRCTag) > 0
-                        && res.getDataSize(icSigGreenTRCTag) > 0
-                        && res.getDataSize(icSigBlueTRCTag) > 0) {
-                    res = new ICC_ProfileRGB(res.getProfileHandle());
-                } else if (res.getColorSpaceType() == ColorSpace.TYPE_GRAY
-                        && res.getDataSize(icSigMediaWhitePointTag) > 0
-                        && res.getDataSize(icSigGrayTRCTag) > 0) {
-                    res = new ICC_ProfileGray(res.getProfileHandle());
-                }
-
-            } catch (CMMException e) { /* return res in this case */
-            }
-        }
-
-        return res;
-    }
-
-    /**
-     * Gets the single instance of ICC_Profile with the specific color space
-     * defined by the ColorSpace class: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ,
-     * CS_PYCC, CS_GRAY.
-     * 
-     * @param cspace
-     *            the type of color space defined in the ColorSpace class.
-     * @return single instance of ICC_Profile.
-     * @throws IllegalArgumentException
-     *             is not one of the defined color space types.
-     */
-    public static ICC_Profile getInstance(int cspace) {
-        try {
-            switch (cspace) {
-
-                case ColorSpace.CS_sRGB:
-                    if (sRGBProfile == null) {
-                        sRGBProfile = getInstance("sRGB.pf"); //$NON-NLS-1$
-                    }
-                    return sRGBProfile;
-
-                case ColorSpace.CS_CIEXYZ:
-                    if (xyzProfile == null) {
-                        xyzProfile = getInstance("CIEXYZ.pf"); //$NON-NLS-1$
-                    }
-                    return xyzProfile;
-
-                case ColorSpace.CS_GRAY:
-                    if (grayProfile == null) {
-                        grayProfile = getInstance("GRAY.pf"); //$NON-NLS-1$
-                    }
-                    return grayProfile;
-
-                case ColorSpace.CS_PYCC:
-                    if (pyccProfile == null) {
-                        pyccProfile = getInstance("PYCC.pf"); //$NON-NLS-1$
-                    }
-                    return pyccProfile;
-
-                case ColorSpace.CS_LINEAR_RGB:
-                    if (linearRGBProfile == null) {
-                        linearRGBProfile = getInstance("LINEAR_RGB.pf"); //$NON-NLS-1$
-                    }
-                    return linearRGBProfile;
-            }
-
-        } catch (IOException e) {
-            // awt.163=Can't open color profile
-            throw new IllegalArgumentException(Messages.getString("Can't open color profile")); //$NON-NLS-1$
-        }
-
-        // awt.164=Not a predefined color space
-        throw new IllegalArgumentException(Messages.getString("Not a predefined color space")); //$NON-NLS-1$
-    }
-
-    /**
-     * Reads an integer from the profile header at the specified position.
-     * 
-     * @param idx
-     *            - offset in bytes from the beginning of the header
-     * @return the integer value from header
-     */
-    private int getIntFromHeader(int idx) {
-        if (headerData == null) {
-            headerData = getData(icSigHead);
-        }
-
-        return ((headerData[idx] & 0xFF) << 24) | ((headerData[idx + 1] & 0xFF) << 16)
-                | ((headerData[idx + 2] & 0xFF) << 8) | ((headerData[idx + 3] & 0xFF));
-    }
-
-    /**
-     * Reads byte from the profile header at the specified position.
-     * 
-     * @param idx
-     *            - offset in bytes from the beginning of the header
-     * @return the byte from header
-     */
-    private byte getByteFromHeader(int idx) {
-        if (headerData == null) {
-            headerData = getData(icSigHead);
-        }
-
-        return headerData[idx];
-    }
-
-    /**
-     * Converts ICC color space signature to the java predefined color space
-     * type.
-     * 
-     * @param signature
-     *            the signature
-     * @return the int
-     */
-    private int csFromSignature(int signature) {
-        switch (signature) {
-            case icSigRgbData:
-                return ColorSpace.TYPE_RGB;
-            case icSigXYZData:
-                return ColorSpace.TYPE_XYZ;
-            case icSigCmykData:
-                return ColorSpace.TYPE_CMYK;
-            case icSigLabData:
-                return ColorSpace.TYPE_Lab;
-            case icSigGrayData:
-                return ColorSpace.TYPE_GRAY;
-            case icSigHlsData:
-                return ColorSpace.TYPE_HLS;
-            case icSigLuvData:
-                return ColorSpace.TYPE_Luv;
-            case icSigYCbCrData:
-                return ColorSpace.TYPE_YCbCr;
-            case icSigYxyData:
-                return ColorSpace.TYPE_Yxy;
-            case icSigHsvData:
-                return ColorSpace.TYPE_HSV;
-            case icSigCmyData:
-                return ColorSpace.TYPE_CMY;
-            case icSigSpace2CLR:
-                return ColorSpace.TYPE_2CLR;
-            case icSigSpace3CLR:
-                return ColorSpace.TYPE_3CLR;
-            case icSigSpace4CLR:
-                return ColorSpace.TYPE_4CLR;
-            case icSigSpace5CLR:
-                return ColorSpace.TYPE_5CLR;
-            case icSigSpace6CLR:
-                return ColorSpace.TYPE_6CLR;
-            case icSigSpace7CLR:
-                return ColorSpace.TYPE_7CLR;
-            case icSigSpace8CLR:
-                return ColorSpace.TYPE_8CLR;
-            case icSigSpace9CLR:
-                return ColorSpace.TYPE_9CLR;
-            case icSigSpaceACLR:
-                return ColorSpace.TYPE_ACLR;
-            case icSigSpaceBCLR:
-                return ColorSpace.TYPE_BCLR;
-            case icSigSpaceCCLR:
-                return ColorSpace.TYPE_CCLR;
-            case icSigSpaceDCLR:
-                return ColorSpace.TYPE_DCLR;
-            case icSigSpaceECLR:
-                return ColorSpace.TYPE_ECLR;
-            case icSigSpaceFCLR:
-                return ColorSpace.TYPE_FCLR;
-            default:
-        }
-
-        // awt.165=Color space doesn't comply with ICC specification
-        throw new IllegalArgumentException(Messages.getString("awt.165")); //$NON-NLS-1$
-    }
-
-    /**
-     * Gets the profile handle.
-     * 
-     * @return the profile handle
-     */
-    private long getProfileHandle() {
-        handleStolen = true;
-        return profileHandle;
-    }
-
-    /**
-     * Gets the data size.
-     * 
-     * @param tagSignature
-     *            the tag signature
-     * @return the data size
-     */
-    private int getDataSize(int tagSignature) {
-        return NativeCMM.cmmGetProfileElementSize(profileHandle, tagSignature);
-    }
-
-    /**
-     * Reads XYZ value from the tag data.
-     * 
-     * @param tagSignature
-     *            the tag signature
-     * @return the XYZ value
-     */
-    float[] getXYZValue(int tagSignature) {
-        float[] res = new float[3];
-        byte[] data = getData(tagSignature);
-
-        // Convert from ICC s15Fixed16Number type
-        // 1 (float) = 0x10000 (s15Fixed16Number),
-        // hence dividing by 0x10000
-        res[0] = ICC_ProfileHelper.getIntFromByteArray(data, 0) / 65536.f;
-        res[1] = ICC_ProfileHelper.getIntFromByteArray(data, 4) / 65536.f;
-        res[2] = ICC_ProfileHelper.getIntFromByteArray(data, 8) / 65536.f;
-
-        return res;
-    }
-
-    /**
-     * Gets the media white point.
-     * 
-     * @return the media white point.
-     */
-    float[] getMediaWhitePoint() {
-        return getXYZValue(icSigMediaWhitePointTag);
-    }
-
-    /**
-     * If TRC is not a table returns gamma via return value and sets dataTRC to
-     * null. If TRC is a table returns 0 and fills dataTRC with values.
-     * 
-     * @param tagSignature
-     *            the tag signature
-     * @param dataTRC
-     *            the data trc
-     * @return - gamma or zero if TRC is a table
-     */
-    private float getGammaOrTRC(int tagSignature, short[] dataTRC) {
-        byte[] data = getData(tagSignature);
-        int trcSize = ICC_ProfileHelper.getIntFromByteArray(data, icCurveCount);
-
-        dataTRC = null;
-
-        if (trcSize == 0) {
-            return 1.0f;
-        }
-
-        if (trcSize == 1) {
-            // Cast from ICC u8Fixed8Number to float
-            return ICC_ProfileHelper.getShortFromByteArray(data, icCurveData) / 256.f;
-        }
-
-        // TRC is a table
-        dataTRC = new short[trcSize];
-        for (int i = 0, pos = icCurveData; i < trcSize; i++, pos += 2) {
-            dataTRC[i] = ICC_ProfileHelper.getShortFromByteArray(data, pos);
-        }
-        return 0;
-    }
-
-    /**
-     * Gets the gamma.
-     * 
-     * @param tagSignature
-     *            the tag signature
-     * @return the gamma
-     */
-    float getGamma(int tagSignature) {
-        short[] dataTRC = null;
-        float gamma = getGammaOrTRC(tagSignature, dataTRC);
-
-        if (dataTRC == null) {
-            return gamma;
-        }
-        // awt.166=TRC is not a simple gamma value.
-        throw new ProfileDataException(Messages.getString("awt.166")); //$NON-NLS-1$
-    }
-
-    /**
-     * Gets the TRC.
-     * 
-     * @param tagSignature
-     *            the tag signature
-     * @return the tRC
-     */
-    short[] getTRC(int tagSignature) {
-        short[] dataTRC = null;
-        getGammaOrTRC(tagSignature, dataTRC);
-
-        if (dataTRC == null) {
-            // awt.167=TRC is a gamma value, not a table.
-            throw new ProfileDataException(Messages.getString("awt.167")); //$NON-NLS-1$
-        }
-        return dataTRC;
-    }
-}
diff --git a/awt/java/awt/color/ICC_ProfileGray.java b/awt/java/awt/color/ICC_ProfileGray.java
deleted file mode 100644
index f748101..0000000
--- a/awt/java/awt/color/ICC_ProfileGray.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package java.awt.color;
-
-/**
- * The ICC_ProfileGray class represent profiles with TYPE_GRAY color space type,
- * and includes the grayTRCTag and mediaWhitePointTag tags. The gray component
- * can be transformed from a GRAY device profile color space to the CIEXYZ
- * Profile through the tone reproduction curve (TRC):
- * <p>
- * PCSY = grayTRC[deviceGray]
- * 
- * @since Android 1.0
- */
-public class ICC_ProfileGray extends ICC_Profile {
-    
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -1124721290732002649L;
-
-    /**
-     * Instantiates a new iC c_ profile gray.
-     * 
-     * @param profileHandle
-     *            the profile handle
-     */
-    ICC_ProfileGray(long profileHandle) {
-        super(profileHandle);
-    }
-
-    /**
-     * Gets the TRC as an array of shorts.
-     * 
-     * @return the short array of the TRC.
-     */
-    public short[] getTRC() {
-        return super.getTRC(icSigGrayTRCTag);
-    }
-
-    /**
-     * Gets the media white point.
-     * 
-     * @return the media white point
-     */
-    @Override
-    public float[] getMediaWhitePoint() {
-        return super.getMediaWhitePoint();
-    }
-
-    /**
-     * Gets a gamma value representing the tone reproduction curve (TRC).
-     * 
-     * @return the gamma value representing the tone reproduction curve (TRC).
-     */
-    public float getGamma() {
-        return super.getGamma(icSigGrayTRCTag);
-    }
-}
-
diff --git a/awt/java/awt/color/ICC_ProfileRGB.java b/awt/java/awt/color/ICC_ProfileRGB.java
deleted file mode 100644
index 9c6010f..0000000
--- a/awt/java/awt/color/ICC_ProfileRGB.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package java.awt.color;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The ICC_ProfileRGB class represents profiles with RGB color space type and
- * contains the redColorantTag, greenColorantTag, blueColorantTag, redTRCTag,
- * greenTRCTag, blueTRCTag, and mediaWhitePointTag tags.
- * 
- * @since Android 1.0
- */
-public class ICC_ProfileRGB extends ICC_Profile {
-    
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 8505067385152579334L;
-
-    /**
-     * Instantiates a new RGB ICC_Profile.
-     * 
-     * @param profileHandle
-     *            the profile handle
-     */
-    ICC_ProfileRGB(long profileHandle) {
-        super(profileHandle);
-    }
-
-    /**
-     * The Constant REDCOMPONENT indicates the red component.
-     */
-    public static final int REDCOMPONENT = 0;
-
-    /**
-     * The Constant GREENCOMPONENT indicates the green component.
-     */
-    public static final int GREENCOMPONENT = 1;
-
-    /**
-     * The Constant BLUECOMPONENT indicates the blue component.
-     */
-    public static final int BLUECOMPONENT = 2;
-
-    // awt.15E=Unknown component. Must be REDCOMPONENT, GREENCOMPONENT or BLUECOMPONENT.
-    /**
-     * The Constant UNKNOWN_COMPONENT_MSG.
-     */
-    private static final String UNKNOWN_COMPONENT_MSG = Messages
-            .getString("awt.15E"); //$NON-NLS-1$
-
-    /**
-     * Gets the TRC.
-     * 
-     * @param component
-     *            the tag signature.
-     * @return the TRC value.
-     */
-    @Override
-    public short[] getTRC(int component) {
-        switch (component) {
-            case REDCOMPONENT:
-                return super.getTRC(icSigRedTRCTag);
-            case GREENCOMPONENT:
-                return super.getTRC(icSigGreenTRCTag);
-            case BLUECOMPONENT:
-                return super.getTRC(icSigBlueTRCTag);
-            default:
-        }
-
-        throw new IllegalArgumentException(UNKNOWN_COMPONENT_MSG);
-    }
-
-    /**
-     * Gets the gamma.
-     * 
-     * @param component
-     *            the tag signature.
-     * @return the gamma value.
-     */
-    @Override
-    public float getGamma(int component) {
-        switch (component) {
-            case REDCOMPONENT:
-                return super.getGamma(icSigRedTRCTag);
-            case GREENCOMPONENT:
-                return super.getGamma(icSigGreenTRCTag);
-            case BLUECOMPONENT:
-                return super.getGamma(icSigBlueTRCTag);
-            default:
-        }
-
-        throw new IllegalArgumentException(UNKNOWN_COMPONENT_MSG);
-    }
-
-    /**
-     * Gets a float matrix which contains the X, Y, and Z components of the
-     * profile's redColorantTag, greenColorantTag, and blueColorantTag.
-     * 
-     * @return the float matrix which contains the X, Y, and Z components of the
-     *         profile's redColorantTag, greenColorantTag, and blueColorantTag.
-     */
-    public float[][] getMatrix() {
-        float [][] m = new float[3][3]; // The matrix
-
-        float[] redXYZ = getXYZValue(icSigRedColorantTag);
-        float[] greenXYZ = getXYZValue(icSigGreenColorantTag);
-        float[] blueXYZ = getXYZValue(icSigBlueColorantTag);
-
-        m[0][0] = redXYZ[0];
-        m[1][0] = redXYZ[1];
-        m[2][0] = redXYZ[2];
-
-        m[0][1] = greenXYZ[0];
-        m[1][1] = greenXYZ[1];
-        m[2][1] = greenXYZ[2];
-
-        m[0][2] = blueXYZ[0];
-        m[1][2] = blueXYZ[1];
-        m[2][2] = blueXYZ[2];
-
-        return m;
-    }
-
-    /**
-     * Gets the media white point.
-     * 
-     * @return the media white point.
-     */
-    @Override
-    public float[] getMediaWhitePoint() {
-        return super.getMediaWhitePoint();
-    }
-}
-
diff --git a/awt/java/awt/color/ICC_ProfileStub.java b/awt/java/awt/color/ICC_ProfileStub.java
deleted file mode 100644
index bc04c8a..0000000
--- a/awt/java/awt/color/ICC_ProfileStub.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package java.awt.color;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectStreamException;
-import java.io.OutputStream;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-final class ICC_ProfileStub extends ICC_Profile {
-    private static final long serialVersionUID = 501389760875253507L;
-
-    transient int colorspace;
-
-    public ICC_ProfileStub(int csSpecifier) {
-        switch (csSpecifier) {
-            case ColorSpace.CS_sRGB:
-            case ColorSpace.CS_CIEXYZ:
-            case ColorSpace.CS_LINEAR_RGB:
-            case ColorSpace.CS_PYCC:
-            case ColorSpace.CS_GRAY:
-                break;
-            default:
-                // awt.15D=Invalid colorspace
-                throw new IllegalArgumentException(Messages.getString("awt.15D")); //$NON-NLS-1$
-        }
-        colorspace = csSpecifier;
-    }
-
-    @Override
-    public void write(String fileName) throws IOException {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    /**
-     * Serializable implementation
-     *
-     * @throws ObjectStreamException
-     */
-    private Object writeReplace() throws ObjectStreamException {
-        return loadProfile();
-    }
-
-    @Override
-    public void write(OutputStream s) throws IOException {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    @Override
-    public void setData(int tagSignature, byte[] tagData) {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    @Override
-    public byte[] getData(int tagSignature) {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    @Override
-    public byte[] getData() {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    @Override
-    protected void finalize() {
-    }
-
-    @Override
-    public int getProfileClass() {
-        return CLASS_COLORSPACECONVERSION;
-    }
-
-    @Override
-    public int getPCSType() {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    @Override
-    public int getNumComponents() {
-        switch (colorspace) {
-            case ColorSpace.CS_sRGB:
-            case ColorSpace.CS_CIEXYZ:
-            case ColorSpace.CS_LINEAR_RGB:
-            case ColorSpace.CS_PYCC:
-                return 3;
-            case ColorSpace.CS_GRAY:
-                return 1;
-            default:
-                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-        }
-    }
-
-    @Override
-    public int getMinorVersion() {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    @Override
-    public int getMajorVersion() {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    @Override
-    public int getColorSpaceType() {
-        switch (colorspace) {
-            case ColorSpace.CS_sRGB:
-            case ColorSpace.CS_LINEAR_RGB:
-                return ColorSpace.TYPE_RGB;
-            case ColorSpace.CS_CIEXYZ:
-                return ColorSpace.TYPE_XYZ;
-            case ColorSpace.CS_PYCC:
-                return ColorSpace.TYPE_3CLR;
-            case ColorSpace.CS_GRAY:
-                return ColorSpace.TYPE_GRAY;
-            default:
-                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-        }
-    }
-
-    public static ICC_Profile getInstance(String fileName) throws IOException {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    public static ICC_Profile getInstance(InputStream s) throws IOException {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    public static ICC_Profile getInstance(byte[] data) {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    public static ICC_Profile getInstance(int cspace) {
-        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-    }
-
-    public ICC_Profile loadProfile() {
-        switch (colorspace) {
-            case ColorSpace.CS_sRGB:
-                return ICC_Profile.getInstance(ColorSpace.CS_sRGB);
-            case ColorSpace.CS_GRAY:
-                return ICC_Profile.getInstance(ColorSpace.CS_GRAY);
-            case ColorSpace.CS_CIEXYZ:
-                return ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
-            case ColorSpace.CS_LINEAR_RGB:
-                return ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB);
-            case ColorSpace.CS_PYCC:
-                return ICC_Profile.getInstance(ColorSpace.CS_PYCC);
-            default:
-                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
-        }
-    }
-}
\ No newline at end of file
diff --git a/awt/java/awt/color/ProfileDataException.java b/awt/java/awt/color/ProfileDataException.java
deleted file mode 100644
index 335f314..0000000
--- a/awt/java/awt/color/ProfileDataException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package java.awt.color;
-
-/**
- * The ProfileDataException class represents an error which occurs while
- * accessing or processing an ICC_Profile object.
- * 
- * @since Android 1.0
- */
-public class ProfileDataException extends RuntimeException {
-    
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 7286140888240322498L;
-
-    /**
-     * Instantiates a new profile data exception with detailed message.
-     * 
-     * @param s
-     *            the detailed message of the exception.
-     */
-    public ProfileDataException(String s) {
-        super(s);
-    }
-
-}
-
diff --git a/awt/java/awt/color/package.html b/awt/java/awt/color/package.html
deleted file mode 100644
index 609d963..0000000
--- a/awt/java/awt/color/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes representing color spaces and profiles based on the International Color Consortium (ICC) Profile Format Specification. 
-    </p>
-    @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/event/AWTEventListener.java b/awt/java/awt/event/AWTEventListener.java
deleted file mode 100644
index 76293b3..0000000
--- a/awt/java/awt/event/AWTEventListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.AWTEvent;
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface AWTEventListener extends EventListener {
-
-    public void eventDispatched(AWTEvent event);
-
-}
diff --git a/awt/java/awt/event/AWTEventListenerProxy.java b/awt/java/awt/event/AWTEventListenerProxy.java
deleted file mode 100644
index 3edc41f..0000000
--- a/awt/java/awt/event/AWTEventListenerProxy.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.AWTEvent;
-
-import java.util.EventListenerProxy;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class AWTEventListenerProxy extends EventListenerProxy implements AWTEventListener {
-
-    private AWTEventListener listener;
-    private long eventMask;
-
-    public AWTEventListenerProxy(long eventMask, AWTEventListener listener) {
-        super(listener);
-
-        // awt.193=Listener can't be zero
-        assert listener != null : Messages.getString("awt.193"); //$NON-NLS-1$
-
-        this.listener = listener;
-        this.eventMask = eventMask;
-    }
-
-    public void eventDispatched(AWTEvent evt) {
-        listener.eventDispatched(evt);
-    }
-
-    public long getEventMask() {
-        return eventMask;
-    }
-
-}
diff --git a/awt/java/awt/event/ActionEvent.java b/awt/java/awt/event/ActionEvent.java
deleted file mode 100644
index e882e0d..0000000
--- a/awt/java/awt/event/ActionEvent.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.AWTEvent;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class ActionEvent extends AWTEvent {
-
-    private static final long serialVersionUID = -7671078796273832149L;
-
-    public static final int SHIFT_MASK = 1;
-
-    public static final int CTRL_MASK = 2;
-
-    public static final int META_MASK = 4;
-
-    public static final int ALT_MASK = 8;
-
-    public static final int ACTION_FIRST = 1001;
-
-    public static final int ACTION_LAST = 1001;
-
-    public static final int ACTION_PERFORMED = 1001;
-
-    private long when;
-    private int modifiers;
-    private String command;
-
-    public ActionEvent(Object source, int id, String command) {
-        this(source, id, command, 0);
-    }
-
-    public ActionEvent(Object source, int id, String command, int modifiers) {
-        this(source, id, command, 0l, modifiers);
-    }
-
-    public ActionEvent(Object source, int id, String command, long when, int modifiers) {
-        super(source, id);
-
-        this.command = command;
-        this.when = when;
-        this.modifiers = modifiers;
-    }
-
-    public int getModifiers() {
-        return modifiers;
-    }
-
-    public String getActionCommand() {
-        return command;
-    }
-
-    public long getWhen() {
-        return when;
-    }
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * ActionEvent e = new ActionEvent(new Component(){},
-         *       ActionEvent.ACTION_PERFORMED, "Command",
-         *       ActionEvent.SHIFT_MASK|ActionEvent.CTRL_MASK|
-         *       ActionEvent.META_MASK|ActionEvent.ALT_MASK);
-         * System.out.println(e);
-         */
-
-        String idString = (id == ACTION_PERFORMED) ? 
-                          "ACTION_PERFORMED" : "unknown type"; //$NON-NLS-1$ //$NON-NLS-2$
-        String modifiersString = ""; //$NON-NLS-1$
-
-        if ((modifiers & SHIFT_MASK) > 0) {
-            modifiersString += "Shift"; //$NON-NLS-1$
-        }
-        if ((modifiers & CTRL_MASK) > 0) {
-            modifiersString += modifiersString.length() == 0 ? "Ctrl" : "+Ctrl"; //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        if ((modifiers & META_MASK) > 0) {
-            modifiersString += modifiersString.length() == 0 ? "Meta" : "+Meta"; //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        if ((modifiers & ALT_MASK) > 0) {
-            modifiersString += modifiersString.length() == 0 ? "Alt" : "+Alt"; //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        return (idString + ",cmd=" + command + ",when=" + when +  //$NON-NLS-1$ //$NON-NLS-2$
-                ",modifiers=" + modifiersString); //$NON-NLS-1$
-    }
-
-}
diff --git a/awt/java/awt/event/ActionListener.java b/awt/java/awt/event/ActionListener.java
deleted file mode 100644
index a6eee7a..0000000
--- a/awt/java/awt/event/ActionListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface ActionListener extends EventListener {
-
-    public void actionPerformed(ActionEvent e);
-
-}
diff --git a/awt/java/awt/event/AdjustmentEvent.java b/awt/java/awt/event/AdjustmentEvent.java
deleted file mode 100644
index be2d6c4..0000000
--- a/awt/java/awt/event/AdjustmentEvent.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.AWTEvent;
-import java.awt.Adjustable;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class AdjustmentEvent extends AWTEvent {
-
-    private static final long serialVersionUID = 5700290645205279921L;
-
-    public static final int ADJUSTMENT_FIRST = 601;
-
-    public static final int ADJUSTMENT_LAST = 601;
-
-    public static final int ADJUSTMENT_VALUE_CHANGED = 601;
-
-    public static final int UNIT_INCREMENT = 1;
-
-    public static final int UNIT_DECREMENT = 2;
-
-    public static final int BLOCK_DECREMENT = 3;
-
-    public static final int BLOCK_INCREMENT = 4;
-
-    public static final int TRACK = 5;
-
-    private int type;
-    private int value;
-    private boolean isAdjusting;
-
-    public AdjustmentEvent(Adjustable source, int id, int type, int value) {
-        this(source, id, type, value, false);
-    }
-
-    public AdjustmentEvent(Adjustable source, int id, int type, int value, 
-                           boolean isAdjusting) {
-        super(source, id);
-        this.type = type;
-        this.value = value;
-        this.isAdjusting = isAdjusting;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-    public int getAdjustmentType() {
-        return type;
-    }
-
-    public boolean getValueIsAdjusting() {
-        return isAdjusting;
-    }
-
-    public Adjustable getAdjustable() {
-        return (Adjustable) source;
-    }
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * AdjustmentEvent e = new AdjustmentEvent(new Scrollbar(), 
-         *       AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 
-         *       AdjustmentEvent.UNIT_INCREMENT, 1);
-         * System.out.println(e);
-         */
-
-        String idString = (id == ADJUSTMENT_VALUE_CHANGED ?
-                "ADJUSTMENT_VALUE_CHANGED" : "unknown type"); //$NON-NLS-1$ //$NON-NLS-2$
-        String adjType = null;
-
-        switch (type) {
-        case UNIT_INCREMENT:
-            adjType = "UNIT_INCREMENT"; //$NON-NLS-1$
-            break;
-        case UNIT_DECREMENT:
-            adjType = "UNIT_DECREMENT"; //$NON-NLS-1$
-            break;
-        case BLOCK_INCREMENT:
-            adjType = "BLOCK_INCREMENT"; //$NON-NLS-1$
-            break;
-        case BLOCK_DECREMENT:
-            adjType = "BLOCK_DECREMENT"; //$NON-NLS-1$
-            break;
-        case TRACK:
-            adjType = "TRACK"; //$NON-NLS-1$
-            break;
-        default:
-            adjType = "unknown type"; //$NON-NLS-1$
-        }
-
-        return (idString + ",adjType=" + adjType + ",value=" + value + //$NON-NLS-1$ //$NON-NLS-2$
-                ",isAdjusting=" + isAdjusting); //$NON-NLS-1$
-    }
-
-}
diff --git a/awt/java/awt/event/AdjustmentListener.java b/awt/java/awt/event/AdjustmentListener.java
deleted file mode 100644
index 5f6a724..0000000
--- a/awt/java/awt/event/AdjustmentListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface AdjustmentListener extends EventListener {
-
-    public void adjustmentValueChanged(AdjustmentEvent e);
-
-}
diff --git a/awt/java/awt/event/ComponentAdapter.java b/awt/java/awt/event/ComponentAdapter.java
deleted file mode 100644
index c42235f..0000000
--- a/awt/java/awt/event/ComponentAdapter.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public abstract class ComponentAdapter implements ComponentListener {
-
-    public ComponentAdapter() {
-    }
-
-    public void componentHidden(ComponentEvent e) {
-    }
-
-    public void componentMoved(ComponentEvent e) {
-    }
-
-    public void componentResized(ComponentEvent e) {
-    }
-
-    public void componentShown(ComponentEvent e) {
-    }
-
-}
diff --git a/awt/java/awt/event/ComponentEvent.java b/awt/java/awt/event/ComponentEvent.java
deleted file mode 100644
index 760d3ab..0000000
--- a/awt/java/awt/event/ComponentEvent.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.AWTEvent;
-import java.awt.Component;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class ComponentEvent extends AWTEvent {
-
-    private static final long serialVersionUID = 8101406823902992965L;
-
-    public static final int COMPONENT_FIRST = 100;
-
-    public static final int COMPONENT_LAST = 103;
-
-    public static final int COMPONENT_MOVED = 100;
-
-    public static final int COMPONENT_RESIZED = 101;
-
-    public static final int COMPONENT_SHOWN = 102;
-
-    public static final int COMPONENT_HIDDEN = 103;
-
-    public ComponentEvent(Component source, int id) {
-        super(source, id);
-    }
-
-    public Component getComponent() {
-        return (Component) source;
-    }
-    
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * ComponentEvent e = new ComponentEvent(new Button("Button"), 
-         *          ComponentEvent.COMPONENT_SHOWN);
-         * System.out.println(e);
-         */
-
-        String idString = null;
-        Component c = getComponent();
-
-        switch (id) {
-        case COMPONENT_MOVED:
-            idString = "COMPONENT_MOVED"; //$NON-NLS-1$
-            break;
-        case COMPONENT_RESIZED:
-            idString = "COMPONENT_RESIZED"; //$NON-NLS-1$
-            break;
-        case COMPONENT_SHOWN:
-            return "COMPONENT_SHOWN"; //$NON-NLS-1$
-        case COMPONENT_HIDDEN:
-            return "COMPONENT_HIDDEN"; //$NON-NLS-1$
-        default:
-            return "unknown type"; //$NON-NLS-1$
-        }
-
-        return (idString + " (" + c.getX() + "," + c.getY() +  //$NON-NLS-1$ //$NON-NLS-2$
-                " " + c.getWidth()+ "x" + c.getHeight() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    }
-
-}
diff --git a/awt/java/awt/event/ComponentListener.java b/awt/java/awt/event/ComponentListener.java
deleted file mode 100644
index a5adba2..0000000
--- a/awt/java/awt/event/ComponentListener.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface ComponentListener extends EventListener {
-
-    public void componentHidden(ComponentEvent e);
-
-    public void componentMoved(ComponentEvent e);
-
-    public void componentResized(ComponentEvent e);
-
-    public void componentShown(ComponentEvent e);
-
-}
diff --git a/awt/java/awt/event/ContainerAdapter.java b/awt/java/awt/event/ContainerAdapter.java
deleted file mode 100644
index 44983c7..0000000
--- a/awt/java/awt/event/ContainerAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public abstract class ContainerAdapter implements ContainerListener {
-
-    public ContainerAdapter() {
-    }
-
-    public void componentAdded(ContainerEvent e) {
-    }
-
-    public void componentRemoved(ContainerEvent e) {
-    }
-
-}
diff --git a/awt/java/awt/event/ContainerEvent.java b/awt/java/awt/event/ContainerEvent.java
deleted file mode 100644
index 372c9e4..0000000
--- a/awt/java/awt/event/ContainerEvent.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.Component;
-//???AWT: import java.awt.Container;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class ContainerEvent extends ComponentEvent {
-
-    private static final long serialVersionUID = -4114942250539772041L;
-
-    public static final int CONTAINER_FIRST = 300;
-
-    public static final int CONTAINER_LAST = 301;
-
-    public static final int COMPONENT_ADDED = 300;
-
-    public static final int COMPONENT_REMOVED = 301;
-
-    private Component child;
-
-    public ContainerEvent(Component src, int id, Component child) {
-        super(src, id);
-        this.child = child;
-    }
-
-    public Component getChild() {
-        return child;
-    }
-
-    //???AWT
-    /*
-    public Container getContainer() {
-        return (Container) source;
-    }
-    */
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * ContainerEvent e = new ContainerEvent(new Panel(),
-         *          ContainerEvent.COMPONENT_ADDED,
-         *          new Button("Button"));
-         * System.out.println(e);
-         */
-
-        String idString = null;
-
-        switch (id) {
-        case COMPONENT_ADDED:
-            idString = "COMPONENT_ADDED"; //$NON-NLS-1$
-            break;
-        case COMPONENT_REMOVED:
-            idString = "COMPONENT_REMOVED"; //$NON-NLS-1$
-            break;
-        default:
-            idString = "unknown type"; //$NON-NLS-1$
-        }
-
-        return (idString + ",child=" + child.getName()); //$NON-NLS-1$
-    }
-
-}
diff --git a/awt/java/awt/event/ContainerListener.java b/awt/java/awt/event/ContainerListener.java
deleted file mode 100644
index 517859e..0000000
--- a/awt/java/awt/event/ContainerListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface ContainerListener extends EventListener {
-
-    public void componentAdded(ContainerEvent e);
-
-    public void componentRemoved(ContainerEvent e);
-
-}
diff --git a/awt/java/awt/event/FocusAdapter.java b/awt/java/awt/event/FocusAdapter.java
deleted file mode 100644
index 3a3e37f..0000000
--- a/awt/java/awt/event/FocusAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public abstract class FocusAdapter implements FocusListener {
-
-    public FocusAdapter() {
-    }
-
-    public void focusGained(FocusEvent e) {
-    }
-
-    public void focusLost(FocusEvent e) {
-    }
-
-}
diff --git a/awt/java/awt/event/FocusEvent.java b/awt/java/awt/event/FocusEvent.java
deleted file mode 100644
index 4a186895..0000000
--- a/awt/java/awt/event/FocusEvent.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.Component;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class FocusEvent extends ComponentEvent {
-
-    private static final long serialVersionUID = 523753786457416396L;
-
-    public static final int FOCUS_FIRST = 1004;
-
-    public static final int FOCUS_LAST = 1005;
-
-    public static final int FOCUS_GAINED = 1004;
-
-    public static final int FOCUS_LOST = 1005;
-
-    private boolean temporary;
-    private Component opposite;
-
-    public FocusEvent(Component source, int id) {
-        this(source, id, false);
-    }
-
-    public FocusEvent(Component source, int id, boolean temporary) {
-        this(source, id, temporary, null);
-    }
-
-    public FocusEvent(Component source, int id, boolean temporary, Component opposite) {
-        super(source, id);
-        this.temporary = temporary;
-        this.opposite = opposite;
-    }
-
-    public Component getOppositeComponent() {
-        return opposite;
-    }
-
-    public boolean isTemporary() {
-        return temporary;
-    }
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * FocusEvent e = new FocusEvent(new Button("Button0"),
-         *       FocusEvent.FOCUS_GAINED, false, new Button("Button1"));
-         * System.out.println(e);
-         */
-
-        String idString = null;
-
-        switch (id) {
-        case FOCUS_GAINED:
-            idString = "FOCUS_GAINED"; //$NON-NLS-1$
-            break;
-        case FOCUS_LOST:
-            idString = "FOCUS_LOST"; //$NON-NLS-1$
-            break;
-        default:
-            idString = "unknown type"; //$NON-NLS-1$
-        }
-
-        return (idString +
-                (temporary ? ",temporary" : ",permanent") + //$NON-NLS-1$ //$NON-NLS-2$
-                ",opposite=" + opposite); //$NON-NLS-1$
-    }
-
-}
diff --git a/awt/java/awt/event/FocusListener.java b/awt/java/awt/event/FocusListener.java
deleted file mode 100644
index 6bbbd00..0000000
--- a/awt/java/awt/event/FocusListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface FocusListener extends EventListener {
-
-    public void focusGained(FocusEvent e);
-
-    public void focusLost(FocusEvent e);
-
-}
diff --git a/awt/java/awt/event/HierarchyBoundsAdapter.java b/awt/java/awt/event/HierarchyBoundsAdapter.java
deleted file mode 100644
index bbfe8ff..0000000
--- a/awt/java/awt/event/HierarchyBoundsAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public abstract class HierarchyBoundsAdapter implements HierarchyBoundsListener {
-
-    public HierarchyBoundsAdapter() {
-    }
-
-    public void ancestorMoved(HierarchyEvent e) {
-    }
-
-    public void ancestorResized(HierarchyEvent e) {
-    }
-
-}
diff --git a/awt/java/awt/event/HierarchyBoundsListener.java b/awt/java/awt/event/HierarchyBoundsListener.java
deleted file mode 100644
index 3e8f2e7..0000000
--- a/awt/java/awt/event/HierarchyBoundsListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface HierarchyBoundsListener extends EventListener {
-
-    public void ancestorMoved(HierarchyEvent e);
-
-    public void ancestorResized(HierarchyEvent e);
-
-}
diff --git a/awt/java/awt/event/HierarchyEvent.java b/awt/java/awt/event/HierarchyEvent.java
deleted file mode 100644
index c1d22f4..0000000
--- a/awt/java/awt/event/HierarchyEvent.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.AWTEvent;
-import java.awt.Component;
-//???AWT: import java.awt.Container;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class HierarchyEvent extends AWTEvent {
-
-    private static final long serialVersionUID = -5337576970038043990L;
-
-    public static final int HIERARCHY_FIRST = 1400;
-
-    public static final int HIERARCHY_CHANGED = 1400;
-
-    public static final int ANCESTOR_MOVED = 1401;
-
-    public static final int ANCESTOR_RESIZED = 1402;
-
-    public static final int HIERARCHY_LAST = 1402;
-
-    public static final int PARENT_CHANGED = 1;
-
-    public static final int DISPLAYABILITY_CHANGED = 2;
-
-    public static final int SHOWING_CHANGED = 4;
-
-    //???AWT: private Container changedParent;
-    private Component changed;
-    private long changeFlag;
-
-    //???AWT
-    /*
-    public HierarchyEvent(Component source, int id, Component changed, 
-                          Container changedParent) {
-        this(source, id, changed, changedParent, 0l);
-    }
-    */
-
-    //???AWT
-    /*
-    public HierarchyEvent(Component source, int id, Component changed,
-            Container changedParent, long changeFlags) {
-        super(source, id);
-
-        this.changed = changed;
-        this.changedParent = changedParent;
-        this.changeFlag = changeFlags;
-    }
-    */
-    //???AWT: Fake constructor, should be as above.
-    public HierarchyEvent(Component source, int id, Component changed,
-            Object changedParent, long changeFlags) {
-        super(source, id);
-
-//        this.changed = changed;
-//        this.changedParent = changedParent;
-//        this.changeFlag = changeFlags;
-    }
-    
-    public Component getComponent() {
-        return (Component) source;
-    }
-
-    public long getChangeFlags() {
-        return changeFlag;
-    }
-
-    public Component getChanged() {
-        return changed;
-    }
-
-    //???AWT
-    /*
-    public Container getChangedParent() {
-        return changedParent;
-
-    }
-    */
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * HierarchyEvent e = new HierarchyEvent(new Button("Button"),
-         *          HierarchyEvent.HIERARCHY_CHANGED,
-         *          new Panel(), new Container());
-         * System.out.println(e);
-         */
-        String paramString = null;
-
-        switch (id) {
-        case HIERARCHY_CHANGED:
-            paramString = "HIERARCHY_CHANGED"; //$NON-NLS-1$
-            break;
-        case ANCESTOR_MOVED:
-            paramString = "ANCESTOR_MOVED"; //$NON-NLS-1$
-            break;
-        case ANCESTOR_RESIZED:
-            paramString = "ANCESTOR_RESIZED"; //$NON-NLS-1$
-            break;
-        default:
-            paramString = "unknown type"; //$NON-NLS-1$
-        }
-
-        paramString += " ("; //$NON-NLS-1$
-
-        if (id == HIERARCHY_CHANGED) {
-            if ((changeFlag & PARENT_CHANGED) > 0) {
-                paramString += "PARENT_CHANGED,"; //$NON-NLS-1$
-            }
-            if ((changeFlag & DISPLAYABILITY_CHANGED) > 0) {
-                paramString += "DISPLAYABILITY_CHANGED,"; //$NON-NLS-1$
-            }
-            if ((changeFlag & SHOWING_CHANGED) > 0) {
-                paramString += "SHOWING_CHANGED,"; //$NON-NLS-1$
-            }
-        }
-
-        //???AWT
-        /*
-        return paramString + "changed=" + changed +  //$NON-NLS-1$
-                ",changedParent=" + changedParent + ")"; //$NON-NLS-1$ //$NON-NLS-2$
-        */
-        return paramString;
-    }
-
-}
diff --git a/awt/java/awt/event/HierarchyListener.java b/awt/java/awt/event/HierarchyListener.java
deleted file mode 100644
index ff3d9bc..0000000
--- a/awt/java/awt/event/HierarchyListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface HierarchyListener extends EventListener {
-
-    public void hierarchyChanged(HierarchyEvent e);
-
-}
diff --git a/awt/java/awt/event/InputEvent.java b/awt/java/awt/event/InputEvent.java
deleted file mode 100644
index 343b7a3..0000000
--- a/awt/java/awt/event/InputEvent.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.Component;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public abstract class InputEvent extends ComponentEvent {
-
-    private static final long serialVersionUID = -2482525981698309786L;
-
-    public static final int SHIFT_MASK = 1;
-
-    public static final int CTRL_MASK = 2;
-
-    public static final int META_MASK = 4;
-
-    public static final int ALT_MASK = 8;
-
-    public static final int ALT_GRAPH_MASK = 32;
-
-    public static final int BUTTON1_MASK = 16;
-
-    public static final int BUTTON2_MASK = 8;
-
-    public static final int BUTTON3_MASK = 4;
-
-    public static final int SHIFT_DOWN_MASK = 64;
-
-    public static final int CTRL_DOWN_MASK = 128;
-
-    public static final int META_DOWN_MASK = 256;
-
-    public static final int ALT_DOWN_MASK = 512;
-
-    public static final int BUTTON1_DOWN_MASK = 1024;
-
-    public static final int BUTTON2_DOWN_MASK = 2048;
-
-    public static final int BUTTON3_DOWN_MASK = 4096;
-
-    public static final int ALT_GRAPH_DOWN_MASK = 8192;
-
-    private static final int DOWN_MASKS = SHIFT_DOWN_MASK | CTRL_DOWN_MASK |
-            META_DOWN_MASK | ALT_DOWN_MASK | BUTTON1_DOWN_MASK |
-            BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK | ALT_GRAPH_DOWN_MASK;
-
-    private long when;
-    private int modifiersEx;
-
-    public static String getModifiersExText(int modifiers/*Ex*/) {
-        return MouseEvent.addMouseModifiersExText(
-                KeyEvent.getKeyModifiersExText(modifiers), modifiers);
-    }
-
-    static int extractExFlags(int modifiers) {
-        int exFlags = modifiers & DOWN_MASKS;
-
-        if ((modifiers & SHIFT_MASK) != 0) {
-            exFlags |= SHIFT_DOWN_MASK;
-        }
-        if ((modifiers & CTRL_MASK) != 0) {
-            exFlags |= CTRL_DOWN_MASK;
-        }
-        if ((modifiers & META_MASK) != 0) {
-            exFlags |= META_DOWN_MASK;
-        }
-        if ((modifiers & ALT_MASK) != 0) {
-            exFlags |= ALT_DOWN_MASK;
-        }
-        if ((modifiers & ALT_GRAPH_MASK) != 0) {
-            exFlags |= ALT_GRAPH_DOWN_MASK;
-        }
-        if ((modifiers & BUTTON1_MASK) != 0) {
-            exFlags |= BUTTON1_DOWN_MASK;
-        }
-        if ((modifiers & BUTTON2_MASK) != 0) {
-            exFlags |= BUTTON2_DOWN_MASK;
-        }
-        if ((modifiers & BUTTON3_MASK) != 0) {
-            exFlags |= BUTTON3_DOWN_MASK;
-        }
-
-        return exFlags;
-    }
-
-    InputEvent(Component source, int id, long when, int modifiers) {
-        super(source, id);
-
-        this.when = when;
-        modifiersEx = extractExFlags(modifiers);
-    }
-
-    public int getModifiers() {
-        int modifiers = 0;
-
-        if ((modifiersEx & SHIFT_DOWN_MASK) != 0) {
-            modifiers |= SHIFT_MASK;
-        }
-        if ((modifiersEx & CTRL_DOWN_MASK) != 0) {
-            modifiers |= CTRL_MASK;
-        }
-        if ((modifiersEx & META_DOWN_MASK) != 0) {
-            modifiers |= META_MASK;
-        }
-        if ((modifiersEx & ALT_DOWN_MASK) != 0) {
-            modifiers |= ALT_MASK;
-        }
-        if ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0) {
-            modifiers |= ALT_GRAPH_MASK;
-        }
-        if ((modifiersEx & BUTTON1_DOWN_MASK) != 0) {
-            modifiers |= BUTTON1_MASK;
-        }
-        if ((modifiersEx & BUTTON2_DOWN_MASK) != 0) {
-            modifiers |= BUTTON2_MASK;
-        }
-        if ((modifiersEx & BUTTON3_DOWN_MASK) != 0) {
-            modifiers |= BUTTON3_MASK;
-        }
-
-        return modifiers;
-    }
-
-    public int getModifiersEx() {
-        return modifiersEx;
-    }
-
-    void setModifiers(int modifiers) {
-        modifiersEx = extractExFlags(modifiers);
-    }
-
-    public boolean isAltDown() {
-        return ((modifiersEx & ALT_DOWN_MASK) != 0);
-    }
-
-    public boolean isAltGraphDown() {
-        return ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0);
-    }
-
-    public boolean isControlDown() {
-        return ((modifiersEx & CTRL_DOWN_MASK) != 0);
-    }
-
-    public boolean isMetaDown() {
-        return ((modifiersEx & META_DOWN_MASK) != 0);
-    }
-
-    public boolean isShiftDown() {
-        return ((modifiersEx & SHIFT_DOWN_MASK) != 0);
-    }
-
-    public long getWhen() {
-        return when;
-    }
-
-    @Override
-    public void consume() {
-        super.consume();
-    }
-
-    @Override
-    public boolean isConsumed() {
-        return super.isConsumed();
-    }
-
-}
diff --git a/awt/java/awt/event/InputMethodEvent.java b/awt/java/awt/event/InputMethodEvent.java
deleted file mode 100644
index be001a5..0000000
--- a/awt/java/awt/event/InputMethodEvent.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.AWTEvent;
-import java.awt.Component;
-import java.awt.font.TextHitInfo;
-import java.text.AttributedCharacterIterator;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class InputMethodEvent extends AWTEvent {
-
-    private static final long serialVersionUID = 4727190874778922661L;
-
-    public static final int INPUT_METHOD_FIRST = 1100;
-
-    public static final int INPUT_METHOD_TEXT_CHANGED = 1100;
-
-    public static final int CARET_POSITION_CHANGED = 1101;
-
-    public static final int INPUT_METHOD_LAST = 1101;
-
-    private AttributedCharacterIterator text;
-    private TextHitInfo visiblePosition;
-    private TextHitInfo caret;
-    private int committedCharacterCount;
-    private long when;
-
-    public InputMethodEvent(Component src, int id,
-                            TextHitInfo caret, 
-                            TextHitInfo visiblePos) {
-        this(src, id, null, 0, caret, visiblePos);
-    }
-
-    public InputMethodEvent(Component src, int id, 
-                            AttributedCharacterIterator text,
-                            int commitedCharCount,
-                            TextHitInfo caret, 
-                            TextHitInfo visiblePos) {
-        this(src, id, 0l, text, commitedCharCount, caret, visiblePos);
-    }
-
-    public InputMethodEvent(Component src, int id, long when,
-                            AttributedCharacterIterator text, 
-                            int committedCharacterCount,
-                            TextHitInfo caret,
-                            TextHitInfo visiblePos) {
-        super(src, id);
-
-        if ((id < INPUT_METHOD_FIRST) || (id > INPUT_METHOD_LAST)) {
-            // awt.18E=Wrong event id
-            throw new IllegalArgumentException(Messages.getString("awt.18E")); //$NON-NLS-1$
-        }
-        if ((id == CARET_POSITION_CHANGED) && (text != null)) {
-            // awt.18F=Text must be null for CARET_POSITION_CHANGED
-            throw new IllegalArgumentException(Messages.getString("awt.18F")); //$NON-NLS-1$
-        }
-        if ((text != null) &&
-                ((committedCharacterCount < 0) ||
-                 (committedCharacterCount > 
-                        (text.getEndIndex() - text.getBeginIndex())))) {
-            // awt.190=Wrong committedCharacterCount
-            throw new IllegalArgumentException(Messages.getString("awt.190")); //$NON-NLS-1$
-        }
-
-        this.when = when;
-        this.text = text;
-        this.caret = caret;
-        this.visiblePosition = visiblePos;
-        this.committedCharacterCount = committedCharacterCount;
-    }
-
-    public TextHitInfo getCaret() {
-        return caret;
-    }
-
-    public int getCommittedCharacterCount() {
-        return committedCharacterCount;
-    }
-
-    public AttributedCharacterIterator getText() {
-        return text;
-    }
-
-    public TextHitInfo getVisiblePosition() {
-        return visiblePosition;
-    }
-
-    public long getWhen() {
-        return when;
-    }
-
-    @Override
-    public void consume() {
-        super.consume();
-    }
-
-    @Override
-    public boolean isConsumed() {
-        return super.isConsumed();
-    }
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * InputMethodEvent e = new InputMethodEvent(new Component(){},
-         *          InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
-         *          TextHitInfo.leading(1), TextHitInfo.trailing(2));
-         * System.out.println(e);
-         */
-        String typeString = null;
-
-        switch (id) {
-        case INPUT_METHOD_TEXT_CHANGED:
-            typeString = "INPUT_METHOD_TEXT_CHANGED"; //$NON-NLS-1$
-            break;
-        case CARET_POSITION_CHANGED:
-            typeString = "CARET_POSITION_CHANGED"; //$NON-NLS-1$
-            break;
-        default:
-            typeString = "unknown type"; //$NON-NLS-1$
-        }
-
-        return typeString + ",text=" + text +  //$NON-NLS-1$
-                ",commitedCharCount=" + committedCharacterCount + //$NON-NLS-1$
-                ",caret=" + caret + ",visiblePosition=" + visiblePosition; //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-}
diff --git a/awt/java/awt/event/InputMethodListener.java b/awt/java/awt/event/InputMethodListener.java
deleted file mode 100644
index 85eaa7e..0000000
--- a/awt/java/awt/event/InputMethodListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface InputMethodListener extends EventListener {
-
-    public void caretPositionChanged(InputMethodEvent e);
-
-    public void inputMethodTextChanged(InputMethodEvent e);
-
-}
diff --git a/awt/java/awt/event/InvocationEvent.java b/awt/java/awt/event/InvocationEvent.java
deleted file mode 100644
index 58e3b72..0000000
--- a/awt/java/awt/event/InvocationEvent.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.AWTEvent;
-import java.awt.ActiveEvent;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class InvocationEvent extends AWTEvent implements ActiveEvent {
-
-    private static final long serialVersionUID = 436056344909459450L;
-
-    public static final int INVOCATION_FIRST = 1200;
-
-    public static final int INVOCATION_DEFAULT = 1200;
-
-    public static final int INVOCATION_LAST = 1200;
-
-    protected Runnable runnable;
-
-    protected Object notifier;
-
-    protected boolean catchExceptions;
-
-    private long when;
-    private Throwable throwable;
-
-    public InvocationEvent(Object source, Runnable runnable) {
-        this(source, runnable, null, false);
-    }
-
-    public InvocationEvent(Object source, Runnable runnable, 
-                           Object notifier, boolean catchExceptions) {
-        this(source, INVOCATION_DEFAULT, runnable, notifier, catchExceptions);
-    }
-
-    protected InvocationEvent(Object source, int id, Runnable runnable,
-            Object notifier, boolean catchExceptions)
-    {
-        super(source, id);
-
-        // awt.18C=Cannot invoke null runnable
-        assert runnable != null : Messages.getString("awt.18C"); //$NON-NLS-1$
-
-        if (source == null) {
-            // awt.18D=Source is null
-            throw new IllegalArgumentException(Messages.getString("awt.18D")); //$NON-NLS-1$
-        }
-        this.runnable = runnable;
-        this.notifier = notifier;
-        this.catchExceptions = catchExceptions;
-
-        throwable = null;
-        when = System.currentTimeMillis();
-    }
-
-    public void dispatch() {
-        if (!catchExceptions) {
-            runAndNotify();
-        } else {
-            try {
-                runAndNotify();
-            } catch (Throwable t) {
-                throwable = t;
-            }
-        }
-    }
-
-    private void runAndNotify() {
-        if (notifier != null) {
-            synchronized(notifier) {
-                try {
-                    runnable.run();
-                } finally {
-                    notifier.notifyAll();
-                }
-            }
-        } else {
-            runnable.run();
-        }
-    }
-
-    public Exception getException() {
-        return (throwable != null && throwable instanceof Exception) ?
-                (Exception)throwable : null;
-    }
-
-    public Throwable getThrowable() {
-        return throwable;
-    }
-
-    public long getWhen() {
-        return when;
-    }
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * InvocationEvent e = new InvocationEvent(new Component(){},
-         *       new Runnable() { public void run(){} });
-         * System.out.println(e);
-         */
-
-        return ((id == INVOCATION_DEFAULT ? "INVOCATION_DEFAULT" : "unknown type") + //$NON-NLS-1$ //$NON-NLS-2$
-                ",runnable=" + runnable + //$NON-NLS-1$
-                ",notifier=" + notifier + //$NON-NLS-1$
-                ",catchExceptions=" + catchExceptions + //$NON-NLS-1$
-                ",when=" + when); //$NON-NLS-1$
-    }
-
-}
diff --git a/awt/java/awt/event/ItemEvent.java b/awt/java/awt/event/ItemEvent.java
deleted file mode 100644
index 09908f2..0000000
--- a/awt/java/awt/event/ItemEvent.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.AWTEvent;
-import java.awt.ItemSelectable;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class ItemEvent extends AWTEvent {
-
-    private static final long serialVersionUID = -608708132447206933L;
-
-    public static final int ITEM_FIRST = 701;
-
-    public static final int ITEM_LAST = 701;
-
-    public static final int ITEM_STATE_CHANGED = 701;
-
-    public static final int SELECTED = 1;
-
-    public static final int DESELECTED = 2;
-
-    private Object item;
-    private int stateChange;
-
-    public ItemEvent(ItemSelectable source, int id, Object item, int stateChange) {
-        super(source, id);
-
-        this.item = item;
-        this.stateChange = stateChange;
-    }
-
-    public Object getItem() {
-        return item;
-    }
-
-    public int getStateChange() {
-        return stateChange;
-    }
-
-    public ItemSelectable getItemSelectable() {
-        return (ItemSelectable) source;
-    }
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * Checkbox c = new Checkbox("Checkbox", true);
-         * ItemEvent e = new ItemEvent(c, ItemEvent.ITEM_STATE_CHANGED, 
-         *                             c, ItemEvent.SELECTED);
-         * System.out.println(e);
-         */
-
-        String stateString = null;
-
-        switch (stateChange) {
-        case SELECTED:
-            stateString = "SELECTED"; //$NON-NLS-1$
-            break;
-        case DESELECTED:
-            stateString = "DESELECTED"; //$NON-NLS-1$
-            break;
-        default:
-            stateString = "unknown type"; //$NON-NLS-1$
-        }
-
-        return ((id == ITEM_STATE_CHANGED ? "ITEM_STATE_CHANGED" : "unknown type") + //$NON-NLS-1$ //$NON-NLS-2$
-                ",item=" + item + ",stateChange=" + stateString); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-}
diff --git a/awt/java/awt/event/ItemListener.java b/awt/java/awt/event/ItemListener.java
deleted file mode 100644
index 8dec673..0000000
--- a/awt/java/awt/event/ItemListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface ItemListener extends EventListener {
-
-    public void itemStateChanged(ItemEvent e);
-
-}
diff --git a/awt/java/awt/event/KeyAdapter.java b/awt/java/awt/event/KeyAdapter.java
deleted file mode 100644
index a96cca8..0000000
--- a/awt/java/awt/event/KeyAdapter.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public abstract class KeyAdapter implements KeyListener {
-
-    public KeyAdapter() {
-    }
-
-    public void keyPressed(KeyEvent e) {
-    }
-
-    public void keyReleased(KeyEvent e) {
-    }
-
-    public void keyTyped(KeyEvent e) {
-    }
-
-}
diff --git a/awt/java/awt/event/KeyEvent.java b/awt/java/awt/event/KeyEvent.java
deleted file mode 100644
index 8627f70..0000000
--- a/awt/java/awt/event/KeyEvent.java
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.Component;
-import java.awt.Toolkit;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class KeyEvent extends InputEvent {
-
-    private static final long serialVersionUID = -2352130953028126954L;
-
-    public static final int KEY_FIRST = 400;
-
-    public static final int KEY_LAST = 402;
-
-    public static final int KEY_TYPED = 400;
-
-    public static final int KEY_PRESSED = 401;
-
-    public static final int KEY_RELEASED = 402;
-
-    public static final int VK_ENTER = 10;
-
-    public static final int VK_BACK_SPACE = 8;
-
-    public static final int VK_TAB = 9;
-
-    public static final int VK_CANCEL = 3;
-
-    public static final int VK_CLEAR = 12;
-
-    public static final int VK_SHIFT = 16;
-
-    public static final int VK_CONTROL = 17;
-
-    public static final int VK_ALT = 18;
-
-    public static final int VK_PAUSE = 19;
-
-    public static final int VK_CAPS_LOCK = 20;
-
-    public static final int VK_ESCAPE = 27;
-
-    public static final int VK_SPACE = 32;
-
-    public static final int VK_PAGE_UP = 33;
-
-    public static final int VK_PAGE_DOWN = 34;
-
-    public static final int VK_END = 35;
-
-    public static final int VK_HOME = 36;
-
-    public static final int VK_LEFT = 37;
-
-    public static final int VK_UP = 38;
-
-    public static final int VK_RIGHT = 39;
-
-    public static final int VK_DOWN = 40;
-
-    public static final int VK_COMMA = 44;
-
-    public static final int VK_MINUS = 45;
-
-    public static final int VK_PERIOD = 46;
-
-    public static final int VK_SLASH = 47;
-
-    public static final int VK_0 = 48;
-
-    public static final int VK_1 = 49;
-
-    public static final int VK_2 = 50;
-
-    public static final int VK_3 = 51;
-
-    public static final int VK_4 = 52;
-
-    public static final int VK_5 = 53;
-
-    public static final int VK_6 = 54;
-
-    public static final int VK_7 = 55;
-
-    public static final int VK_8 = 56;
-
-    public static final int VK_9 = 57;
-
-    public static final int VK_SEMICOLON = 59;
-
-    public static final int VK_EQUALS = 61;
-
-    public static final int VK_A = 65;
-
-    public static final int VK_B = 66;
-
-    public static final int VK_C = 67;
-
-    public static final int VK_D = 68;
-
-    public static final int VK_E = 69;
-
-    public static final int VK_F = 70;
-
-    public static final int VK_G = 71;
-
-    public static final int VK_H = 72;
-
-    public static final int VK_I = 73;
-
-    public static final int VK_J = 74;
-
-    public static final int VK_K = 75;
-
-    public static final int VK_L = 76;
-
-    public static final int VK_M = 77;
-
-    public static final int VK_N = 78;
-
-    public static final int VK_O = 79;
-
-    public static final int VK_P = 80;
-
-    public static final int VK_Q = 81;
-
-    public static final int VK_R = 82;
-
-    public static final int VK_S = 83;
-
-    public static final int VK_T = 84;
-
-    public static final int VK_U = 85;
-
-    public static final int VK_V = 86;
-
-    public static final int VK_W = 87;
-
-    public static final int VK_X = 88;
-
-    public static final int VK_Y = 89;
-
-    public static final int VK_Z = 90;
-
-    public static final int VK_OPEN_BRACKET = 91;
-
-    public static final int VK_BACK_SLASH = 92;
-
-    public static final int VK_CLOSE_BRACKET = 93;
-
-    public static final int VK_NUMPAD0 = 96;
-
-    public static final int VK_NUMPAD1 = 97;
-
-    public static final int VK_NUMPAD2 = 98;
-
-    public static final int VK_NUMPAD3 = 99;
-
-    public static final int VK_NUMPAD4 = 100;
-
-    public static final int VK_NUMPAD5 = 101;
-
-    public static final int VK_NUMPAD6 = 102;
-
-    public static final int VK_NUMPAD7 = 103;
-
-    public static final int VK_NUMPAD8 = 104;
-
-    public static final int VK_NUMPAD9 = 105;
-
-    public static final int VK_MULTIPLY = 106;
-
-    public static final int VK_ADD = 107;
-
-    public static final int VK_SEPARATER = 108;
-
-    public static final int VK_SEPARATOR = 108;
-
-    public static final int VK_SUBTRACT = 109;
-
-    public static final int VK_DECIMAL = 110;
-
-    public static final int VK_DIVIDE = 111;
-
-    public static final int VK_DELETE = 127;
-
-    public static final int VK_NUM_LOCK = 144;
-
-    public static final int VK_SCROLL_LOCK = 145;
-
-    public static final int VK_F1 = 112;
-
-    public static final int VK_F2 = 113;
-
-    public static final int VK_F3 = 114;
-
-    public static final int VK_F4 = 115;
-
-    public static final int VK_F5 = 116;
-
-    public static final int VK_F6 = 117;
-
-    public static final int VK_F7 = 118;
-
-    public static final int VK_F8 = 119;
-
-    public static final int VK_F9 = 120;
-
-    public static final int VK_F10 = 121;
-
-    public static final int VK_F11 = 122;
-
-    public static final int VK_F12 = 123;
-
-    public static final int VK_F13 = 61440;
-
-    public static final int VK_F14 = 61441;
-
-    public static final int VK_F15 = 61442;
-
-    public static final int VK_F16 = 61443;
-
-    public static final int VK_F17 = 61444;
-
-    public static final int VK_F18 = 61445;
-
-    public static final int VK_F19 = 61446;
-
-    public static final int VK_F20 = 61447;
-
-    public static final int VK_F21 = 61448;
-
-    public static final int VK_F22 = 61449;
-
-    public static final int VK_F23 = 61450;
-
-    public static final int VK_F24 = 61451;
-
-    public static final int VK_PRINTSCREEN = 154;
-
-    public static final int VK_INSERT = 155;
-
-    public static final int VK_HELP = 156;
-
-    public static final int VK_META = 157;
-
-    public static final int VK_BACK_QUOTE = 192;
-
-    public static final int VK_QUOTE = 222;
-
-    public static final int VK_KP_UP = 224;
-
-    public static final int VK_KP_DOWN = 225;
-
-    public static final int VK_KP_LEFT = 226;
-
-    public static final int VK_KP_RIGHT = 227;
-
-    public static final int VK_DEAD_GRAVE = 128;
-
-    public static final int VK_DEAD_ACUTE = 129;
-
-    public static final int VK_DEAD_CIRCUMFLEX = 130;
-
-    public static final int VK_DEAD_TILDE = 131;
-
-    public static final int VK_DEAD_MACRON = 132;
-
-    public static final int VK_DEAD_BREVE = 133;
-
-    public static final int VK_DEAD_ABOVEDOT = 134;
-
-    public static final int VK_DEAD_DIAERESIS = 135;
-
-    public static final int VK_DEAD_ABOVERING = 136;
-
-    public static final int VK_DEAD_DOUBLEACUTE = 137;
-
-    public static final int VK_DEAD_CARON = 138;
-
-    public static final int VK_DEAD_CEDILLA = 139;
-
-    public static final int VK_DEAD_OGONEK = 140;
-
-    public static final int VK_DEAD_IOTA = 141;
-
-    public static final int VK_DEAD_VOICED_SOUND = 142;
-
-    public static final int VK_DEAD_SEMIVOICED_SOUND = 143;
-
-    public static final int VK_AMPERSAND = 150;
-
-    public static final int VK_ASTERISK = 151;
-
-    public static final int VK_QUOTEDBL = 152;
-
-    public static final int VK_LESS = 153;
-
-    public static final int VK_GREATER = 160;
-
-    public static final int VK_BRACELEFT = 161;
-
-    public static final int VK_BRACERIGHT = 162;
-
-    public static final int VK_AT = 512;
-
-    public static final int VK_COLON = 513;
-
-    public static final int VK_CIRCUMFLEX = 514;
-
-    public static final int VK_DOLLAR = 515;
-
-    public static final int VK_EURO_SIGN = 516;
-
-    public static final int VK_EXCLAMATION_MARK = 517;
-
-    public static final int VK_INVERTED_EXCLAMATION_MARK = 518;
-
-    public static final int VK_LEFT_PARENTHESIS = 519;
-
-    public static final int VK_NUMBER_SIGN = 520;
-
-    public static final int VK_PLUS = 521;
-
-    public static final int VK_RIGHT_PARENTHESIS = 522;
-
-    public static final int VK_UNDERSCORE = 523;
-
-    public static final int VK_FINAL = 24;
-
-    public static final int VK_WINDOWS = 524; 
-
-    public static final int VK_CONTEXT_MENU = 525;
-
-    public static final int VK_CONVERT = 28;
-
-    public static final int VK_NONCONVERT = 29;
-
-    public static final int VK_ACCEPT = 30;
-
-    public static final int VK_MODECHANGE = 31;
-
-    public static final int VK_KANA = 21;
-
-    public static final int VK_KANJI = 25;
-
-    public static final int VK_ALPHANUMERIC = 240;
-
-    public static final int VK_KATAKANA = 241;
-
-    public static final int VK_HIRAGANA = 242;
-
-    public static final int VK_FULL_WIDTH = 243;
-
-    public static final int VK_HALF_WIDTH = 244;
-
-    public static final int VK_ROMAN_CHARACTERS = 245;
-
-    public static final int VK_ALL_CANDIDATES = 256;
-
-    public static final int VK_PREVIOUS_CANDIDATE = 257;
-
-    public static final int VK_CODE_INPUT = 258;
-
-    public static final int VK_JAPANESE_KATAKANA = 259;
-
-    public static final int VK_JAPANESE_HIRAGANA = 260;
-
-    public static final int VK_JAPANESE_ROMAN = 261;
-
-    public static final int VK_KANA_LOCK = 262;
-
-    public static final int VK_INPUT_METHOD_ON_OFF = 263;
-
-    public static final int VK_CUT = 65489;
-
-    public static final int VK_COPY = 65485;
-
-    public static final int VK_PASTE = 65487;
-
-    public static final int VK_UNDO = 65483;
-
-    public static final int VK_AGAIN = 65481;
-
-    public static final int VK_FIND = 65488;
-
-    public static final int VK_PROPS = 65482;
-
-    public static final int VK_STOP = 65480;
-
-    public static final int VK_COMPOSE = 65312;
-
-    public static final int VK_ALT_GRAPH = 65406;
-
-    public static final int VK_BEGIN = 65368;
-
-    public static final int VK_UNDEFINED = 0;
-
-    public static final char CHAR_UNDEFINED = (char)(-1);
-
-    public static final int KEY_LOCATION_UNKNOWN = 0;
-
-    public static final int KEY_LOCATION_STANDARD = 1;
-
-    public static final int KEY_LOCATION_LEFT = 2;
-
-    public static final int KEY_LOCATION_RIGHT = 3;
-
-    public static final int KEY_LOCATION_NUMPAD = 4;
-
-    private int keyCode;
-    private char keyChar;
-    private int keyLocation;
-
-    public static String getKeyModifiersText(int modifiers) {
-        return getKeyModifiersExText(extractExFlags(modifiers));
-    }
-
-    static String getKeyModifiersExText(int modifiersEx) {
-        String text = ""; //$NON-NLS-1$
-
-        if ((modifiersEx & InputEvent.META_DOWN_MASK) != 0) {
-            text += Toolkit.getProperty("AWT.meta", "Meta"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        if ((modifiersEx & InputEvent.CTRL_DOWN_MASK) != 0) {
-            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
-                    Toolkit.getProperty("AWT.control", "Ctrl"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        if ((modifiersEx & InputEvent.ALT_DOWN_MASK) != 0) {
-            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
-                    Toolkit.getProperty("AWT.alt", "Alt"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        if ((modifiersEx & InputEvent.SHIFT_DOWN_MASK) != 0) {
-            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
-                    Toolkit.getProperty("AWT.shift", "Shift"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        if ((modifiersEx & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) {
-            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
-                    Toolkit.getProperty("AWT.altGraph", "Alt Graph"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        return text;
-    }
-
-    public static String getKeyText(int keyCode) {
-        String[] rawName = getPublicStaticFinalIntFieldName(keyCode); //$NON-NLS-1$
-
-        if ((rawName == null) || (rawName.length == 0)) {
-            return ("Unknown keyCode: " + (keyCode >= 0 ? "0x" : "-0x") + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-                    Integer.toHexString(Math.abs(keyCode)));
-        }
-
-        String propertyName = getPropertyName(rawName);
-        String defaultName = getDefaultName(rawName);
-
-        return Toolkit.getProperty(propertyName, defaultName);
-    }
-
-    private static String getDefaultName(String[] rawName) {
-        String name = ""; //$NON-NLS-1$
-
-        for (int i = 0; true; i++) {
-            String part = rawName[i];
-
-            name += new String(new char[] {part.charAt(0)}).toUpperCase() +
-                    part.substring(1).toLowerCase();
-
-            if (i == (rawName.length - 1)) {
-                break;
-            }
-            name += " "; //$NON-NLS-1$
-        }
-
-        return name;
-    }
-
-    private static String getPropertyName(String[] rawName) {
-        String name = rawName[0].toLowerCase();
-
-        for (int i = 1; i < rawName.length; i++) {
-            String part = rawName[i];
-
-            name += new String(new char[] {part.charAt(0)}).toUpperCase() +
-                    part.substring(1).toLowerCase();
-        }
-
-        return ("AWT." + name); //$NON-NLS-1$
-    }
-
-    private static String[] getPublicStaticFinalIntFieldName(int value) {
-        Field[] allFields = KeyEvent.class.getDeclaredFields();
-
-        try {
-            for (Field field : allFields) {
-                Class<?> ssalc = field.getType();
-                int modifiers = field.getModifiers();
-
-                if (ssalc.isPrimitive() && ssalc.getName().equals("int") && //$NON-NLS-1$
-                        Modifier.isFinal(modifiers) && Modifier.isPublic(modifiers) &&
-                        Modifier.isStatic(modifiers))
-                {
-                    if (field.getInt(null) == value){
-                        final String name = field.getName();
-                        final int prefixLength = name.indexOf("_") + 1;
-                        return name.substring(prefixLength).split("_"); //$NON-NLS-1$
-                    }
-                }
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-
-        return null;
-    }
-
-    @Deprecated
-    public KeyEvent(Component src, int id,
-                    long when, int modifiers,
-                    int keyCode) {
-        this(src, id, when, modifiers, keyCode,
-                (keyCode > (2 << 7) - 1) ? CHAR_UNDEFINED : (char) keyCode);
-    }
-
-    public KeyEvent(Component src, int id,
-                    long when, int modifiers,
-                    int keyCode, char keyChar) {
-        this(src, id, when, modifiers, keyCode, keyChar, KEY_LOCATION_UNKNOWN);
-    }
-
-    public KeyEvent(Component src, int id,
-                    long when, int modifiers,
-                    int keyCode, char keyChar,
-                    int keyLocation) {
-        super(src, id, when, modifiers);
-
-        if (id == KEY_TYPED) {
-            if (keyCode != VK_UNDEFINED) {
-                // awt.191=Invalid keyCode for KEY_TYPED event, must be VK_UNDEFINED
-                throw new IllegalArgumentException(Messages.getString("awt.191")); //$NON-NLS-1$
-            }
-            if (keyChar == CHAR_UNDEFINED) {
-                // awt.192=Invalid keyChar for KEY_TYPED event, can't be CHAR_UNDEFINED
-                throw new IllegalArgumentException(Messages.getString("awt.192")); //$NON-NLS-1$
-            }
-        }
-        
-        if ((keyLocation < KEY_LOCATION_UNKNOWN)
-                || (keyLocation > KEY_LOCATION_NUMPAD)) {
-            // awt.297=Invalid keyLocation
-            throw new IllegalArgumentException(Messages.getString("awt.297")); //$NON-NLS-1$
-        }
-
-        this.keyChar = keyChar;
-        this.keyLocation = keyLocation;
-        this.keyCode = keyCode;
-    }
-
-    public int getKeyCode() {
-        return keyCode;
-    }
-
-    public void setKeyCode(int keyCode) {
-        this.keyCode = keyCode;
-    }
-
-    public char getKeyChar() {
-        return keyChar;
-    }
-
-    public void setKeyChar(char keyChar) {
-        this.keyChar = keyChar;
-    }
-
-    public int getKeyLocation() {
-        return keyLocation;
-    }
-
-    @Override
-    @Deprecated
-    public void setModifiers(int modifiers) {
-        super.setModifiers(modifiers);
-    }
-
-    public boolean isActionKey() {
-        return ((keyChar == CHAR_UNDEFINED) && (keyCode != VK_UNDEFINED) &&
-                !((keyCode == VK_ALT) || (keyCode == VK_ALT_GRAPH) ||
-                    (keyCode == VK_CONTROL) || (keyCode == VK_META) || (keyCode == VK_SHIFT)));
-    }
-
-    @Override
-    public String paramString() {
-        /*
-         * The format is based on 1.5 release behavior
-         * which can be revealed by the following code:
-         *
-         * KeyEvent e = new KeyEvent(new Component() {}, 
-         *       KeyEvent.KEY_PRESSED, 0, 
-         *       KeyEvent.CTRL_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK, 
-         *       KeyEvent.VK_A, 'A', KeyEvent.KEY_LOCATION_STANDARD);
-         * System.out.println(e);
-         */
-
-        String idString = null;
-        String locString = null;
-        String paramString = null;
-        String keyCharString = (keyChar == '\n') ?
-                keyCharString = getKeyText(VK_ENTER) : "'" + keyChar + "'"; //$NON-NLS-1$ //$NON-NLS-2$
-
-        switch (id) {
-        case KEY_PRESSED:
-            idString = "KEY_PRESSED"; //$NON-NLS-1$
-            break;
-        case KEY_RELEASED:
-            idString = "KEY_RELEASED"; //$NON-NLS-1$
-            break;
-        case KEY_TYPED:
-            idString = "KEY_TYPED"; //$NON-NLS-1$
-            break;
-        default:
-            idString = "unknown type"; //$NON-NLS-1$
-        }
-
-        switch(keyLocation){
-        case KEY_LOCATION_STANDARD:
-            locString = "KEY_LOCATION_STANDARD"; //$NON-NLS-1$
-            break;
-        case KEY_LOCATION_LEFT:
-            locString = "KEY_LOCATION_LEFT"; //$NON-NLS-1$
-            break;
-        case KEY_LOCATION_RIGHT:
-            locString = "KEY_LOCATION_RIGHT"; //$NON-NLS-1$
-            break;
-        case KEY_LOCATION_NUMPAD:
-            locString = "KEY_LOCATION_NUMPAD"; //$NON-NLS-1$
-            break;
-        case KEY_LOCATION_UNKNOWN:
-            locString = "KEY_LOCATION_UNKNOWN"; //$NON-NLS-1$
-            break;
-        default:
-            locString = "unknown type"; //$NON-NLS-1$
-        }
-
-        paramString = idString + ",keyCode=" + keyCode; //$NON-NLS-1$
-        if (isActionKey()) {
-            paramString += "," + getKeyText(keyCode); //$NON-NLS-1$
-        } else {
-            paramString += ",keyChar=" + keyCharString; //$NON-NLS-1$
-        }
-        if (getModifiersEx() > 0) {
-            paramString += ",modifiers=" + getModifiersExText(getModifiersEx()) + //$NON-NLS-1$
-                    ",extModifiers=" + getModifiersExText(getModifiersEx()); //$NON-NLS-1$
-        }
-        paramString += ",keyLocation=" + locString; //$NON-NLS-1$
-
-        return paramString;
-    }
-
-}
diff --git a/awt/java/awt/event/KeyListener.java b/awt/java/awt/event/KeyListener.java
deleted file mode 100644
index ec144dfe..0000000
--- a/awt/java/awt/event/KeyListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface KeyListener extends EventListener {
-
-    public void keyPressed(KeyEvent e);
-
-    public void keyReleased(KeyEvent e);
-
-    public void keyTyped(KeyEvent e);
-
-}
diff --git a/awt/java/awt/event/MouseAdapter.java b/awt/java/awt/event/MouseAdapter.java
deleted file mode 100644
index dc19173..0000000
--- a/awt/java/awt/event/MouseAdapter.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public abstract class MouseAdapter implements MouseListener {
-
-    public MouseAdapter() {
-    }
-
-    public void mouseClicked(MouseEvent e) {
-    }
-
-    public void mouseEntered(MouseEvent e) {
-    }
-
-    public void mouseExited(MouseEvent e) {
-    }
-
-    public void mousePressed(MouseEvent e) {
-    }
-
-    public void mouseReleased(MouseEvent e) {
-    }
-
-}
diff --git a/awt/java/awt/event/MouseEvent.java b/awt/java/awt/event/MouseEvent.java
deleted file mode 100644
index 2b1fa8b..0000000
--- a/awt/java/awt/event/MouseEvent.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.Component;
-import java.awt.Point;
-import java.awt.Toolkit;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class MouseEvent extends InputEvent {
-
-    private static final long serialVersionUID = -991214153494842848L;
-
-    public static final int MOUSE_FIRST = 500;
-
-    public static final int MOUSE_LAST = 507;
-
-    public static final int MOUSE_CLICKED = 500;
-
-    public static final int MOUSE_PRESSED = 501;
-
-    public static final int MOUSE_RELEASED = 502;
-
-    public static final int MOUSE_MOVED = 503;
-
-    public static final int MOUSE_ENTERED = 504;
-
-    public static final int MOUSE_EXITED = 505;
-
-    public static final int MOUSE_DRAGGED = 506;
-
-    public static final int MOUSE_WHEEL = 507;
-
-    public static final int NOBUTTON = 0;
-
-    public static final int BUTTON1 = 1;
-
-    public static final int BUTTON2 = 2;
-
-    public static final int BUTTON3 = 3;
-
-    private boolean popupTrigger;
-    private int clickCount;
-    private int button;
-    private int x;
-    private int y;
-
-    public static String getMouseModifiersText(int modifiers) {
-        final StringBuffer text = new StringBuffer();
-
-        if ((modifiers & META_MASK) != 0) {
-            text.append(Toolkit.getProperty("AWT.meta", "Meta")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-        if ((modifiers & SHIFT_MASK) != 0) {
-            text.append(Toolkit.getProperty("AWT.shift", "Shift")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-        if ((modifiers & CTRL_MASK) != 0) {
-            text.append(Toolkit.getProperty("AWT.control", "Ctrl")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-        if ((modifiers & ALT_MASK) != 0) {
-            text.append(Toolkit.getProperty("AWT.alt", "Alt")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-        if ((modifiers & ALT_GRAPH_MASK) != 0) {
-            text.append(Toolkit.getProperty("AWT.altGraph", "Alt Graph")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-        if ((modifiers & BUTTON1_MASK) != 0) {
-            text.append(Toolkit.getProperty("AWT.button1", "Button1")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-        if ((modifiers & BUTTON2_MASK) != 0) {
-            text.append(Toolkit.getProperty("AWT.button2", "Button2")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-        if ((modifiers & BUTTON3_MASK) != 0) {
-            text.append(Toolkit.getProperty("AWT.button3", "Button3")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-
-        return text.length() == 0 ? text.toString() : text.substring(0, text
-                .length() - 1);
-    }
-
-    static String addMouseModifiersExText(String text, int modifiersEx) {
-        if ((modifiersEx & InputEvent.BUTTON1_DOWN_MASK) != 0) {
-            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
-                    Toolkit.getProperty("AWT.button1", "Button1"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        if ((modifiersEx & InputEvent.BUTTON2_DOWN_MASK) != 0) {
-            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
-                    Toolkit.getProperty("AWT.button2", "Button2"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        if ((modifiersEx & InputEvent.BUTTON3_DOWN_MASK) != 0) {
-            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
-                    Toolkit.getProperty("AWT.button3", "Button3"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        return text;
-    }
-
-    public MouseEvent(Component source, int id, long when,
-                      int modifiers, int x, int y,
-                      int clickCount, boolean popupTrigger) {
-        this(source, id, when, modifiers, x, y,
-             clickCount, popupTrigger, NOBUTTON);
-    }
-
-    public MouseEvent(Component source, int id, long when,
-                      int modifiers, int x, int y,
-                      int clickCount, boolean popupTrigger, int button) {
-        super(source, id, when, modifiers);
-
-        if ((button != NOBUTTON) && (button != BUTTON1) &&
-                (button != BUTTON2) && (button != BUTTON3)) {
-            // awt.18B=Invalid button value
-            throw new IllegalArgumentException(Messages.getString("awt.18B")); //$NON-NLS-1$
-        }
-
-        this.popupTrigger = popupTrigger;
-        this.clickCount = clickCount;
-        this.button = button;
-        this.x = x;
-        this.y = y;
-    }
-
-    public int getButton() {
-        return button;
-    }
-
-    public int getClickCount() {
-        return clickCount;
-    }
-
-    public Point getPoint() {
-        return new Point(x, y);
-    }
-
-    public int getX() {
-        return x;
-    }
-
-    public int getY() {
-        return y;
-    }
-
-    public boolean isPopupTrigger() {
-        return popupTrigger;
-    }
-
-    public void translatePoint(int x, int y) {
-        this.x += x;
-        this.y += y;
-    }
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * MouseEvent e = new MouseEvent(new Component(){}, 
-         *          MouseEvent.MOUSE_PRESSED, 0, 
-         *          MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.CTRL_DOWN_MASK,
-         *          10, 20, 1, false, MouseEvent.BUTTON1);
-         * System.out.println(e);
-         */
-
-        String idString = null;
-        String paramString = null;
-
-        switch (id) {
-        case MOUSE_MOVED:
-            idString = "MOUSE_MOVED"; //$NON-NLS-1$
-            break;
-        case MOUSE_CLICKED:
-            idString = "MOUSE_CLICKED"; //$NON-NLS-1$
-            break;
-        case MOUSE_PRESSED:
-            idString = "MOUSE_PRESSED"; //$NON-NLS-1$
-            break;
-        case MOUSE_RELEASED:
-            idString = "MOUSE_RELEASED"; //$NON-NLS-1$
-            break;
-        case MOUSE_DRAGGED:
-            idString = "MOUSE_DRAGGED"; //$NON-NLS-1$
-            break;
-        case MOUSE_ENTERED:
-            idString = "MOUSE_ENTERED"; //$NON-NLS-1$
-            break;
-        case MOUSE_EXITED:
-            idString = "MOUSE_EXITED"; //$NON-NLS-1$
-            break;
-        case MOUSE_WHEEL:
-            idString = "MOUSE_WHEEL"; //$NON-NLS-1$
-            break;
-        default:
-            idString = "unknown type"; //$NON-NLS-1$
-        }
-
-        paramString = idString + ",(" + getX() + "," + getY() + ")" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-                ",button=" + button; //$NON-NLS-1$
-        if (getModifiersEx() > 0) {
-            paramString += 
-                    ",modifiers=" + getModifiersExText(getModifiersEx()) + //$NON-NLS-1$
-                    ",extModifiers=" + getModifiersExText(getModifiersEx()); //$NON-NLS-1$
-        }
-        paramString += ",clickCount=" + getClickCount(); //$NON-NLS-1$
-
-        return paramString;
-    }
-
-}
diff --git a/awt/java/awt/event/MouseListener.java b/awt/java/awt/event/MouseListener.java
deleted file mode 100644
index 95879b9..0000000
--- a/awt/java/awt/event/MouseListener.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface MouseListener extends EventListener {
-
-    public void mouseClicked(MouseEvent e);
-
-    public void mouseEntered(MouseEvent e);
-
-    public void mouseExited(MouseEvent e);
-
-    public void mousePressed(MouseEvent e);
-
-    public void mouseReleased(MouseEvent e);
-
-}
diff --git a/awt/java/awt/event/MouseMotionAdapter.java b/awt/java/awt/event/MouseMotionAdapter.java
deleted file mode 100644
index 1ecd0d5..0000000
--- a/awt/java/awt/event/MouseMotionAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public abstract class MouseMotionAdapter implements MouseMotionListener {
-
-    public MouseMotionAdapter() {
-    }
-
-    public void mouseDragged(MouseEvent e) {
-    }
-
-    public void mouseMoved(MouseEvent e) {
-    }
-
-}
diff --git a/awt/java/awt/event/MouseMotionListener.java b/awt/java/awt/event/MouseMotionListener.java
deleted file mode 100644
index e1313c3..0000000
--- a/awt/java/awt/event/MouseMotionListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface MouseMotionListener extends EventListener {
-
-    public void mouseDragged(MouseEvent e);
-
-    public void mouseMoved(MouseEvent e);
-
-}
diff --git a/awt/java/awt/event/MouseWheelEvent.java b/awt/java/awt/event/MouseWheelEvent.java
deleted file mode 100644
index a3ed424..0000000
--- a/awt/java/awt/event/MouseWheelEvent.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.Component;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class MouseWheelEvent extends MouseEvent {
-
-    private static final long serialVersionUID = -9187413581993563929L;
-
-    public static final int WHEEL_UNIT_SCROLL = 0;
-
-    public static final int WHEEL_BLOCK_SCROLL = 1;
-
-    private int wheelRotation;
-    private int scrollAmount;
-    private int scrollType;
-
-    public MouseWheelEvent(Component source, int id, long when, int modifiers,
-            int x, int y, int clickCount, boolean popupTrigger, int scrollType,
-            int scrollAmount, int wheelRotation) {
-        super(source, id, when, modifiers, x, y, clickCount, popupTrigger);
-
-        this.scrollType = scrollType;
-        this.scrollAmount = scrollAmount;
-        this.wheelRotation = wheelRotation;
-    }
-
-    public int getScrollAmount() {
-        return scrollAmount;
-    }
-
-    public int getScrollType() {
-        return scrollType;
-    }
-
-    public int getWheelRotation() {
-        return wheelRotation;
-    }
-
-    public int getUnitsToScroll() {
-        return (scrollAmount * wheelRotation);
-    }
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * MouseWheelEvent e = new MouseWheelEvent(new Component(){}, 
-         *          MouseWheelEvent.MOUSE_WHEEL, 0, 
-         *          MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.CTRL_DOWN_MASK,
-         *          10, 20, 1, false, MouseWheelEvent.WHEEL_UNIT_SCROLL,
-         *          1, 3);
-         * System.out.println(e);
-         */
-
-        String paramString = super.paramString();
-        String typeString = null;
-
-        switch (scrollType) {
-        case WHEEL_UNIT_SCROLL:
-            typeString = "WHEEL_UNIT_SCROLL"; //$NON-NLS-1$
-            break;
-        case WHEEL_BLOCK_SCROLL:
-            typeString = "WHEEL_BLOCK_SCROLL"; //$NON-NLS-1$
-            break;
-        default:
-            typeString = "unknown type"; //$NON-NLS-1$
-        }
-
-        paramString += ",scrollType=" + typeString + //$NON-NLS-1$
-                ",scrollAmount=" + scrollAmount +  //$NON-NLS-1$
-                ",wheelRotation=" + wheelRotation; //$NON-NLS-1$
-
-        return paramString;
-    }
-
-}
diff --git a/awt/java/awt/event/MouseWheelListener.java b/awt/java/awt/event/MouseWheelListener.java
deleted file mode 100644
index 2d6a982..0000000
--- a/awt/java/awt/event/MouseWheelListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface MouseWheelListener extends EventListener {
-
-    public void mouseWheelMoved(MouseWheelEvent e);
-
-}
diff --git a/awt/java/awt/event/PaintEvent.java b/awt/java/awt/event/PaintEvent.java
deleted file mode 100644
index 22ac090..0000000
--- a/awt/java/awt/event/PaintEvent.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.Component;
-import java.awt.Rectangle;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class PaintEvent extends ComponentEvent {
-
-    private static final long serialVersionUID = 1267492026433337593L;
-
-    public static final int PAINT_FIRST = 800;
-
-    public static final int PAINT_LAST = 801;
-
-    public static final int PAINT = 800;
-
-    public static final int UPDATE = 801;
-
-    private Rectangle updateRect;
-
-    public PaintEvent(Component source, int id, Rectangle updateRect) {
-        super(source, id);
-
-        this.updateRect = updateRect;
-    }
-
-    public Rectangle getUpdateRect() {
-        return updateRect;
-    }
-
-    public void setUpdateRect(Rectangle updateRect) {
-        this.updateRect = updateRect;
-    }
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * PaintEvent e = new PaintEvent(new Component(){}, 
-         *          PaintEvent.PAINT, new Rectangle(0, 0, 10, 20)); 
-         * System.out.println(e);
-         */
-
-        String typeString = null;
-
-        switch (id) {
-        case PAINT:
-            typeString = "PAINT"; //$NON-NLS-1$
-            break;
-        case UPDATE:
-            typeString = "UPDATE"; //$NON-NLS-1$
-            break;
-        default:
-            typeString = "unknown type"; //$NON-NLS-1$
-        }
-
-        return typeString + ",updateRect=" + updateRect; //$NON-NLS-1$
-    }
-
-}
diff --git a/awt/java/awt/event/TextEvent.java b/awt/java/awt/event/TextEvent.java
deleted file mode 100644
index 2a690ad..0000000
--- a/awt/java/awt/event/TextEvent.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.awt.AWTEvent;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class TextEvent extends AWTEvent {
-
-    private static final long serialVersionUID = 6269902291250941179L;
-
-    public static final int TEXT_FIRST = 900;
-
-    public static final int TEXT_LAST = 900;
-
-    public static final int TEXT_VALUE_CHANGED = 900;
-
-    public TextEvent(Object src, int id) {
-        super(src, id);
-    }
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * TextEvent e = new TextEvent(new Component(){}, 
-         *          TextEvent.TEXT_VALUE_CHANGED); 
-         * System.out.println(e);
-         */
-
-        return (id == TEXT_VALUE_CHANGED) ? 
-                "TEXT_VALUE_CHANGED" : "unknown type"; //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-}
diff --git a/awt/java/awt/event/TextListener.java b/awt/java/awt/event/TextListener.java
deleted file mode 100644
index 05757c4..0000000
--- a/awt/java/awt/event/TextListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface TextListener extends EventListener {
-
-    public void textValueChanged(TextEvent e);
-
-}
-
diff --git a/awt/java/awt/event/WindowAdapter.java b/awt/java/awt/event/WindowAdapter.java
deleted file mode 100644
index 970aa8d..0000000
--- a/awt/java/awt/event/WindowAdapter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public abstract class WindowAdapter implements WindowListener, WindowStateListener, WindowFocusListener {
-
-    public WindowAdapter() {
-    }
-
-    public void windowActivated(WindowEvent e) {
-    }
-
-    public void windowClosed(WindowEvent e) {
-    }
-
-    public void windowClosing(WindowEvent e) {
-    }
-
-    public void windowDeactivated(WindowEvent e) {
-    }
-
-    public void windowDeiconified(WindowEvent e) {
-    }
-
-    public void windowGainedFocus(WindowEvent e) {
-    }
-
-    public void windowIconified(WindowEvent e) {
-    }
-
-    public void windowLostFocus(WindowEvent e) {
-    }
-
-    public void windowOpened(WindowEvent e) {
-    }
-
-    public void windowStateChanged(WindowEvent e) {
-    }
-
-}
diff --git a/awt/java/awt/event/WindowEvent.java b/awt/java/awt/event/WindowEvent.java
deleted file mode 100644
index 474d2ac..0000000
--- a/awt/java/awt/event/WindowEvent.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-
-//???AWT
-//import java.awt.Window;
-//import java.awt.Frame;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class WindowEvent extends ComponentEvent {
-
-    private static final long serialVersionUID = -1567959133147912127L;
-
-    public static final int WINDOW_FIRST = 200;
-
-    public static final int WINDOW_OPENED = 200;
-
-    public static final int WINDOW_CLOSING = 201;
-
-    public static final int WINDOW_CLOSED = 202;
-
-    public static final int WINDOW_ICONIFIED = 203;
-
-    public static final int WINDOW_DEICONIFIED = 204;
-
-    public static final int WINDOW_ACTIVATED = 205;
-
-    public static final int WINDOW_DEACTIVATED = 206;
-
-    public static final int WINDOW_GAINED_FOCUS = 207;
-
-    public static final int WINDOW_LOST_FOCUS = 208;
-
-    public static final int WINDOW_STATE_CHANGED = 209;
-
-    public static final int WINDOW_LAST = 209;
-
-    //???AWT: private Window oppositeWindow;
-    private int oldState;
-    private int newState;
-
-    //???AWT
-    /*
-    public WindowEvent(Window source, int id) {
-        this(source, id, null);
-    }
-
-    public WindowEvent(Window source, int id, Window opposite) {
-        this(source, id, opposite, Frame.NORMAL, Frame.NORMAL);
-    }
-
-    public WindowEvent(Window source, int id, int oldState, int newState) {
-        this(source, id, null, oldState, newState);
-    }
-
-    public WindowEvent(Window source, int id, Window opposite, 
-                       int oldState, int newState) {
-        super(source, id);
-
-        oppositeWindow = opposite;
-        this.oldState = oldState;
-        this.newState = newState;
-    }
-    */
-    //???AWT: Fake constructor
-    public WindowEvent() {
-        super(null, 0);
-    }
-    
-    public int getNewState() {
-        return newState;
-    }
-
-    public int getOldState() {
-        return oldState;
-    }
-
-    //???AWT
-    /*
-    public Window getOppositeWindow() {
-        return oppositeWindow;
-    }
-
-    public Window getWindow() {
-        return (Window) source;
-    }
-    */
-
-    @Override
-    public String paramString() {
-        /* The format is based on 1.5 release behavior 
-         * which can be revealed by the following code:
-         * 
-         * WindowEvent e = new WindowEvent(new Frame(), 
-         *          WindowEvent.WINDOW_OPENED); 
-         * System.out.println(e);
-         */
-
-        String typeString = null;
-
-        switch (id) {
-        case WINDOW_OPENED:
-            typeString = "WINDOW_OPENED"; //$NON-NLS-1$
-            break;
-        case WINDOW_CLOSING:
-            typeString = "WINDOW_CLOSING"; //$NON-NLS-1$
-            break;
-        case WINDOW_CLOSED:
-            typeString = "WINDOW_CLOSED"; //$NON-NLS-1$
-            break;
-        case WINDOW_ICONIFIED:
-            typeString = "WINDOW_ICONIFIED"; //$NON-NLS-1$
-            break;
-        case WINDOW_DEICONIFIED:
-            typeString = "WINDOW_DEICONIFIED"; //$NON-NLS-1$
-            break;
-        case WINDOW_ACTIVATED:
-            typeString = "WINDOW_ACTIVATED"; //$NON-NLS-1$
-            break;
-        case WINDOW_DEACTIVATED:
-            typeString = "WINDOW_DEACTIVATED"; //$NON-NLS-1$
-            break;
-        case WINDOW_GAINED_FOCUS:
-            typeString = "WINDOW_GAINED_FOCUS"; //$NON-NLS-1$
-            break;
-        case WINDOW_LOST_FOCUS:
-            typeString = "WINDOW_LOST_FOCUS"; //$NON-NLS-1$
-            break;
-        case WINDOW_STATE_CHANGED:
-            typeString = "WINDOW_STATE_CHANGED"; //$NON-NLS-1$
-            break;
-        default:
-            typeString = "unknown type"; //$NON-NLS-1$
-        }
-
-        //???AWT
-        /*
-        return typeString + ",opposite=" + oppositeWindow + //$NON-NLS-1$
-                ",oldState=" + oldState + ",newState=" + newState; //$NON-NLS-1$ //$NON-NLS-2$
-        */
-        return typeString;
-    }
-
-}
diff --git a/awt/java/awt/event/WindowFocusListener.java b/awt/java/awt/event/WindowFocusListener.java
deleted file mode 100644
index 528459f..0000000
--- a/awt/java/awt/event/WindowFocusListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface WindowFocusListener extends EventListener {
-
-    public void windowGainedFocus(WindowEvent e);
-
-    public void windowLostFocus(WindowEvent e);
-
-}
diff --git a/awt/java/awt/event/WindowListener.java b/awt/java/awt/event/WindowListener.java
deleted file mode 100644
index 31bd547..0000000
--- a/awt/java/awt/event/WindowListener.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface WindowListener extends EventListener {
-
-    public void windowActivated(WindowEvent e);
-
-    public void windowClosed(WindowEvent e);
-
-    public void windowClosing(WindowEvent e);
-
-    public void windowDeactivated(WindowEvent e);
-
-    public void windowDeiconified(WindowEvent e);
-
-    public void windowIconified(WindowEvent e);
-
-    public void windowOpened(WindowEvent e);
-
-}
diff --git a/awt/java/awt/event/WindowStateListener.java b/awt/java/awt/event/WindowStateListener.java
deleted file mode 100644
index ba14d9e..0000000
--- a/awt/java/awt/event/WindowStateListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov
- * @version $Revision$
- */
-package java.awt.event;
-
-import java.util.EventListener;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface WindowStateListener extends EventListener {
-
-    public void windowStateChanged(WindowEvent e);
-
-}
-
diff --git a/awt/java/awt/font/FontRenderContext.java b/awt/java/awt/font/FontRenderContext.java
deleted file mode 100644
index d7de00f..0000000
--- a/awt/java/awt/font/FontRenderContext.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package java.awt.font;
-
-import java.awt.geom.AffineTransform;
-
-/**
- * The FontRenderContext class contains the information about text measurement.
- * Anti-aliasing and fractional-metrics modes are defined by an application and
- * affect the size of a character.
- * 
- * @since Android 1.0
- */
-public class FontRenderContext {
-
-    // Affine transform of this mode
-    /**
-     * The transform.
-     */
-    private AffineTransform transform;
-
-    // Is the anti-aliased mode used
-    /**
-     * The anti aliased.
-     */
-    private boolean fAntiAliased;
-
-    // Is the fractional metrics used
-    /**
-     * The fractional metrics.
-     */
-    private boolean fFractionalMetrics;
-
-
-    /**
-     * Instantiates a new FontRenderContext object with the specified
-     * AffineTransform, anti-aliasing and fractional metrics flags.
-     * 
-     * @param trans
-     *            the AffineTransform.
-     * @param antiAliased
-     *            the anti-aliasing flag.
-     * @param usesFractionalMetrics
-     *            the fractional metrics flag.
-     */
-    public FontRenderContext(AffineTransform trans, boolean antiAliased, 
-            boolean usesFractionalMetrics) {
-        if (trans != null){
-            transform = new AffineTransform(trans);
-        }
-        fAntiAliased = antiAliased;
-        fFractionalMetrics = usesFractionalMetrics;
-    }
-
-    /**
-     * Instantiates a new FontRenderContext object.
-     */
-    protected FontRenderContext() {
-    }
-
-    /**
-     * Compares the specified Object with current FontRenderContext object.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if the specified Object is equal to current
-     *         FontRenderContext object.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-
-        if (obj != null) {
-            try {
-                return equals((FontRenderContext) obj);
-            } catch (ClassCastException e) {
-                return false;
-            }
-        }
-        return false;
-
-    }
-
-    /**
-     * Gets the transform which is used for scaling typographical points to
-     * pixels in this FontRenderContext.
-     * 
-     * @return the AffineTransform which is used for scaling typographical
-     *         points to pixels in this FontRenderContext.
-     */
-    public AffineTransform getTransform() {
-        if (transform != null){
-            return new AffineTransform(transform);
-        }
-        return new AffineTransform();
-    }
-
-    /**
-     * Compares the specified FontRenderContext object with current
-     * FontRenderContext.
-     * 
-     * @param frc
-     *            the FontRenderContext object to be compared.
-     * @return true, if the specified FontRenderContext object is equal to
-     *         current FontRenderContext.
-     */
-    public boolean equals(FontRenderContext frc) {
-        if (this == frc){
-            return true;
-        }
-
-        if (frc == null){
-            return false;
-        }
-
-        if (!frc.getTransform().equals(this.getTransform()) &&
-            !frc.isAntiAliased() == this.fAntiAliased &&
-            !frc.usesFractionalMetrics() == this.fFractionalMetrics){
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Returns true if the text fractional metrics are used in this
-     * FontRenderContext.
-     * 
-     * @return true, if the text fractional metrics are used in this
-     *         FontRenderContext, false otherwise.
-     */
-    public boolean usesFractionalMetrics() {
-        return this.fFractionalMetrics;
-    }
-
-    /**
-     * Returns true if anti-aliasing is used in this FontRenderContext.
-     * 
-     * @return true, if is anti-aliasing is used in this FontRenderContext,
-     *         false otherwise.
-     */
-    public boolean isAntiAliased() {
-        return this.fAntiAliased;
-    }
-
-    /**
-     * Returns hash code of the FontRenderContext object.
-     * 
-     * @return the hash code of the FontRenderContext object.
-     */
-    @Override
-    public int hashCode() {
-        return this.getTransform().hashCode() ^
-                new Boolean(this.fFractionalMetrics).hashCode() ^
-                new Boolean(this.fAntiAliased).hashCode();
-    }
-
-}
-
diff --git a/awt/java/awt/font/GlyphJustificationInfo.java b/awt/java/awt/font/GlyphJustificationInfo.java
deleted file mode 100644
index b03de0a..0000000
--- a/awt/java/awt/font/GlyphJustificationInfo.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The GlyphJustificationInfo class provides information about the glyph's
- * justification properties. There are four justification properties: weight,
- * priority, absorb, and limit.
- * <p>
- * There are two sets of metrics: growing and shrinking. Growing metrics are
- * used when the glyphs are to be spread apart to fit a larger width. Shrinking
- * metrics are used when the glyphs are to be moved together to fit a smaller
- * width.
- * </p>
- * 
- * @since Android 1.0
- */
-public final class GlyphJustificationInfo {
-
-    /**
-     * The Constant PRIORITY_KASHIDA indicates the highest justification
-     * priority.
-     */
-    public static final int PRIORITY_KASHIDA = 0;
-
-    /**
-     * The Constant PRIORITY_WHITESPACE indicates the second highest
-     * justification priority.
-     */
-    public static final int PRIORITY_WHITESPACE = 1;
-
-    /**
-     * The Constant PRIORITY_INTERCHAR indicates the second lowest justification
-     * priority.
-     */
-    public static final int PRIORITY_INTERCHAR = 2;
-
-    /**
-     * The Constant PRIORITY_NONE indicates the lowest justification priority.
-     */
-    public static final int PRIORITY_NONE = 3;
-
-    /**
-     * The grow absorb flag indicates if this glyph absorbs all extra space at
-     * this and lower priority levels when it grows.
-     */
-    public final boolean growAbsorb;
-
-    /**
-     * The grow left limit value represents the maximum value by which the left
-     * side of this glyph grows.
-     */
-    public final float growLeftLimit;
-
-    /**
-     * The grow right limit value repesents the maximum value by which the right
-     * side of this glyph grows.
-     */
-    public final float growRightLimit;
-
-    /**
-     * The grow priority value represents the priority level of this glyph as it
-     * is growing.
-     */
-    public final int growPriority;
-
-    /**
-     * The shrink absorb fleg indicates this glyph absorbs all remaining
-     * shrinkage at this and lower priority levels as it shrinks.
-     */
-    public final boolean shrinkAbsorb;
-
-    /**
-     * The shrink left limit value represents the maximum value by which the
-     * left side of this glyph shrinks.
-     */
-    public final float shrinkLeftLimit;
-
-    /**
-     * The shrink right limit value represents the maximum value by which the
-     * right side of this glyph shrinks.
-     */
-    public final float shrinkRightLimit;
-
-    /**
-     * The shrink priority represents the glyth's priority level as it is
-     * shrinking.
-     */
-    public final int shrinkPriority;
-
-    /**
-     * The weight of the glyph.
-     */
-    public final float weight;
-
-    /**
-     * Instantiates a new GlyphJustificationInfo object which contains glyph's
-     * justification properties.
-     * 
-     * @param weight
-     *            the weight of glyph.
-     * @param growAbsorb
-     *            indicates if this glyph contais all space at this priority and
-     *            lower priority levels when it grows.
-     * @param growPriority
-     *            indicates the priority level of this glyph when it grows.
-     * @param growLeftLimit
-     *            indicates the maximum value of which the left side of this
-     *            glyph can grow.
-     * @param growRightLimit
-     *            the maximum value of which the right side of this glyph can
-     *            grow.
-     * @param shrinkAbsorb
-     *            indicates if this glyph contains all remaining shrinkage at
-     *            this and lower priority levels when it shrinks.
-     * @param shrinkPriority
-     *            indicates the glyph's priority level when it shrinks.
-     * @param shrinkLeftLimit
-     *            indicates the maximum value of which the left side of this
-     *            glyph can shrink.
-     * @param shrinkRightLimit
-     *            indicates the maximum amount by which the right side of this
-     *            glyph can shrink.
-     */
-    public GlyphJustificationInfo(float weight, boolean growAbsorb, int growPriority,
-            float growLeftLimit, float growRightLimit, boolean shrinkAbsorb, int shrinkPriority,
-            float shrinkLeftLimit, float shrinkRightLimit) {
-
-        if (weight < 0) {
-            // awt.19C=weight must be a positive number
-            throw new IllegalArgumentException(Messages.getString("awt.19C")); //$NON-NLS-1$
-        }
-        this.weight = weight;
-
-        if (growLeftLimit < 0) {
-            // awt.19D=growLeftLimit must be a positive number
-            throw new IllegalArgumentException(Messages.getString("awt.19D")); //$NON-NLS-1$
-        }
-        this.growLeftLimit = growLeftLimit;
-
-        if (growRightLimit < 0) {
-            // awt.19E=growRightLimit must be a positive number
-            throw new IllegalArgumentException(Messages.getString("awt.19E")); //$NON-NLS-1$
-        }
-        this.growRightLimit = growRightLimit;
-
-        if ((shrinkPriority < 0) || (shrinkPriority > PRIORITY_NONE)) {
-            // awt.19F=incorrect value for shrinkPriority, more than
-            // PRIORITY_NONE or less than PRIORITY_KASHIDA value
-            throw new IllegalArgumentException(Messages.getString("awt.19F")); //$NON-NLS-1$
-        }
-        this.shrinkPriority = shrinkPriority;
-
-        if ((growPriority < 0) || (growPriority > PRIORITY_NONE)) {
-            // awt.200=incorrect value for growPriority, more than PRIORITY_NONE
-            // or less than PRIORITY_KASHIDA value
-            throw new IllegalArgumentException(Messages.getString("awt.200")); //$NON-NLS-1$
-        }
-        this.growPriority = growPriority;
-
-        if (shrinkLeftLimit < 0) {
-            // awt.201=shrinkLeftLimit must be a positive number
-            throw new IllegalArgumentException(Messages.getString("awt.201")); //$NON-NLS-1$
-        }
-        this.shrinkLeftLimit = shrinkLeftLimit;
-
-        if (shrinkRightLimit < 0) {
-            // awt.202=shrinkRightLimit must be a positive number
-            throw new IllegalArgumentException(Messages.getString("awt.202")); //$NON-NLS-1$
-        }
-        this.shrinkRightLimit = shrinkRightLimit;
-
-        this.shrinkAbsorb = shrinkAbsorb;
-        this.growAbsorb = growAbsorb;
-    }
-}
diff --git a/awt/java/awt/font/GlyphMetrics.java b/awt/java/awt/font/GlyphMetrics.java
deleted file mode 100644
index 28717223..0000000
--- a/awt/java/awt/font/GlyphMetrics.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import java.awt.geom.Rectangle2D;
-
-/**
- * The GlyphMetrics class provides information about the size and shape of a
- * single glyph. Each glyph has information to specify whether its baseline is
- * horizontal or vertical as well as information on how it interacts with other
- * characters in a text, given as one of the following types: STANDARD,
- * LIGATURE, COMBINING, or COMPONENT.
- * 
- * @since Android 1.0
- */
-public final class GlyphMetrics {
-
-    // advance width of the glyph character cell
-    /**
-     * The advance x.
-     */
-    private float advanceX;
-
-    // advance height of the glyph character cell
-    /**
-     * The advance y.
-     */
-    private float advanceY;
-
-    // flag if the glyph horizontal
-    /**
-     * The horizontal.
-     */
-    private boolean horizontal;
-
-    // glyph type code
-    /**
-     * The glyph type.
-     */
-    private byte glyphType;
-
-    // bounding box for outline of the glyph
-    /**
-     * The bounds.
-     */
-    private Rectangle2D.Float bounds;
-
-    /**
-     * The Constant STANDARD indicates a glyph that represents a single
-     * character.
-     */
-    public static final byte STANDARD = 0;
-
-    /**
-     * The Constant LIGATURE indicates a glyph that represents multiple
-     * characters as a ligature.
-     */
-    public static final byte LIGATURE = 1;
-
-    /**
-     * The Constant COMBINING indicates a glyph which has no caret position
-     * between glyphs (for example umlaut).
-     */
-    public static final byte COMBINING = 2;
-
-    /**
-     * The Constant COMPONENT indicates a glyph with no corresponding character
-     * in the backing store.
-     */
-    public static final byte COMPONENT = 3;
-
-    /**
-     * The Constant WHITESPACE indicates a glyph without visual representation.
-     */
-    public static final byte WHITESPACE = 4;
-
-    /**
-     * Instantiates a new GlyphMetrics object with the specified parameters.
-     * 
-     * @param horizontal
-     *            specifies if metrics are for a horizontal baseline (true
-     *            value), or a vertical baseline (false value).
-     * @param advanceX
-     *            the X component of the glyph's advance.
-     * @param advanceY
-     *            the Y component of the glyph's advance.
-     * @param bounds
-     *            the glyph's bounds.
-     * @param glyphType
-     *            the glyph's type.
-     */
-    public GlyphMetrics(boolean horizontal, float advanceX, float advanceY, Rectangle2D bounds,
-            byte glyphType) {
-        this.horizontal = horizontal;
-        this.advanceX = advanceX;
-        this.advanceY = advanceY;
-
-        this.bounds = new Rectangle2D.Float();
-        this.bounds.setRect(bounds);
-
-        this.glyphType = glyphType;
-    }
-
-    /**
-     * Instantiates a new horizontal GlyphMetrics with the specified parameters.
-     * 
-     * @param advanceX
-     *            the X component of the glyph's advance.
-     * @param bounds
-     *            the glyph's bounds.
-     * @param glyphType
-     *            the glyph's type.
-     */
-    public GlyphMetrics(float advanceX, Rectangle2D bounds, byte glyphType) {
-        this.advanceX = advanceX;
-        this.advanceY = 0;
-
-        this.horizontal = true;
-
-        this.bounds = new Rectangle2D.Float();
-        this.bounds.setRect(bounds);
-
-        this.glyphType = glyphType;
-    }
-
-    /**
-     * Gets the glyph's bounds.
-     * 
-     * @return glyph's bounds.
-     */
-    public Rectangle2D getBounds2D() {
-        return (Rectangle2D.Float)this.bounds.clone();
-    }
-
-    /**
-     * Checks if this glyph is whitespace or not.
-     * 
-     * @return true, if this glyph is whitespace, false otherwise.
-     */
-    public boolean isWhitespace() {
-        return ((this.glyphType & 4) == WHITESPACE);
-    }
-
-    /**
-     * Checks if this glyph is standard or not.
-     * 
-     * @return true, if this glyph is standard, false otherwise.
-     */
-    public boolean isStandard() {
-        return ((this.glyphType & 3) == STANDARD);
-    }
-
-    /**
-     * Checks if this glyph is ligature or not.
-     * 
-     * @return true, if this glyph is ligature, false otherwise.
-     */
-    public boolean isLigature() {
-        return ((this.glyphType & 3) == LIGATURE);
-    }
-
-    /**
-     * Checks if this glyph is component or not.
-     * 
-     * @return true, if this glyph is component, false otherwise.
-     */
-    public boolean isComponent() {
-        return ((this.glyphType & 3) == COMPONENT);
-    }
-
-    /**
-     * Checks if this glyph is combining or not.
-     * 
-     * @return true, if this glyph is combining, false otherwise.
-     */
-    public boolean isCombining() {
-        return ((this.glyphType & 3) == COMBINING);
-    }
-
-    /**
-     * Gets the glyph's type.
-     * 
-     * @return the glyph's type.
-     */
-    public int getType() {
-        return this.glyphType;
-    }
-
-    /**
-     * Gets the distance from the right (for horizontal) or bottom (for
-     * vertical) of the glyph bounds to the advance.
-     * 
-     * @return the distance from the right (for horizontal) or bottom (for
-     *         vertical) of the glyph bounds to the advance.
-     */
-    public float getRSB() {
-        if (this.horizontal) {
-            return this.advanceX - this.bounds.x - (float)this.bounds.getWidth();
-        }
-        return this.advanceY - this.bounds.y - (float)this.bounds.getHeight();
-    }
-
-    /**
-     * Gets the distance from 0, 0 to the left (for horizontal) or top (for
-     * vertical) of the glyph bounds.
-     * 
-     * @return the distance from 0, 0 to the left (for horizontal) or top (for
-     *         vertical) of the glyph bounds.
-     */
-    public float getLSB() {
-        if (this.horizontal) {
-            return this.bounds.x;
-        }
-        return this.bounds.y;
-    }
-
-    /**
-     * Gets the Y component of the glyph's advance.
-     * 
-     * @return the Y component of the glyph's advance.
-     */
-    public float getAdvanceY() {
-        return this.advanceY;
-    }
-
-    /**
-     * Gets the X component of the glyph's advance.
-     * 
-     * @return the X component of the glyph's advance.
-     */
-    public float getAdvanceX() {
-        return this.advanceX;
-    }
-
-    /**
-     * Gets the glyph's advance along the baseline.
-     * 
-     * @return the glyph's advance.
-     */
-    public float getAdvance() {
-        if (this.horizontal) {
-            return this.advanceX;
-        }
-        return this.advanceY;
-    }
-
-}
diff --git a/awt/java/awt/font/GlyphVector.java b/awt/java/awt/font/GlyphVector.java
deleted file mode 100644
index a72b774..0000000
--- a/awt/java/awt/font/GlyphVector.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import java.awt.Font;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphJustificationInfo;
-import java.awt.font.GlyphMetrics;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-
-/**
- * The GlyphVector class contains a collection of glyphs with geometric
- * information and each glyph's location. Each GlyphVector can be associated
- * with only one Font. GlyphVector contains the following properties for each
- * glyph:
- * <ul>
- * <li>the glyph position;</li>
- * <li>the transform of the glyph;</li>
- * <li>the metrics of the glyph in the context of the GlyphVector.</li>
- * </ul>
- * 
- * @since Android 1.0
- */
-public abstract class GlyphVector implements Cloneable {
-
-    /**
-     * The Constant FLAG_HAS_TRANSFORMS indicates that this GlyphVector has
-     * per-glyph transforms.
-     */
-    public static final int FLAG_HAS_TRANSFORMS = 1;
-
-    /**
-     * The Constant FLAG_HAS_POSITION_ADJUSTMENTS indicates that the GlyphVector
-     * has per-glyph position adjustments.
-     */
-    public static final int FLAG_HAS_POSITION_ADJUSTMENTS = 2;
-
-    /**
-     * The Constant FLAG_RUN_RTL indicates that this GlyphVector has a right to
-     * left run direction.
-     */
-    public static final int FLAG_RUN_RTL = 4;
-
-    /**
-     * The Constant FLAG_COMPLEX_GLYPHS indicates that this GlyphVector has a
-     * complex glyph to char mapping.
-     */
-    public static final int FLAG_COMPLEX_GLYPHS = 8;
-
-    /**
-     * The Constant FLAG_MASK indicates a mask for supported flags from
-     * getLayoutFlags.
-     */
-    public static final int FLAG_MASK = 15; // (|) mask of other flags
-
-    /**
-     * Instantiates a new GlyphVector.
-     */
-    public GlyphVector() {
-    }
-
-    /**
-     * Gets the pixel bounds of the GlyphVector when rendered at the specified
-     * location with the specified FontRenderContext.
-     * 
-     * @param frc
-     *            the FontRenderContext.
-     * @param x
-     *            the X coordinate of the GlyphVector's location.
-     * @param y
-     *            the Y coordinate of the GlyphVector's location.
-     * @return the pixel bounds
-     */
-    public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
-        // default implementation - integer Rectangle, that encloses visual
-        // bounds rectangle
-        Rectangle2D visualRect = getVisualBounds();
-
-        int minX = (int)Math.floor(visualRect.getMinX() + x);
-        int minY = (int)Math.floor(visualRect.getMinY() + y);
-        int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
-        int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
-
-        return new Rectangle(minX, minY, width, height);
-    }
-
-    /**
-     * Gets the pixel bounds of the glyph with the specified index in this
-     * GlyphVector which is rendered with the specified FontRenderContext at the
-     * specified location.
-     * 
-     * @param index
-     *            the glyph index in this GlyphVector.
-     * @param frc
-     *            the FontRenderContext.
-     * @param x
-     *            the X coordinate of the GlyphVector's location.
-     * @param y
-     *            the Y coordinate of the GlyphVector's location.
-     * @return a Rectangle bounds.
-     */
-    public Rectangle getGlyphPixelBounds(int index, FontRenderContext frc, float x, float y) {
-        Rectangle2D visualRect = getGlyphVisualBounds(index).getBounds2D();
-
-        int minX = (int)Math.floor(visualRect.getMinX() + x);
-        int minY = (int)Math.floor(visualRect.getMinY() + y);
-        int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
-        int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
-
-        return new Rectangle(minX, minY, width, height);
-    }
-
-    /**
-     * Gets the visual bounds of the GlyphVector.
-     * 
-     * @return the visual bounds of the GlyphVector.
-     */
-    public abstract Rectangle2D getVisualBounds();
-
-    /**
-     * Gets the logical bounds of the GlyphVector.
-     * 
-     * @return the logical bounds of the GlyphVector.
-     */
-    public abstract Rectangle2D getLogicalBounds();
-
-    /**
-     * Sets the position of the specified glyph in this GlyphVector.
-     * 
-     * @param glyphIndex
-     *            the glyph index in this GlyphVector.
-     * @param newPos
-     *            the new position of the glyph at the specified glyphIndex.
-     */
-    public abstract void setGlyphPosition(int glyphIndex, Point2D newPos);
-
-    /**
-     * Gets the position of the specified glyph in this GlyphVector.
-     * 
-     * @param glyphIndex
-     *            the glyph index in this GlyphVector.
-     * @return the position of the specified glyph in this GlyphVector.
-     */
-    public abstract Point2D getGlyphPosition(int glyphIndex);
-
-    /**
-     * Sets the affine transform to a glyph with the specified index in this
-     * GlyphVector.
-     * 
-     * @param glyphIndex
-     *            the glyth index in this GlyphVector.
-     * @param trans
-     *            the AffineTransform to be assigned to the specified glyph.
-     */
-    public abstract void setGlyphTransform(int glyphIndex, AffineTransform trans);
-
-    /**
-     * Gets the transform of the specified glyph in this GlyphVector.
-     * 
-     * @param glyphIndex
-     *            the glyph index in this GlyphVector.
-     * @return the new transform of the glyph.
-     */
-    public abstract AffineTransform getGlyphTransform(int glyphIndex);
-
-    /**
-     * Compares this GlyphVector with the specified GlyphVector objects.
-     * 
-     * @param glyphVector
-     *            the GlyphVector object to be compared.
-     * @return true, if this GlyphVector is equal to the specified GlyphVector
-     *         object, false otherwise.
-     */
-    public abstract boolean equals(GlyphVector glyphVector);
-
-    /**
-     * Gets the metrics of the glyph with the specified index in this
-     * GlyphVector.
-     * 
-     * @param glyphIndex
-     *            index in this GlyphVector.
-     * @return the metrics of the glyph with the specified index in this
-     *         GlyphVector.
-     */
-    public abstract GlyphMetrics getGlyphMetrics(int glyphIndex);
-
-    /**
-     * Gets the justification information of the glyph whose index is specified.
-     * 
-     * @param glyphIndex
-     *            the glyph index.
-     * @return the GlyphJustificationInfo for the specified glyph.
-     */
-    public abstract GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex);
-
-    /**
-     * Gets the FontRenderContext of this GlyphVector.
-     * 
-     * @return the FontRenderContext of this GlyphVector.
-     */
-    public abstract FontRenderContext getFontRenderContext();
-
-    /**
-     * Gets a Shape object which defines the visual representation of the
-     * specified glyph in this GlyphVector, translated a distance of x in the X
-     * direction and y in the Y direction.
-     * 
-     * @param glyphIndex
-     *            the glyth index in this GlyphVector.
-     * @param x
-     *            the distance in the X direction to translate the shape object
-     *            before returning it.
-     * @param y
-     *            the distance in the Y direction to translate the shape object
-     *            before returning it.
-     * @return a Shape object which represents the visual representation of the
-     *         specified glyph in this GlyphVector - glyph outline.
-     */
-    public Shape getGlyphOutline(int glyphIndex, float x, float y) {
-        Shape initialShape = getGlyphOutline(glyphIndex);
-        AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
-        return trans.createTransformedShape(initialShape);
-    }
-
-    /**
-     * Gets the visual bounds of the specified glyph in the GlyphVector.
-     * 
-     * @param glyphIndex
-     *            the glyph index in this GlyphVector.
-     * @return the glyph visual bounds of the glyph with the specified index in
-     *         the GlyphVector.
-     */
-    public abstract Shape getGlyphVisualBounds(int glyphIndex);
-
-    /**
-     * Gets a Shape object which defines the visual representation of the
-     * specified glyph in this GlyphVector.
-     * 
-     * @param glyphIndex
-     *            the glyth index in this GlyphVector.
-     * @return a Shape object which represents the visual representation of the
-     *         specified glyph in this GlyphVector - glyph outline.
-     */
-    public abstract Shape getGlyphOutline(int glyphIndex);
-
-    /**
-     * Gets the logical bounds of the specified glyph in the GlyphVector.
-     * 
-     * @param glyphIndex
-     *            the index in this GlyphVector of the glyph from which to
-     *            retrieve its logical bounds
-     * @return the logical bounds of the specified glyph in the GlyphVector.
-     */
-    public abstract Shape getGlyphLogicalBounds(int glyphIndex);
-
-    /**
-     * Gets the visual representation of this GlyphVector rendered in x, y
-     * location as a Shape object.
-     * 
-     * @param x
-     *            the x coordinate of the GlyphVector.
-     * @param y
-     *            the y coordinate of the GlyphVector.
-     * @return the visual representation of this GlyphVector as a Shape object.
-     */
-    public abstract Shape getOutline(float x, float y);
-
-    /**
-     * Gets the visual representation of this GlyphVector as a Shape object.
-     * 
-     * @return the visual representation of this GlyphVector as a Shape object.
-     */
-    public abstract Shape getOutline();
-
-    /**
-     * Gets the font of this GlyphVector.
-     * 
-     * @return the font of this GlyphVector.
-     */
-    public abstract Font getFont();
-
-    /**
-     * Gets an array of the glyph codes of the specified glyphs.
-     * 
-     * @param beginGlyphIndex
-     *            the index into this GlyphVector at which to start retrieving
-     *            glyph codes.
-     * @param numEntries
-     *            the number of glyph codes.
-     * @param codeReturn
-     *            the array into which the resulting glyphcodes will be written.
-     * @return the array of the glyph codes.
-     */
-    public abstract int[] getGlyphCodes(int beginGlyphIndex, int numEntries, int[] codeReturn);
-
-    /**
-     * Gets an array of the character indices of the specified glyphs.
-     * 
-     * @param beginGlyphIndex
-     *            the index of the first glyph to return information for.
-     * @param numEntries
-     *            the number of glyph indices to return.
-     * @param codeReturn
-     *            the array into which the resulting character indices will be
-     *            written.
-     * @return an array of character indices for the specifies glyphs.
-     */
-    public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries, int[] codeReturn) {
-        if (codeReturn == null) {
-            codeReturn = new int[numEntries];
-        }
-
-        for (int i = 0; i < numEntries; i++) {
-            codeReturn[i] = getGlyphCharIndex(i + beginGlyphIndex);
-        }
-        return codeReturn;
-    }
-
-    /**
-     * Gets an array of the positions of the specified glyphs in this
-     * GlyphVector.
-     * 
-     * @param beginGlyphIndex
-     *            the index of the first glyph to return information for.
-     * @param numEntries
-     *            the number of glyphs to return information for.
-     * @param positionReturn
-     *            the array where the result will be stored.
-     * @return an array of glyph positions.
-     */
-    public abstract float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
-            float[] positionReturn);
-
-    /**
-     * Gets the glyph code of the specified glyph.
-     * 
-     * @param glyphIndex
-     *            the index in this GlyphVector which corresponds to the glyph
-     *            from which to retrieve the glyphcode.
-     * @return the glyphcode of the specified glyph.
-     */
-    public abstract int getGlyphCode(int glyphIndex);
-
-    /**
-     * Gets the first logical character's index of the specified glyph.
-     * 
-     * @param glyphIndex
-     *            the glyph index.
-     * @return the the first logical character's index.
-     */
-    public int getGlyphCharIndex(int glyphIndex) {
-        // default implemetation one-to-one
-        return glyphIndex;
-    }
-
-    /**
-     * Sets default layout to this GlyphVector.
-     */
-    public abstract void performDefaultLayout();
-
-    /**
-     * Gets the number of glyphs in the GlyphVector.
-     * 
-     * @return the number of glyphs in the GlyphVector.
-     */
-    public abstract int getNumGlyphs();
-
-    /**
-     * Gets flags which describe the global state of the GlyphVector. The
-     * default implementation returns 0.
-     * 
-     * @return the layout flags
-     */
-    public int getLayoutFlags() {
-        // default implementation - returned value is 0
-        return 0;
-    }
-
-}
diff --git a/awt/java/awt/font/GraphicAttribute.java b/awt/java/awt/font/GraphicAttribute.java
deleted file mode 100644
index 8480e0f..0000000
--- a/awt/java/awt/font/GraphicAttribute.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The GraphicAttribute abstract class provides an opportunity to insert
- * graphical elements in printed text.
- * 
- * @since Android 1.0
- */
-public abstract class GraphicAttribute {
-
-    /**
-     * The Constant TOP_ALIGNMENT indicates using the top line to calculate
-     * placement of graphics.
-     */
-    public static final int TOP_ALIGNMENT = -1;
-
-    /**
-     * The Constant BOTTOM_ALIGNMENT indicates using the bottom line to
-     * calculate placement of graphics.
-     */
-    public static final int BOTTOM_ALIGNMENT = -2;
-
-    /**
-     * The Constant ROMAN_BASELINE indicates the placement of the roman baseline
-     * with respect to the graphics origin.
-     */
-    public static final int ROMAN_BASELINE = 0;
-
-    /**
-     * The Constant CENTER_BASELINE indicates the placement of the center
-     * baseline with respect to the graphics origin.
-     */
-    public static final int CENTER_BASELINE = 1;
-
-    /**
-     * The Constant HANGING_BASELINE indicates the placement of the hanging
-     * baseline with respect to the graphics origin.
-     */
-    public static final int HANGING_BASELINE = 2;
-
-    // the alignment of this GraphicAttribute
-    /**
-     * The alignment.
-     */
-    private int alignment;
-
-    /**
-     * Instantiates a new graphic attribute with the specified alignment.
-     * 
-     * @param align
-     *            the specified alignment.
-     */
-    protected GraphicAttribute(int align) {
-        if ((align < BOTTOM_ALIGNMENT) || (align > HANGING_BASELINE)) {
-            // awt.198=Illegal alignment argument
-            throw new IllegalArgumentException(Messages.getString("awt.198")); //$NON-NLS-1$
-        }
-        this.alignment = align;
-    }
-
-    /**
-     * Draws the GraphicAttribute at the specified location.
-     * 
-     * @param graphics
-     *            the Graphics.
-     * @param x
-     *            the X coordinate of GraphicAttribute location.
-     * @param y
-     *            the Y coordinate of GraphicAttribute location.
-     */
-    public abstract void draw(Graphics2D graphics, float x, float y);
-
-    /**
-     * Gets the GraphicAttribute's advance. It's the distance from the point at
-     * which the graphic is rendered and the point where the next character or
-     * graphic is rendered.
-     * 
-     * @return the GraphicAttribute's advance.
-     */
-    public abstract float getAdvance();
-
-    /**
-     * Gets the alignment of this GraphicAttribute.
-     * 
-     * @return the alignment of this GraphicAttribute.
-     */
-    public final int getAlignment() {
-        return this.alignment;
-    }
-
-    /**
-     * Gets the ascent of this GraphicAttribute.
-     * 
-     * @return the ascent of this GraphicAttribute.
-     */
-    public abstract float getAscent();
-
-    /**
-     * Gets the bounds of this GraphicAttribute.
-     * 
-     * @return the bounds of this GraphicAttribute.
-     */
-    public Rectangle2D getBounds() {
-        float ascent = getAscent();
-        float advance = getAdvance();
-        float descent = getDescent();
-
-        // Default implementation - see API documentation.
-        return new Rectangle2D.Float(0, -ascent, advance, ascent + descent);
-    }
-
-    /**
-     * Gets the descent of this GraphicAttribute.
-     * 
-     * @return the descent of this GraphicAttribute.
-     */
-    public abstract float getDescent();
-
-    /**
-     * Gets the GlyphJustificationInfo of this GraphicAttribute.
-     * 
-     * @return the GlyphJustificationInfo of this GraphicAttribute.
-     */
-    public GlyphJustificationInfo getJustificationInfo() {
-
-        /*
-         * Default implementation. Since documentation doesn't describe default
-         * values, they were calculated based on 1.5 release behavior and can be
-         * obtained using next test sample: // Create GraphicAttribute class
-         * implementation public class MyGraphicAttribute extends
-         * GraphicAttribute { protected MyGraphicAttribute(int align) {
-         * super(align); } public float getDescent() { return 0; } public float
-         * getAdvance() { return 1; } public void draw(Graphics2D g2, float x,
-         * float y) { } public float getAscent() { return 0; } }
-         * MyGraphicAttribute myGA = gat.new MyGraphicAttribute(0); // print
-         * justification parameters
-         * System.out.println(myGA.getJustificationInfo().growAbsorb);
-         * System.out.println(myGA.getJustificationInfo().shrinkAbsorb);
-         * System.out.println(myGA.getJustificationInfo().growLeftLimit);
-         * System.out.println(myGA.getJustificationInfo().growPriority);
-         * System.out.println(myGA.getJustificationInfo().growRightLimit);
-         * System.out.println(myGA.getJustificationInfo().shrinkLeftLimit);
-         * System.out.println(myGA.getJustificationInfo().shrinkPriority);
-         * System.out.println(myGA.getJustificationInfo().shrinkRightLimit);
-         * System.out.println(myGA.getJustificationInfo().weight);
-         */
-        float advance = getAdvance();
-        return new GlyphJustificationInfo(advance, false,
-                GlyphJustificationInfo.PRIORITY_INTERCHAR, advance / 3, advance / 3, false,
-                GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, 0);
-    }
-
-}
diff --git a/awt/java/awt/font/ImageGraphicAttribute.java b/awt/java/awt/font/ImageGraphicAttribute.java
deleted file mode 100644
index d6d4758..0000000
--- a/awt/java/awt/font/ImageGraphicAttribute.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.harmony.misc.HashCode;
-
-/**
- * The ImageGraphicAttribute class provides an opportunity to insert images to a
- * text.
- * 
- * @since Android 1.0
- */
-public final class ImageGraphicAttribute extends GraphicAttribute {
-
-    // Image object rendered by this ImageGraphicAttribute
-    /**
-     * The image.
-     */
-    private Image fImage;
-
-    // X coordinate of the origin point
-    /**
-     * The origin x.
-     */
-    private float fOriginX;
-
-    // Y coordinate of the origin point
-    /**
-     * The origin y.
-     */
-    private float fOriginY;
-
-    // the width of the image object
-    /**
-     * The img width.
-     */
-    private float fImgWidth;
-
-    // the height of the image object
-    /**
-     * The img height.
-     */
-    private float fImgHeight;
-
-    /**
-     * Instantiates a new ImageGraphicAttribute with the specified image,
-     * alignment and origins.
-     * 
-     * @param image
-     *            the Image to be rendered by ImageGraphicAttribute.
-     * @param alignment
-     *            the alignment of the ImageGraphicAttribute.
-     * @param originX
-     *            the origin X coordinate in the image of ImageGraphicAttribute.
-     * @param originY
-     *            the origin Y coordinate in the image of ImageGraphicAttribute.
-     */
-    public ImageGraphicAttribute(Image image, int alignment, float originX, float originY) {
-        super(alignment);
-
-        this.fImage = image;
-        this.fOriginX = originX;
-        this.fOriginY = originY;
-
-        this.fImgWidth = fImage.getWidth(null);
-        this.fImgHeight = fImage.getHeight(null);
-
-    }
-
-    /**
-     * Instantiates a new ImageGraphicAttribute with the specified image and
-     * alignment.
-     * 
-     * @param image
-     *            the Image to be rendered by ImageGraphicAttribute.
-     * @param alignment
-     *            the alignment of the ImageGraphicAttribute.
-     */
-    public ImageGraphicAttribute(Image image, int alignment) {
-        this(image, alignment, 0, 0);
-    }
-
-    /**
-     * Returns a hash code of this ImageGraphicAttribute object.
-     * 
-     * @return the hash code of this ImageGraphicAttribute object.
-     */
-    @Override
-    public int hashCode() {
-        HashCode hash = new HashCode();
-
-        hash.append(fImage.hashCode());
-        hash.append(getAlignment());
-        return hash.hashCode();
-    }
-
-    /**
-     * Compares the specified ImageGraphicAttribute object with this
-     * ImageGraphicAttribute object.
-     * 
-     * @param iga
-     *            the ImageGraphicAttribute object to be compared.
-     * @return true, if the specified ImageGraphicAttribute object is equal to
-     *         this ImageGraphicAttribute object, false otherwise.
-     */
-    public boolean equals(ImageGraphicAttribute iga) {
-        if (iga == null) {
-            return false;
-        }
-
-        if (iga == this) {
-            return true;
-        }
-
-        return (fOriginX == iga.fOriginX && fOriginY == iga.fOriginY
-                && getAlignment() == iga.getAlignment() && fImage.equals(iga.fImage));
-    }
-
-    /**
-     * Compares the specified Object with this ImageGraphicAttribute object.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if the specified Object is equal to this
-     *         ImageGraphicAttribute object, false otherwise.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        try {
-            return equals((ImageGraphicAttribute)obj);
-        } catch (ClassCastException e) {
-            return false;
-        }
-
-    }
-
-    @Override
-    public void draw(Graphics2D g2, float x, float y) {
-        g2.drawImage(fImage, (int)(x - fOriginX), (int)(y - fOriginY), null);
-    }
-
-    @Override
-    public float getAdvance() {
-        return Math.max(0, fImgWidth - fOriginX);
-    }
-
-    @Override
-    public float getAscent() {
-        return Math.max(0, fOriginY);
-    }
-
-    @Override
-    public Rectangle2D getBounds() {
-        return new Rectangle2D.Float(-fOriginX, -fOriginY, fImgWidth, fImgHeight);
-    }
-
-    @Override
-    public float getDescent() {
-        return Math.max(0, fImgHeight - fOriginY);
-    }
-
-}
diff --git a/awt/java/awt/font/LineBreakMeasurer.java b/awt/java/awt/font/LineBreakMeasurer.java
deleted file mode 100644
index 4800093..0000000
--- a/awt/java/awt/font/LineBreakMeasurer.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/*
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import java.text.AttributedCharacterIterator; //???AWT: import java.text.BreakIterator;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The class LineBreakMeasurer provides methods to measure the graphical
- * representation of a text in order to determine where to add line breaks so
- * the resulting line of text fits its wrapping width. The wrapping width
- * defines the visual width of the paragraph.
- * 
- * @since Android 1.0
- */
-public final class LineBreakMeasurer {
-
-    /**
-     * The tm.
-     */
-    private TextMeasurer tm = null;
-
-    // ???AWT private BreakIterator bi = null;
-    /**
-     * The position.
-     */
-    private int position = 0;
-
-    /**
-     * The maxpos.
-     */
-    int maxpos = 0;
-
-    /**
-     * Instantiates a new LineBreakMeasurer object for the specified text.
-     * 
-     * @param text
-     *            the AttributedCharacterIterator object which contains text
-     *            with at least one character.
-     * @param frc
-     *            the FontRenderContext represented information about graphic
-     *            device.
-     */
-    public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
-        // ???AWT: this(text, BreakIterator.getLineInstance(), frc);
-    }
-
-    /*
-     * ???AWT public LineBreakMeasurer( AttributedCharacterIterator text,
-     * BreakIterator bi, FontRenderContext frc ) { tm = new TextMeasurer(text,
-     * frc); this.bi = bi; this.bi.setText(text); position =
-     * text.getBeginIndex(); maxpos = tm.aci.getEndIndex(); }
-     */
-
-    /**
-     * Deletes a character from the specified position of the text, updates this
-     * LineBreakMeasurer object.
-     * 
-     * @param newText
-     *            the new text.
-     * @param pos
-     *            the position of the character which is deleted.
-     */
-    public void deleteChar(AttributedCharacterIterator newText, int pos) {
-        tm.deleteChar(newText, pos);
-        // ???AWT: bi.setText(newText);
-
-        position = newText.getBeginIndex();
-
-        maxpos--;
-    }
-
-    /**
-     * Gets current position of this LineBreakMeasurer.
-     * 
-     * @return the current position of this LineBreakMeasurer
-     */
-    public int getPosition() {
-        return position;
-    }
-
-    /**
-     * Inserts a character at the specified position in the text, updates this
-     * LineBreakMeasurer object.
-     * 
-     * @param newText
-     *            the new text.
-     * @param pos
-     *            the position of the character which is inserted.
-     */
-    public void insertChar(AttributedCharacterIterator newText, int pos) {
-        tm.insertChar(newText, pos);
-        // ???AWT: bi.setText(newText);
-
-        position = newText.getBeginIndex();
-
-        maxpos++;
-    }
-
-    /**
-     * Returns the next line of text, updates current position in this
-     * LineBreakMeasurer.
-     * 
-     * @param wrappingWidth
-     *            the maximum visible line width.
-     * @param offsetLimit
-     *            the limit point within the text indicating that no further
-     *            text should be included on the line; the paragraph break.
-     * @param requireNextWord
-     *            if true, null is returned (the entire word at the current
-     *            position does not fit within the wrapping width); if false, a
-     *            valid layout is returned that includes at least the character
-     *            at the current position.
-     * @return the next TextLayout which begins at the current position and
-     *         represents the next line of text with width wrappingWidth, null
-     *         is returned if the entire word at the current position does not
-     *         fit within the wrapping width.
-     */
-    public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
-        if (position == maxpos) {
-            return null;
-        }
-
-        int nextPosition = nextOffset(wrappingWidth, offsetLimit, requireNextWord);
-
-        if (nextPosition == position) {
-            return null;
-        }
-        TextLayout layout = tm.getLayout(position, nextPosition);
-        position = nextPosition;
-        return layout;
-    }
-
-    /**
-     * Returns the next line of text.
-     * 
-     * @param wrappingWidth
-     *            the maximum visible line width.
-     * @return the next line of text.
-     */
-    public TextLayout nextLayout(float wrappingWidth) {
-        return nextLayout(wrappingWidth, maxpos, false);
-    }
-
-    /**
-     * Returns the end position of the next line of text.
-     * 
-     * @param wrappingWidth
-     *            the maximum visible line width.
-     * @return the end position of the next line of text.
-     */
-    public int nextOffset(float wrappingWidth) {
-        return nextOffset(wrappingWidth, maxpos, false);
-    }
-
-    /**
-     * Returns the end position of the next line of text.
-     * 
-     * @param wrappingWidth
-     *            the maximum visible line width.
-     * @param offsetLimit
-     *            the limit point withing the text indicating that no further
-     *            text should be included on the line; the paragraph break.
-     * @param requireNextWord
-     *            if true, the current position is returned if the entire next
-     *            word does not fit within wrappingWidth; if false, the offset
-     *            returned is at least one greater than the current position.
-     * @return the end position of the next line of text.
-     * @throws IllegalArgumentException
-     *             if the offsetLimit is less than the current position.
-     */
-    public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
-        if (offsetLimit <= position) {
-            // awt.203=Offset limit should be greater than current position.
-            throw new IllegalArgumentException(Messages.getString("awt.203")); //$NON-NLS-1$
-        }
-
-        if (position == maxpos) {
-            return position;
-        }
-
-        int breakPos = tm.getLineBreakIndex(position, wrappingWidth);
-        int correctedPos = breakPos;
-
-        // This check is required because bi.preceding(maxpos) throws an
-        // exception
-        /*
-         * ???AWT if (breakPos == maxpos) { correctedPos = maxpos; } else if
-         * (Character.isWhitespace(bi.getText().setIndex(breakPos))) {
-         * correctedPos = bi.following(breakPos); } else { correctedPos =
-         * bi.preceding(breakPos); }
-         */
-
-        if (position >= correctedPos) {
-            if (requireNextWord) {
-                correctedPos = position;
-            } else {
-                correctedPos = Math.max(position + 1, breakPos);
-            }
-        }
-
-        return Math.min(correctedPos, offsetLimit);
-    }
-
-    /**
-     * Sets the new position of this LineBreakMeasurer.
-     * 
-     * @param pos
-     *            the new position of this LineBreakMeasurer.
-     */
-    public void setPosition(int pos) {
-        if (tm.aci.getBeginIndex() > pos || maxpos < pos) {
-            // awt.33=index is out of range
-            throw new IllegalArgumentException(Messages.getString("awt.33")); //$NON-NLS-1$
-        }
-        position = pos;
-    }
-}
diff --git a/awt/java/awt/font/LineMetrics.java b/awt/java/awt/font/LineMetrics.java
deleted file mode 100644
index 4b03e5d..0000000
--- a/awt/java/awt/font/LineMetrics.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt.font;
-
-/**
- * The LineMetrics class provides information such as concerning how the text is
- * positioned with respect to the base line, such as ascent, descent, and
- * leading.
- * 
- * @since Android 1.0
- */
-public abstract class LineMetrics {
-
-    /**
-     * Gets the baseline offsets of the text according to the the baseline of
-     * this text.
-     * 
-     * @return the baseline offsets of the text according to the the baseline of
-     *         this text.
-     */
-    public abstract float[] getBaselineOffsets();
-
-    /**
-     * Gets the number of characters of the text.
-     * 
-     * @return the number of characters of the text.
-     */
-    public abstract int getNumChars();
-
-    /**
-     * Gets the baseline index, returns one of the following index:
-     * ROMAN_BASELINE, CENTER_BASELINE, HANGING_BASELINE.
-     * 
-     * @return the baseline index: ROMAN_BASELINE, CENTER_BASELINE or
-     *         HANGING_BASELINE.
-     */
-    public abstract int getBaselineIndex();
-
-    /**
-     * Gets the thickness of the underline.
-     * 
-     * @return the thickness of the underline.
-     */
-    public abstract float getUnderlineThickness();
-
-    /**
-     * Gets the offset of the underline.
-     * 
-     * @return the offset of the underline.
-     */
-    public abstract float getUnderlineOffset();
-
-    /**
-     * Gets the thickness of strike through line.
-     * 
-     * @return the thickness of strike through line.
-     */
-    public abstract float getStrikethroughThickness();
-
-    /**
-     * Gets the offset of the strike through line.
-     * 
-     * @return the offset of the strike through line.
-     */
-    public abstract float getStrikethroughOffset();
-
-    /**
-     * Gets the leading of the text.
-     * 
-     * @return the leading of the text.
-     */
-    public abstract float getLeading();
-
-    /**
-     * Gets the height of the text as a sum of the ascent, the descent and the
-     * leading.
-     * 
-     * @return the height of the text as a sum of the ascent, the descent and
-     *         the leading.
-     */
-    public abstract float getHeight();
-
-    /**
-     * Gets the descent of the text.
-     * 
-     * @return the descent of the text.
-     */
-    public abstract float getDescent();
-
-    /**
-     * Gets the ascent of the text.
-     * 
-     * @return the ascent of the text.
-     */
-    public abstract float getAscent();
-
-}
diff --git a/awt/java/awt/font/MultipleMaster.java b/awt/java/awt/font/MultipleMaster.java
deleted file mode 100644
index d264f24..0000000
--- a/awt/java/awt/font/MultipleMaster.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import java.awt.Font;
-
-/**
- * The MultipleMaster interface provides methods to manipulate MultipleMaster
- * type fonts and retrieve graphical and design data from them.
- * 
- * @since Android 1.0
- */
-public interface MultipleMaster {
-
-    /**
-     * Derives a new multiple master font based on the specified parameters.
-     * 
-     * @param glyphWidths
-     *            float array which represents width of each glyph in font
-     *            space.
-     * @param avgStemWidth
-     *            the average stem width in font space.
-     * @param typicalCapHeight
-     *            the typical upper case char height.
-     * @param typicalXHeight
-     *            the typical lower case char height.
-     * @param italicAngle
-     *            the slope angle for italics.
-     * @return a MultipleMaster font.
-     */
-    public Font deriveMMFont(float[] glyphWidths, float avgStemWidth, float typicalCapHeight,
-            float typicalXHeight, float italicAngle);
-
-    /**
-     * Derives a new multiple master font based on the design axis values
-     * contained in the specified array.
-     * 
-     * @param axes
-     *            an float array which contains axis values.
-     * @return a MultipleMaster font.
-     */
-    public Font deriveMMFont(float[] axes);
-
-    /**
-     * Gets default design values for the axes.
-     * 
-     * @return the default design values for the axes.
-     */
-    public float[] getDesignAxisDefaults();
-
-    /**
-     * Gets the array of design axis names.
-     * 
-     * @return the array of design axis names.
-     */
-    public String[] getDesignAxisNames();
-
-    /**
-     * Gets the array of design axis ranges.
-     * 
-     * @return the array of design axis ranges.
-     */
-    public float[] getDesignAxisRanges();
-
-    /**
-     * Gets the number of multiple master design controls.
-     * 
-     * @return the number of multiple master design controls.
-     */
-    public int getNumDesignAxes();
-
-}
diff --git a/awt/java/awt/font/OpenType.java b/awt/java/awt/font/OpenType.java
deleted file mode 100644
index db66911..0000000
--- a/awt/java/awt/font/OpenType.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt.font;
-
-/**
- * The OpenType interface provides constants and methods for getting instance
- * data for fonts of type OpenType and TrueType. For more information, see the
- * <a
- * href="http://partners.adobe.com/public/developer/opentype/index_spec.html">
- * OpenType specification</a>.
- * 
- * @since Android 1.0
- */
-public interface OpenType {
-
-    /**
-     * The Constant TAG_ACNT indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_ACNT = 1633906292;
-
-    /**
-     * The Constant TAG_AVAR indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_AVAR = 1635148146;
-
-    /**
-     * The Constant TAG_BASE indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_BASE = 1111577413;
-
-    /**
-     * The Constant TAG_BDAT indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_BDAT = 1650745716;
-
-    /**
-     * The Constant TAG_BLOC indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_BLOC = 1651273571;
-
-    /**
-     * The Constant TAG_BSLN indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_BSLN = 1651731566;
-
-    /**
-     * The Constant TAG_CFF indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_CFF = 1128678944;
-
-    /**
-     * The Constant TAG_CMAP indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_CMAP = 1668112752;
-
-    /**
-     * The Constant TAG_CVAR indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_CVAR = 1668702578;
-
-    /**
-     * The Constant TAG_CVT indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_CVT = 1668707360;
-
-    /**
-     * The Constant TAG_DSIG indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_DSIG = 1146308935;
-
-    /**
-     * The Constant TAG_EBDT indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_EBDT = 1161970772;
-
-    /**
-     * The Constant TAG_EBLC indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_EBLC = 1161972803;
-
-    /**
-     * The Constant TAG_EBSC indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_EBSC = 1161974595;
-
-    /**
-     * The Constant TAG_FDSC indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_FDSC = 1717859171;
-
-    /**
-     * The Constant TAG_FEAT indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_FEAT = 1717920116;
-
-    /**
-     * The Constant TAG_FMTX indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_FMTX = 1718449272;
-
-    /**
-     * The Constant TAG_FPGM indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_FPGM = 1718642541;
-
-    /**
-     * The Constant TAG_FVAR indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_FVAR = 1719034226;
-
-    /**
-     * The Constant TAG_GASP indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_GASP = 1734439792;
-
-    /**
-     * The Constant TAG_GDEF indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_GDEF = 1195656518;
-
-    /**
-     * The Constant TAG_GLYF indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_GLYF = 1735162214;
-
-    /**
-     * The Constant TAG_GPOS indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_GPOS = 1196445523;
-
-    /**
-     * The Constant TAG_GSUB indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_GSUB = 1196643650;
-
-    /**
-     * The Constant TAG_GVAR indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_GVAR = 1735811442;
-
-    /**
-     * The Constant TAG_HDMX indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_HDMX = 1751412088;
-
-    /**
-     * The Constant TAG_HEAD indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_HEAD = 1751474532;
-
-    /**
-     * The Constant TAG_HHEA indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_HHEA = 1751672161;
-
-    /**
-     * The Constant TAG_HMTX indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_HMTX = 1752003704;
-
-    /**
-     * The Constant TAG_JSTF indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_JSTF = 1246975046;
-
-    /**
-     * The Constant TAG_JUST indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_JUST = 1786082164;
-
-    /**
-     * The Constant TAG_KERN indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_KERN = 1801810542;
-
-    /**
-     * The Constant TAG_LCAR indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_LCAR = 1818452338;
-
-    /**
-     * The Constant TAG_LOCA indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_LOCA = 1819239265;
-
-    /**
-     * The Constant TAG_LTSH indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_LTSH = 1280594760;
-
-    /**
-     * The Constant TAG_MAXP indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_MAXP = 1835104368;
-
-    /**
-     * The Constant TAG_MMFX indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_MMFX = 1296909912;
-
-    /**
-     * The Constant TAG_MMSD indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_MMSD = 1296913220;
-
-    /**
-     * The Constant TAG_MORT indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_MORT = 1836020340;
-
-    /**
-     * The Constant TAG_NAME indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_NAME = 1851878757;
-
-    /**
-     * The Constant TAG_OPBD indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_OPBD = 1836020340;
-
-    /**
-     * The Constant TAG_OS2 indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_OS2 = 1330851634;
-
-    /**
-     * The Constant TAG_PCLT indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_PCLT = 1346587732;
-
-    /**
-     * The Constant TAG_POST indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_POST = 1886352244;
-
-    /**
-     * The Constant TAG_PREP indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_PREP = 1886545264;
-
-    /**
-     * The Constant TAG_PROP indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_PROP = 1886547824;
-
-    /**
-     * The Constant TAG_TRAK indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_TRAK = 1953653099;
-
-    /**
-     * The Constant TAG_TYP1 indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_TYP1 = 1954115633;
-
-    /**
-     * The Constant TAG_VDMX indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_VDMX = 1447316824;
-
-    /**
-     * The Constant TAG_VHEA indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_VHEA = 1986553185;
-
-    /**
-     * The Constant TAG_VMTX indicates corresponding table tag in the Open Type
-     * Specification.
-     */
-    public static final int TAG_VMTX = 1986884728;
-
-    /**
-     * Returns the OpenType font version.
-     * 
-     * @return the the OpenType font version.
-     */
-    public int getVersion();
-
-    /**
-     * Gets the table for a specified tag. Sfnt tables include cmap, name and
-     * head items.
-     * 
-     * @param sfntTag
-     *            the sfnt tag.
-     * @return a byte array contains the font data corresponding to the
-     *         specified tag.
-     */
-    public byte[] getFontTable(int sfntTag);
-
-    /**
-     * Gets the table for a specified tag. Sfnt tables include cmap, name and
-     * head items.
-     * 
-     * @param sfntTag
-     *            the sfnt tag.
-     * @param offset
-     *            the offset of the returned table.
-     * @param count
-     *            the number of returned table.
-     * @return the table corresponding to sfntTag and containing the bytes
-     *         starting at offset byte and including count bytes.
-     */
-    public byte[] getFontTable(int sfntTag, int offset, int count);
-
-    /**
-     * Gets the table for a specified tag. Sfnt tables include cmap, name and
-     * head items.
-     * 
-     * @param strSfntTag
-     *            the str sfnt tag as a String.
-     * @return a byte array contains the font data corresponding to the
-     *         specified tag.
-     */
-    public byte[] getFontTable(String strSfntTag);
-
-    /**
-     * Gets the table for a specified tag. Sfnt tables include cmap, name and
-     * head items.
-     * 
-     * @param strSfntTag
-     *            the sfnt tag as a String.
-     * @param offset
-     *            the offset of the returned table.
-     * @param count
-     *            the number of returned table.
-     * @return the table corresponding to sfntTag and containing the bytes
-     *         starting at offset byte and including count bytes.
-     */
-    public byte[] getFontTable(String strSfntTag, int offset, int count);
-
-    /**
-     * Gets the table size for a specified tag.
-     * 
-     * @param strSfntTag
-     *            the sfnt tag as a String.
-     * @return the table size for a specified tag.
-     */
-    public int getFontTableSize(String strSfntTag);
-
-    /**
-     * Gets the table size for a specified tag.
-     * 
-     * @param sfntTag
-     *            the sfnt tag.
-     * @return the table size for a specified tag.
-     */
-    public int getFontTableSize(int sfntTag);
-
-}
diff --git a/awt/java/awt/font/ShapeGraphicAttribute.java b/awt/java/awt/font/ShapeGraphicAttribute.java
deleted file mode 100644
index 182bffd..0000000
--- a/awt/java/awt/font/ShapeGraphicAttribute.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import java.awt.BasicStroke;
-import java.awt.Graphics2D;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.harmony.misc.HashCode;
-
-/**
- * The ShapeGraphicAttribute class provides an opportunity to insert shapes to a
- * text.
- * 
- * @since Android 1.0
- */
-public final class ShapeGraphicAttribute extends GraphicAttribute {
-
-    // shape to render
-    /**
-     * The shape.
-     */
-    private Shape fShape;
-
-    // flag, if the shape should be stroked (true) or filled (false)
-    /**
-     * The stroke.
-     */
-    private boolean fStroke;
-
-    // bounds of the shape
-    /**
-     * The bounds.
-     */
-    private Rectangle2D fBounds;
-
-    // X coordinate of the origin point
-    /**
-     * The origin x.
-     */
-    private float fOriginX;
-
-    // Y coordinate of the origin point
-    /**
-     * The origin y.
-     */
-    private float fOriginY;
-
-    // width of the shape
-    /**
-     * The shape width.
-     */
-    private float fShapeWidth;
-
-    // height of the shape
-    /**
-     * The shape height.
-     */
-    private float fShapeHeight;
-
-    /**
-     * The Constant STROKE indicates whether the Shape is stroked or not.
-     */
-    public static final boolean STROKE = true;
-
-    /**
-     * The Constant FILL indicates whether the Shape is filled or not.
-     */
-    public static final boolean FILL = false;
-
-    /**
-     * Instantiates a new ShapeGraphicAttribute object for the specified Shape.
-     * 
-     * @param shape
-     *            the shape to be rendered by this ShapeGraphicAttribute.
-     * @param alignment
-     *            the alignment of this ShapeGraphicAttribute.
-     * @param stroke
-     *            true if the Shape is stroked, false if the Shape is filled.
-     */
-    public ShapeGraphicAttribute(Shape shape, int alignment, boolean stroke) {
-        super(alignment);
-
-        this.fShape = shape;
-        this.fStroke = stroke;
-
-        this.fBounds = fShape.getBounds2D();
-
-        this.fOriginX = (float)fBounds.getMinX();
-        this.fOriginY = (float)fBounds.getMinY();
-
-        this.fShapeWidth = (float)fBounds.getWidth();
-        this.fShapeHeight = (float)fBounds.getHeight();
-    }
-
-    /**
-     * Returns a hash code of this ShapeGraphicAttribute object.
-     * 
-     * @return a hash code of this ShapeGraphicAttribute object.
-     */
-    @Override
-    public int hashCode() {
-        HashCode hash = new HashCode();
-
-        hash.append(fShape.hashCode());
-        hash.append(getAlignment());
-        return hash.hashCode();
-    }
-
-    /**
-     * Compares this ShapeGraphicAttribute object to the specified
-     * ShapeGraphicAttribute object.
-     * 
-     * @param sga
-     *            the ShapeGraphicAttribute object to be compared.
-     * @return true, if this ShapeGraphicAttribute object is equal to the
-     *         specified ShapeGraphicAttribute object, false otherwise.
-     */
-    public boolean equals(ShapeGraphicAttribute sga) {
-        if (sga == null) {
-            return false;
-        }
-
-        if (sga == this) {
-            return true;
-        }
-
-        return (fStroke == sga.fStroke && getAlignment() == sga.getAlignment() && fShape
-                .equals(sga.fShape));
-
-    }
-
-    /**
-     * Compares this ShapeGraphicAttribute object to the specified Object.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if this ShapeGraphicAttribute object is equal to the
-     *         specified Object, false otherwise.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        try {
-            return equals((ShapeGraphicAttribute)obj);
-        } catch (ClassCastException e) {
-            return false;
-        }
-    }
-
-    @Override
-    public void draw(Graphics2D g2, float x, float y) {
-        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
-        if (fStroke == STROKE) {
-            Stroke oldStroke = g2.getStroke();
-            g2.setStroke(new BasicStroke());
-            g2.draw(at.createTransformedShape(fShape));
-            g2.setStroke(oldStroke);
-        } else {
-            g2.fill(at.createTransformedShape(fShape));
-        }
-
-    }
-
-    @Override
-    public float getAdvance() {
-        return Math.max(0, fShapeWidth + fOriginX);
-    }
-
-    @Override
-    public float getAscent() {
-        return Math.max(0, -fOriginY);
-    }
-
-    @Override
-    public Rectangle2D getBounds() {
-        return (Rectangle2D)fBounds.clone();
-    }
-
-    @Override
-    public float getDescent() {
-        return Math.max(0, fShapeHeight + fOriginY);
-    }
-
-}
diff --git a/awt/java/awt/font/TextHitInfo.java b/awt/java/awt/font/TextHitInfo.java
deleted file mode 100644
index 6460eba..0000000
--- a/awt/java/awt/font/TextHitInfo.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/*
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import org.apache.harmony.misc.HashCode;
-
-/**
- * The TextHitInfo class provides information about a caret position in a text
- * model for insertion or deletion of a character in a text. The TextHitInfo
- * defines two biases of the character: leading or trailing. Leading position
- * means the left edge of the specified character (TextHitInfo.leading(2) method
- * for "text" returns the left side of "x"). Trailing position means the right
- * edge of the specified character (TextHitInfo.trailing(2) method for "text"
- * returns the right side of "x").
- * 
- * @since Android 1.0
- */
-public final class TextHitInfo {
-
-    /**
-     * The char idx.
-     */
-    private int charIdx; // Represents character index in the line
-
-    /**
-     * The is trailing.
-     */
-    private boolean isTrailing;
-
-    /**
-     * Instantiates a new text hit info.
-     * 
-     * @param idx
-     *            the idx.
-     * @param isTrailing
-     *            the is trailing.
-     */
-    private TextHitInfo(int idx, boolean isTrailing) {
-        charIdx = idx;
-        this.isTrailing = isTrailing;
-    }
-
-    /**
-     * Returns the textual string representation of this TextHitInfo instance.
-     * 
-     * @return the string representation.
-     */
-    @Override
-    public String toString() {
-        return new String("TextHitInfo[" + charIdx + ", " + //$NON-NLS-1$ //$NON-NLS-2$
-                (isTrailing ? "Trailing" : "Leading") + "]" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        );
-    }
-
-    /**
-     * Compares this TextHitInfo object with the specified object.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if the specified object is a TextHitInfo object with the
-     *         same data values as this TextHitInfo, false otherwise.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof TextHitInfo) {
-            return equals((TextHitInfo)obj);
-        }
-        return false;
-    }
-
-    /**
-     * Compares this TextHitInfo object with the specified TextHitInfo object.
-     * 
-     * @param thi
-     *            the TextHitInfo object to be compared.
-     * @return true, if this TextHitInfo object has the same data values as the
-     *         specified TextHitInfo object, false otherwise.
-     */
-    public boolean equals(TextHitInfo thi) {
-        return thi != null && thi.charIdx == charIdx && thi.isTrailing == isTrailing;
-    }
-
-    /**
-     * Gets a TextHitInfo object with its character index at the specified
-     * offset from the character index of this TextHitInfo.
-     * 
-     * @param offset
-     *            the offset.
-     * @return the TextHitInfo.
-     */
-    public TextHitInfo getOffsetHit(int offset) {
-        return new TextHitInfo(charIdx + offset, isTrailing);
-    }
-
-    /**
-     * Gets a TextHitInfo associated with the other side of the insertion point.
-     * 
-     * @return the other hit.
-     */
-    public TextHitInfo getOtherHit() {
-        return isTrailing ? new TextHitInfo(charIdx + 1, false)
-                : new TextHitInfo(charIdx - 1, true);
-    }
-
-    /**
-     * Returns true if the leading edge of the character is hit, false if the
-     * trailing edge of the character is hit.
-     * 
-     * @return true if the leading edge of the character is hit, false if the
-     *         trailing edge of the character is hit.
-     */
-    public boolean isLeadingEdge() {
-        return !isTrailing;
-    }
-
-    /**
-     * Returns the hash code value of this TextHitInfo instance.
-     * 
-     * @return the hash code value.
-     */
-    @Override
-    public int hashCode() {
-        return HashCode.combine(charIdx, isTrailing);
-    }
-
-    /**
-     * Gets the insertion index.
-     * 
-     * @return the insertion index: character index if the leading edge is hit,
-     *         or character index + 1 if the trailing edge is hit.
-     */
-    public int getInsertionIndex() {
-        return isTrailing ? charIdx + 1 : charIdx;
-    }
-
-    /**
-     * Gets the index of the character hit.
-     * 
-     * @return the character hit's index.
-     */
-    public int getCharIndex() {
-        return charIdx;
-    }
-
-    /**
-     * Returns a TextHitInfo associated with the trailing edge of the character
-     * at the specified char index.
-     * 
-     * @param charIndex
-     *            the char index.
-     * @return the TextHitInfo associated with the trailing edge of the
-     *         character at the specified char index.
-     */
-    public static TextHitInfo trailing(int charIndex) {
-        return new TextHitInfo(charIndex, true);
-    }
-
-    /**
-     * Returns a TextHitInfo object associated with the leading edge of the
-     * character at the specified char index.
-     * 
-     * @param charIndex
-     *            the char index.
-     * @return the TextHitInfo object associated with the leading edge of the
-     *         character at the specified char index.
-     */
-    public static TextHitInfo leading(int charIndex) {
-        return new TextHitInfo(charIndex, false);
-    }
-
-    /**
-     * Returns a (trailing) TextHitInfo object associated with the character
-     * before the specified offset.
-     * 
-     * @param offset
-     *            the offset.
-     * @return the TextHitInfo object associated with the character before the
-     *         specified offset.
-     */
-    public static TextHitInfo beforeOffset(int offset) {
-        return new TextHitInfo(offset - 1, true);
-    }
-
-    /**
-     * Returns a (leading) TextHitInfo object associated with the character
-     * after the specified offset.
-     * 
-     * @param offset
-     *            the offset.
-     * @return the TextHitInfo object associated with the character after the
-     *         specified offset.
-     */
-    public static TextHitInfo afterOffset(int offset) {
-        return new TextHitInfo(offset, false);
-    }
-}
diff --git a/awt/java/awt/font/TextLayout.java b/awt/java/awt/font/TextLayout.java
deleted file mode 100644
index cc6f0ba..0000000
--- a/awt/java/awt/font/TextLayout.java
+++ /dev/null
@@ -1,927 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.GeneralPath;
-import java.text.AttributedCharacterIterator;
-import java.text.AttributedString;
-import java.util.Map;
-
-import org.apache.harmony.awt.gl.font.BasicMetrics;
-import org.apache.harmony.awt.gl.font.CaretManager;
-import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
-import org.apache.harmony.awt.gl.font.TextRunBreaker;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The TextLayout class defines the graphical representation of character data.
- * This class provides method for obtaining information about cursor positioning
- * and movement, split cursors for text with different directions, logical and
- * visual highlighting, multiple baselines, hits, justification, ascent,
- * descent, and advance, and rendering. A TextLayout object can be rendered
- * using Graphics context.
- * 
- * @since Android 1.0
- */
-public final class TextLayout implements Cloneable {
-
-    /**
-     * The CaretPolicy class provides a policy for obtaining the caret location.
-     * The single getStrongCaret method specifies the policy.
-     */
-    public static class CaretPolicy {
-
-        /**
-         * Instantiates a new CaretPolicy.
-         */
-        public CaretPolicy() {
-            // Nothing to do
-        }
-
-        /**
-         * Returns whichever of the two specified TextHitInfo objects has the
-         * stronger caret (higher character level) in the specified TextLayout.
-         * 
-         * @param hit1
-         *            the first TextHitInfo of the specified TextLayout.
-         * @param hit2
-         *            the second TextHitInfo of the specified TextLayout.
-         * @param layout
-         *            the TextLayout.
-         * @return the TextHitInfo with the stronger caret.
-         */
-        public TextHitInfo getStrongCaret(TextHitInfo hit1, TextHitInfo hit2, TextLayout layout) {
-            // Stronger hit is the one with greater level.
-            // If the level is same, leading edge is stronger.
-
-            int level1 = layout.getCharacterLevel(hit1.getCharIndex());
-            int level2 = layout.getCharacterLevel(hit2.getCharIndex());
-
-            if (level1 == level2) {
-                return (hit2.isLeadingEdge() && (!hit1.isLeadingEdge())) ? hit2 : hit1;
-            }
-            return level1 > level2 ? hit1 : hit2;
-        }
-
-    }
-
-    /**
-     * The Constant DEFAULT_CARET_POLICY indicates the default caret policy.
-     */
-    public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy();
-
-    /**
-     * The breaker.
-     */
-    private TextRunBreaker breaker;
-
-    /**
-     * The metrics valid.
-     */
-    private boolean metricsValid = false;
-
-    /**
-     * The tmc.
-     */
-    private TextMetricsCalculator tmc;
-
-    /**
-     * The metrics.
-     */
-    private BasicMetrics metrics;
-
-    /**
-     * The caret manager.
-     */
-    private CaretManager caretManager;
-
-    /**
-     * The justification width.
-     */
-    float justificationWidth = -1;
-
-    /**
-     * Instantiates a new TextLayout object from the specified string and Font.
-     * 
-     * @param string
-     *            the string to be displayed.
-     * @param font
-     *            the font of the text.
-     * @param frc
-     *            the FontRenderContext object for obtaining information about a
-     *            graphics device.
-     */
-    public TextLayout(String string, Font font, FontRenderContext frc) {
-        if (string == null) {
-            // awt.01='{0}' parameter is null
-            throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        if (font == null) {
-            // awt.01='{0}' parameter is null
-            throw new IllegalArgumentException(Messages.getString("awt.01", "font")); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        if (string.length() == 0) {
-            // awt.02='{0}' parameter has zero length
-            throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        AttributedString as = new AttributedString(string);
-        as.addAttribute(TextAttribute.FONT, font);
-        this.breaker = new TextRunBreaker(as.getIterator(), frc);
-        caretManager = new CaretManager(breaker);
-    }
-
-    /**
-     * Instantiates a new TextLayout from the specified text and a map of
-     * attributes.
-     * 
-     * @param string
-     *            the string to be displayed.
-     * @param attributes
-     *            the attributes to be used for obtaining the text style.
-     * @param frc
-     *            the FontRenderContext object for obtaining information about a
-     *            graphics device.
-     */
-    public TextLayout(String string,
-            Map<? extends java.text.AttributedCharacterIterator.Attribute, ?> attributes,
-            FontRenderContext frc) {
-        if (string == null) {
-            // awt.01='{0}' parameter is null
-            throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        if (attributes == null) {
-            // awt.01='{0}' parameter is null
-            throw new IllegalArgumentException(Messages.getString("awt.01", "attributes")); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        if (string.length() == 0) {
-            // awt.02='{0}' parameter has zero length
-            throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        AttributedString as = new AttributedString(string);
-        as.addAttributes(attributes, 0, string.length());
-        this.breaker = new TextRunBreaker(as.getIterator(), frc);
-        caretManager = new CaretManager(breaker);
-    }
-
-    /**
-     * Instantiates a new TextLayout from the AttributedCharacterIterator.
-     * 
-     * @param text
-     *            the AttributedCharacterIterator.
-     * @param frc
-     *            the FontRenderContext object for obtaining information about a
-     *            graphics device.
-     */
-    public TextLayout(AttributedCharacterIterator text, FontRenderContext frc) {
-        if (text == null) {
-            // awt.03='{0}' iterator parameter is null
-            throw new IllegalArgumentException(Messages.getString("awt.03", "text")); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        if (text.getBeginIndex() == text.getEndIndex()) {
-            // awt.04='{0}' iterator parameter has zero length
-            throw new IllegalArgumentException(Messages.getString("awt.04", "text")); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        this.breaker = new TextRunBreaker(text, frc);
-        caretManager = new CaretManager(breaker);
-    }
-
-    /**
-     * Instantiates a new text layout.
-     * 
-     * @param breaker
-     *            the breaker.
-     */
-    TextLayout(TextRunBreaker breaker) {
-        this.breaker = breaker;
-        caretManager = new CaretManager(this.breaker);
-    }
-
-    /**
-     * Returns a hash code of this TextLayout object.
-     * 
-     * @return a hash code of this TextLayout object.
-     */
-    @Override
-    public int hashCode() {
-        return breaker.hashCode();
-    }
-
-    /**
-     * Returns a copy of this object.
-     * 
-     * @return a copy of this object.
-     */
-    @Override
-    protected Object clone() {
-        TextLayout res = new TextLayout((TextRunBreaker)breaker.clone());
-
-        if (justificationWidth >= 0) {
-            res.handleJustify(justificationWidth);
-        }
-
-        return res;
-    }
-
-    /**
-     * Compares this TextLayout object to the specified TextLayout object.
-     * 
-     * @param layout
-     *            the TextLayout object to be compared.
-     * @return true, if this TextLayout object is equal to the specified
-     *         TextLayout object, false otherwise.
-     */
-    public boolean equals(TextLayout layout) {
-        if (layout == null) {
-            return false;
-        }
-        return this.breaker.equals(layout.breaker);
-    }
-
-    /**
-     * Compares this TextLayout object to the specified Object.
-     * 
-     * @param obj
-     *            the Object to be compared.
-     * @return true, if this TextLayout object is equal to the specified Object,
-     *         false otherwise.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        return obj instanceof TextLayout ? equals((TextLayout)obj) : false;
-    }
-
-    /**
-     * Gets the string representation for this TextLayout.
-     * 
-     * @return the string representation for this TextLayout.
-     */
-    @Override
-    public String toString() { // what for?
-        return super.toString();
-    }
-
-    /**
-     * Draws this TextLayout at the specified location with the specified
-     * Graphics2D context.
-     * 
-     * @param g2d
-     *            the Graphics2D object which renders this TextLayout.
-     * @param x
-     *            the X coordinate of the TextLayout origin.
-     * @param y
-     *            the Y coordinate of the TextLayout origin.
-     */
-    public void draw(Graphics2D g2d, float x, float y) {
-        updateMetrics();
-        breaker.drawSegments(g2d, x, y);
-    }
-
-    /**
-     * Update metrics.
-     */
-    private void updateMetrics() {
-        if (!metricsValid) {
-            breaker.createAllSegments();
-            tmc = new TextMetricsCalculator(breaker);
-            metrics = tmc.createMetrics();
-            metricsValid = true;
-        }
-    }
-
-    /**
-     * Gets the advance of this TextLayout object.
-     * 
-     * @return the advance of this TextLayout object.
-     */
-    public float getAdvance() {
-        updateMetrics();
-        return metrics.getAdvance();
-    }
-
-    /**
-     * Gets the ascent of this TextLayout object.
-     * 
-     * @return the ascent of this TextLayout object.
-     */
-    public float getAscent() {
-        updateMetrics();
-        return metrics.getAscent();
-    }
-
-    /**
-     * Gets the baseline of this TextLayout object.
-     * 
-     * @return the baseline of this TextLayout object.
-     */
-    public byte getBaseline() {
-        updateMetrics();
-        return (byte)metrics.getBaseLineIndex();
-    }
-
-    /**
-     * Gets the float array of offsets for the baselines which are used in this
-     * TextLayout.
-     * 
-     * @return the float array of offsets for the baselines which are used in
-     *         this TextLayout.
-     */
-    public float[] getBaselineOffsets() {
-        updateMetrics();
-        return tmc.getBaselineOffsets();
-    }
-
-    /**
-     * Gets the black box bounds of the characters in the specified area. The
-     * black box bounds is an Shape which contains all bounding boxes of all the
-     * glyphs of the characters between firstEndpoint and secondEndpoint
-     * parameters values.
-     * 
-     * @param firstEndpoint
-     *            the first point of the area.
-     * @param secondEndpoint
-     *            the second point of the area.
-     * @return the Shape which contains black box bounds.
-     */
-    public Shape getBlackBoxBounds(int firstEndpoint, int secondEndpoint) {
-        updateMetrics();
-        if (firstEndpoint < secondEndpoint) {
-            return breaker.getBlackBoxBounds(firstEndpoint, secondEndpoint);
-        }
-        return breaker.getBlackBoxBounds(secondEndpoint, firstEndpoint);
-    }
-
-    /**
-     * Gets the bounds of this TextLayout.
-     * 
-     * @return the bounds of this TextLayout.
-     */
-    public Rectangle2D getBounds() {
-        updateMetrics();
-        return breaker.getVisualBounds();
-    }
-
-    /**
-     * Gets information about the caret of the specified TextHitInfo.
-     * 
-     * @param hitInfo
-     *            the TextHitInfo.
-     * @return the information about the caret of the specified TextHitInfo.
-     */
-    public float[] getCaretInfo(TextHitInfo hitInfo) {
-        updateMetrics();
-        return caretManager.getCaretInfo(hitInfo);
-    }
-
-    /**
-     * Gets information about the caret of the specified TextHitInfo of a
-     * character in this TextLayout.
-     * 
-     * @param hitInfo
-     *            the TextHitInfo of a character in this TextLayout.
-     * @param bounds
-     *            the bounds to which the caret info is constructed.
-     * @return the caret of the specified TextHitInfo.
-     */
-    public float[] getCaretInfo(TextHitInfo hitInfo, Rectangle2D bounds) {
-        updateMetrics();
-        return caretManager.getCaretInfo(hitInfo);
-    }
-
-    /**
-     * Gets a Shape which represents the caret of the specified TextHitInfo in
-     * the bounds of this TextLayout.
-     * 
-     * @param hitInfo
-     *            the TextHitInfo.
-     * @param bounds
-     *            the bounds to which the caret info is constructed.
-     * @return the Shape which represents the caret.
-     */
-    public Shape getCaretShape(TextHitInfo hitInfo, Rectangle2D bounds) {
-        updateMetrics();
-        return caretManager.getCaretShape(hitInfo, this);
-    }
-
-    /**
-     * Gets a Shape which represents the caret of the specified TextHitInfo in
-     * the bounds of this TextLayout.
-     * 
-     * @param hitInfo
-     *            the TextHitInfo.
-     * @return the Shape which represents the caret.
-     */
-    public Shape getCaretShape(TextHitInfo hitInfo) {
-        updateMetrics();
-        return caretManager.getCaretShape(hitInfo, this);
-    }
-
-    /**
-     * Gets two Shapes for the strong and weak carets with default caret policy
-     * and null bounds: the first element is the strong caret, the second is the
-     * weak caret or null.
-     * 
-     * @param offset
-     *            an offset in the TextLayout.
-     * @return an array of two Shapes corresponded to the strong and weak
-     *         carets.
-     */
-    public Shape[] getCaretShapes(int offset) {
-        return getCaretShapes(offset, null, TextLayout.DEFAULT_CARET_POLICY);
-    }
-
-    /**
-     * Gets two Shapes for the strong and weak carets with the default caret
-     * policy: the first element is the strong caret, the second is the weak
-     * caret or null.
-     * 
-     * @param offset
-     *            an offset in the TextLayout.
-     * @param bounds
-     *            the bounds to which to extend the carets.
-     * @return an array of two Shapes corresponded to the strong and weak
-     *         carets.
-     */
-    public Shape[] getCaretShapes(int offset, Rectangle2D bounds) {
-        return getCaretShapes(offset, bounds, TextLayout.DEFAULT_CARET_POLICY);
-    }
-
-    /**
-     * Gets two Shapes for the strong and weak carets: the first element is the
-     * strong caret, the second is the weak caret or null.
-     * 
-     * @param offset
-     *            an offset in the TextLayout.
-     * @param bounds
-     *            the bounds to which to extend the carets.
-     * @param policy
-     *            the specified CaretPolicy.
-     * @return an array of two Shapes corresponded to the strong and weak
-     *         carets.
-     */
-    public Shape[] getCaretShapes(int offset, Rectangle2D bounds, TextLayout.CaretPolicy policy) {
-        if (offset < 0 || offset > breaker.getCharCount()) {
-            // awt.195=Offset is out of bounds
-            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
-        }
-
-        updateMetrics();
-        return caretManager.getCaretShapes(offset, bounds, policy, this);
-    }
-
-    /**
-     * Gets the number of characters in this TextLayout.
-     * 
-     * @return the number of characters in this TextLayout.
-     */
-    public int getCharacterCount() {
-        return breaker.getCharCount();
-    }
-
-    /**
-     * Gets the level of the character with the specified index.
-     * 
-     * @param index
-     *            the specified index of the character.
-     * @return the level of the character.
-     */
-    public byte getCharacterLevel(int index) {
-        if (index == -1 || index == getCharacterCount()) {
-            return (byte)breaker.getBaseLevel();
-        }
-        return breaker.getLevel(index);
-    }
-
-    /**
-     * Gets the descent of this TextLayout.
-     * 
-     * @return the descent of this TextLayout.
-     */
-    public float getDescent() {
-        updateMetrics();
-        return metrics.getDescent();
-    }
-
-    /**
-     * Gets the TextLayout wich is justified with the specified width related to
-     * this TextLayout.
-     * 
-     * @param justificationWidth
-     *            the width which is used for justification.
-     * @return a TextLayout justified to the specified width.
-     * @throws Error
-     *             the error occures if this TextLayout has been already
-     *             justified.
-     */
-    public TextLayout getJustifiedLayout(float justificationWidth) throws Error {
-        float justification = breaker.getJustification();
-
-        if (justification < 0) {
-            // awt.196=Justification impossible, layout already justified
-            throw new Error(Messages.getString("awt.196")); //$NON-NLS-1$
-        } else if (justification == 0) {
-            return this;
-        }
-
-        TextLayout justifiedLayout = new TextLayout((TextRunBreaker)breaker.clone());
-        justifiedLayout.handleJustify(justificationWidth);
-        return justifiedLayout;
-    }
-
-    /**
-     * Gets the leading of this TextLayout.
-     * 
-     * @return the leading of this TextLayout.
-     */
-    public float getLeading() {
-        updateMetrics();
-        return metrics.getLeading();
-    }
-
-    /**
-     * Gets a Shape representing the logical selection betweeen the specified
-     * endpoints and extended to the natural bounds of this TextLayout.
-     * 
-     * @param firstEndpoint
-     *            the first selected endpoint within the area of characters
-     * @param secondEndpoint
-     *            the second selected endpoint within the area of characters
-     * @return a Shape represented the logical selection betweeen the specified
-     *         endpoints.
-     */
-    public Shape getLogicalHighlightShape(int firstEndpoint, int secondEndpoint) {
-        updateMetrics();
-        return getLogicalHighlightShape(firstEndpoint, secondEndpoint, breaker.getLogicalBounds());
-    }
-
-    /**
-     * Gets a Shape representing the logical selection betweeen the specified
-     * endpoints and extended to the specified bounds of this TextLayout.
-     * 
-     * @param firstEndpoint
-     *            the first selected endpoint within the area of characters
-     * @param secondEndpoint
-     *            the second selected endpoint within the area of characters
-     * @param bounds
-     *            the specified bounds of this TextLayout.
-     * @return a Shape represented the logical selection betweeen the specified
-     *         endpoints.
-     */
-    public Shape getLogicalHighlightShape(int firstEndpoint, int secondEndpoint, Rectangle2D bounds) {
-        updateMetrics();
-
-        if (firstEndpoint > secondEndpoint) {
-            if (secondEndpoint < 0 || firstEndpoint > breaker.getCharCount()) {
-                // awt.197=Endpoints are out of range
-                throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
-            }
-            return caretManager.getLogicalHighlightShape(secondEndpoint, firstEndpoint, bounds,
-                    this);
-        }
-        if (firstEndpoint < 0 || secondEndpoint > breaker.getCharCount()) {
-            // awt.197=Endpoints are out of range
-            throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
-        }
-        return caretManager.getLogicalHighlightShape(firstEndpoint, secondEndpoint, bounds, this);
-    }
-
-    /**
-     * Gets the logical ranges of text which corresponds to a visual selection.
-     * 
-     * @param hit1
-     *            the first endpoint of the visual range.
-     * @param hit2
-     *            the second endpoint of the visual range.
-     * @return the logical ranges of text which corresponds to a visual
-     *         selection.
-     */
-    public int[] getLogicalRangesForVisualSelection(TextHitInfo hit1, TextHitInfo hit2) {
-        return caretManager.getLogicalRangesForVisualSelection(hit1, hit2);
-    }
-
-    /**
-     * Gets the TextHitInfo for the next caret to the left (or up at the end of
-     * the line) of the specified offset.
-     * 
-     * @param offset
-     *            the offset in this TextLayout.
-     * @return the TextHitInfo for the next caret to the left (or up at the end
-     *         of the line) of the specified hit, or null if there is no hit.
-     */
-    public TextHitInfo getNextLeftHit(int offset) {
-        return getNextLeftHit(offset, DEFAULT_CARET_POLICY);
-    }
-
-    /**
-     * Gets the TextHitInfo for the next caret to the left (or up at the end of
-     * the line) of the specified hit.
-     * 
-     * @param hitInfo
-     *            the initial hit.
-     * @return the TextHitInfo for the next caret to the left (or up at the end
-     *         of the line) of the specified hit, or null if there is no hit.
-     */
-    public TextHitInfo getNextLeftHit(TextHitInfo hitInfo) {
-        breaker.createAllSegments();
-        return caretManager.getNextLeftHit(hitInfo);
-    }
-
-    /**
-     * Gets the TextHitInfo for the next caret to the left (or up at the end of
-     * the line) of the specified offset, given the specified caret policy.
-     * 
-     * @param offset
-     *            the offset in this TextLayout.
-     * @param policy
-     *            the policy to be used for obtaining the strong caret.
-     * @return the TextHitInfo for the next caret to the left of the specified
-     *         offset, or null if there is no hit.
-     */
-    public TextHitInfo getNextLeftHit(int offset, TextLayout.CaretPolicy policy) {
-        if (offset < 0 || offset > breaker.getCharCount()) {
-            // awt.195=Offset is out of bounds
-            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
-        }
-
-        TextHitInfo hit = TextHitInfo.afterOffset(offset);
-        TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
-        TextHitInfo nextLeftHit = getNextLeftHit(strongHit);
-
-        if (nextLeftHit != null) {
-            return policy.getStrongCaret(getVisualOtherHit(nextLeftHit), nextLeftHit, this);
-        }
-        return null;
-    }
-
-    /**
-     * Gets the TextHitInfo for the next caret to the right (or down at the end
-     * of the line) of the specified hit.
-     * 
-     * @param hitInfo
-     *            the initial hit.
-     * @return the TextHitInfo for the next caret to the right (or down at the
-     *         end of the line) of the specified hit, or null if there is no
-     *         hit.
-     */
-    public TextHitInfo getNextRightHit(TextHitInfo hitInfo) {
-        breaker.createAllSegments();
-        return caretManager.getNextRightHit(hitInfo);
-    }
-
-    /**
-     * Gets the TextHitInfo for the next caret to the right (or down at the end
-     * of the line) of the specified offset.
-     * 
-     * @param offset
-     *            the offset in this TextLayout.
-     * @return the TextHitInfo for the next caret to the right of the specified
-     *         offset, or null if there is no hit.
-     */
-    public TextHitInfo getNextRightHit(int offset) {
-        return getNextRightHit(offset, DEFAULT_CARET_POLICY);
-    }
-
-    /**
-     * Gets the TextHitInfo for the next caret to the right (or down at the end
-     * of the line) of the specified offset, given the specified caret policy.
-     * 
-     * @param offset
-     *            the offset in this TextLayout.
-     * @param policy
-     *            the policy to be used for obtaining the strong caret.
-     * @return the TextHitInfo for the next caret to the right of the specified
-     *         offset, or null if there is no hit.
-     */
-    public TextHitInfo getNextRightHit(int offset, TextLayout.CaretPolicy policy) {
-        if (offset < 0 || offset > breaker.getCharCount()) {
-            // awt.195=Offset is out of bounds
-            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
-        }
-
-        TextHitInfo hit = TextHitInfo.afterOffset(offset);
-        TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
-        TextHitInfo nextRightHit = getNextRightHit(strongHit);
-
-        if (nextRightHit != null) {
-            return policy.getStrongCaret(getVisualOtherHit(nextRightHit), nextRightHit, this);
-        }
-        return null;
-    }
-
-    /**
-     * Gets the outline of this TextLayout as a Shape.
-     * 
-     * @param xform
-     *            the AffineTransform to be used to transform the outline before
-     *            returning it, or null if no transformation is desired.
-     * @return the outline of this TextLayout as a Shape.
-     */
-    public Shape getOutline(AffineTransform xform) {
-        breaker.createAllSegments();
-
-        GeneralPath outline = breaker.getOutline();
-
-        if (outline != null && xform != null) {
-            outline.transform(xform);
-        }
-
-        return outline;
-    }
-
-    /**
-     * Gets the visible advance of this TextLayout which is defined as diffence
-     * between leading (advance) and trailing whitespace.
-     * 
-     * @return the visible advance of this TextLayout.
-     */
-    public float getVisibleAdvance() {
-        updateMetrics();
-
-        // Trailing whitespace _SHOULD_ be reordered (Unicode spec) to
-        // base direction, so it is also trailing
-        // in logical representation. We use this fact.
-        int lastNonWhitespace = breaker.getLastNonWhitespace();
-
-        if (lastNonWhitespace < 0) {
-            return 0;
-        } else if (lastNonWhitespace == getCharacterCount() - 1) {
-            return getAdvance();
-        } else if (justificationWidth >= 0) { // Layout is justified
-            return justificationWidth;
-        } else {
-            breaker.pushSegments(breaker.getACI().getBeginIndex(), lastNonWhitespace
-                    + breaker.getACI().getBeginIndex() + 1);
-
-            breaker.createAllSegments();
-
-            float visAdvance = tmc.createMetrics().getAdvance();
-
-            breaker.popSegments();
-            return visAdvance;
-        }
-    }
-
-    /**
-     * Gets a Shape which corresponds to the highlighted (selected) area based
-     * on two hit locations within the text and extends to the bounds.
-     * 
-     * @param hit1
-     *            the first text hit location.
-     * @param hit2
-     *            the second text hit location.
-     * @param bounds
-     *            the rectangle that the highlighted area should be extended or
-     *            restricted to.
-     * @return a Shape which corresponds to the highlighted (selected) area.
-     */
-    public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2, Rectangle2D bounds) {
-        return caretManager.getVisualHighlightShape(hit1, hit2, bounds, this);
-    }
-
-    /**
-     * Gets a Shape which corresponds to the highlighted (selected) area based
-     * on two hit locations within the text.
-     * 
-     * @param hit1
-     *            the first text hit location.
-     * @param hit2
-     *            the second text hit location.
-     * @return a Shape which corresponds to the highlighted (selected) area.
-     */
-    public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2) {
-        breaker.createAllSegments();
-        return caretManager.getVisualHighlightShape(hit1, hit2, breaker.getLogicalBounds(), this);
-    }
-
-    /**
-     * Gets the TextHitInfo for a hit on the opposite side of the specified
-     * hit's caret.
-     * 
-     * @param hitInfo
-     *            the specified TextHitInfo.
-     * @return the TextHitInfo for a hit on the opposite side of the specified
-     *         hit's caret.
-     */
-    public TextHitInfo getVisualOtherHit(TextHitInfo hitInfo) {
-        return caretManager.getVisualOtherHit(hitInfo);
-    }
-
-    /**
-     * Justifies the text; this method should be overridden by subclasses.
-     * 
-     * @param justificationWidth
-     *            the width for justification.
-     */
-    protected void handleJustify(float justificationWidth) {
-        float justification = breaker.getJustification();
-
-        if (justification < 0) {
-            // awt.196=Justification impossible, layout already justified
-            throw new IllegalStateException(Messages.getString("awt.196")); //$NON-NLS-1$
-        } else if (justification == 0) {
-            return;
-        }
-
-        float gap = (justificationWidth - getVisibleAdvance()) * justification;
-        breaker.justify(gap);
-        this.justificationWidth = justificationWidth;
-
-        // Correct metrics
-        tmc = new TextMetricsCalculator(breaker);
-        tmc.correctAdvance(metrics);
-    }
-
-    /**
-     * Returns a TextHitInfo object that gives information on which division
-     * point (between two characters) is corresponds to a hit (such as a mouse
-     * click) at the specified coordinates.
-     * 
-     * @param x
-     *            the X coordinate in this TextLayout.
-     * @param y
-     *            the Y coordinate in this TextLayout. TextHitInfo object
-     *            corresponding to the given coordinates within the text.
-     * @return the information about the character at the specified position.
-     */
-    public TextHitInfo hitTestChar(float x, float y) {
-        return hitTestChar(x, y, getBounds());
-    }
-
-    /**
-     * Returns a TextHitInfo object that gives information on which division
-     * point (between two characters) is corresponds to a hit (such as a mouse
-     * click) at the specified coordinates within the specified text rectangle.
-     * 
-     * @param x
-     *            the X coordinate in this TextLayout.
-     * @param y
-     *            the Y coordinate in this TextLayout.
-     * @param bounds
-     *            the bounds of the text area. TextHitInfo object corresponding
-     *            to the given coordinates within the text.
-     * @return the information about the character at the specified position.
-     */
-    public TextHitInfo hitTestChar(float x, float y, Rectangle2D bounds) {
-        if (x > bounds.getMaxX()) {
-            return breaker.isLTR() ? TextHitInfo.trailing(breaker.getCharCount() - 1) : TextHitInfo
-                    .leading(0);
-        }
-
-        if (x < bounds.getMinX()) {
-            return breaker.isLTR() ? TextHitInfo.leading(0) : TextHitInfo.trailing(breaker
-                    .getCharCount() - 1);
-        }
-
-        return breaker.hitTest(x, y);
-    }
-
-    /**
-     * Returns true if this TextLayout has a "left to right" direction.
-     * 
-     * @return true if this TextLayout has a "left to right" direction, false if
-     *         this TextLayout has a "right to left" direction.
-     */
-    public boolean isLeftToRight() {
-        return breaker.isLTR();
-    }
-
-    /**
-     * Returns true if this TextLayout is vertical, false otherwise.
-     * 
-     * @return true if this TextLayout is vertical, false if horizontal.
-     */
-    public boolean isVertical() {
-        return false;
-    }
-}
diff --git a/awt/java/awt/font/TextMeasurer.java b/awt/java/awt/font/TextMeasurer.java
deleted file mode 100644
index 9741f59..0000000
--- a/awt/java/awt/font/TextMeasurer.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/*
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import java.text.AttributedCharacterIterator;
-
-import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
-import org.apache.harmony.awt.gl.font.TextRunBreaker;
-
-/**
- * The TextMeasurer class provides utilities for line break operations.
- * 
- * @since Android 1.0
- */
-public final class TextMeasurer implements Cloneable {
-
-    /**
-     * The aci.
-     */
-    AttributedCharacterIterator aci;
-
-    /**
-     * The frc.
-     */
-    FontRenderContext frc;
-
-    /**
-     * The breaker.
-     */
-    TextRunBreaker breaker = null;
-
-    /**
-     * The tmc.
-     */
-    TextMetricsCalculator tmc = null;
-
-    /**
-     * Instantiates a new text measurer from the specified text.
-     * 
-     * @param text
-     *            the source text.
-     * @param frc
-     *            the FontRenderContext.
-     */
-    public TextMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
-        this.aci = text;
-        this.frc = frc;
-        breaker = new TextRunBreaker(aci, this.frc);
-        tmc = new TextMetricsCalculator(breaker);
-    }
-
-    /**
-     * Replaces the current text with the new text, inserting a break character
-     * at the specified insert position.
-     * 
-     * @param newParagraph
-     *            the new paragraph text.
-     * @param insertPos
-     *            the position in the text where the character is inserted.
-     */
-    public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) {
-        AttributedCharacterIterator oldAci = aci;
-        aci = newParagraph;
-        if ((oldAci.getEndIndex() - oldAci.getBeginIndex())
-                - (aci.getEndIndex() - aci.getBeginIndex()) != -1) {
-            breaker = new TextRunBreaker(aci, this.frc);
-            tmc = new TextMetricsCalculator(breaker);
-        } else {
-            breaker.insertChar(newParagraph, insertPos);
-        }
-    }
-
-    /**
-     * Replaces the current text with the new text and deletes a character at
-     * the specified position.
-     * 
-     * @param newParagraph
-     *            the paragraph text after deletion.
-     * @param deletePos
-     *            the position in the text where the character is removed.
-     */
-    public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) {
-        AttributedCharacterIterator oldAci = aci;
-        aci = newParagraph;
-        if ((oldAci.getEndIndex() - oldAci.getBeginIndex())
-                - (aci.getEndIndex() - aci.getBeginIndex()) != 1) {
-            breaker = new TextRunBreaker(aci, this.frc);
-            tmc = new TextMetricsCalculator(breaker);
-        } else {
-            breaker.deleteChar(newParagraph, deletePos);
-        }
-    }
-
-    /**
-     * Returns a copy of this object.
-     * 
-     * @return a copy of this object.
-     */
-    @Override
-    protected Object clone() {
-        return new TextMeasurer((AttributedCharacterIterator)aci.clone(), frc);
-    }
-
-    /**
-     * Returns a TextLayout of the specified character range.
-     * 
-     * @param start
-     *            the index of the first character.
-     * @param limit
-     *            the index after the last character.
-     * @return a TextLayout for the characters beginning at "start" up to "end".
-     */
-    public TextLayout getLayout(int start, int limit) {
-        breaker.pushSegments(start - aci.getBeginIndex(), limit - aci.getBeginIndex());
-
-        breaker.createAllSegments();
-        TextLayout layout = new TextLayout((TextRunBreaker)breaker.clone());
-
-        breaker.popSegments();
-        return layout;
-    }
-
-    /**
-     * Returns the graphical width of a line beginning at "start" parameter and
-     * including characters up to "end" parameter. "start" and "end" are
-     * absolute indices, not relative to the "start" of the paragraph.
-     * 
-     * @param start
-     *            the character index at which to start measuring.
-     * @param end
-     *            the character index at which to stop measuring.
-     * @return the graphical width of a line beginning at "start" and including
-     *         characters up to "end".
-     */
-    public float getAdvanceBetween(int start, int end) {
-        breaker.pushSegments(start - aci.getBeginIndex(), end - aci.getBeginIndex());
-
-        breaker.createAllSegments();
-        float retval = tmc.createMetrics().getAdvance();
-
-        breaker.popSegments();
-        return retval;
-    }
-
-    /**
-     * Returns the index of the first character which is not fit on a line
-     * beginning at start and possible measuring up to maxAdvance in graphical
-     * width.
-     * 
-     * @param start
-     *            he character index at which to start measuring.
-     * @param maxAdvance
-     *            the graphical width in which the line must fit.
-     * @return the index after the last character that is fit on a line
-     *         beginning at start, which is not longer than maxAdvance in
-     *         graphical width.
-     */
-    public int getLineBreakIndex(int start, float maxAdvance) {
-        breaker.createAllSegments();
-        return breaker.getLineBreakIndex(start - aci.getBeginIndex(), maxAdvance)
-                + aci.getBeginIndex();
-    }
-}
diff --git a/awt/java/awt/font/TransformAttribute.java b/awt/java/awt/font/TransformAttribute.java
deleted file mode 100644
index ff2caa2..0000000
--- a/awt/java/awt/font/TransformAttribute.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package java.awt.font;
-
-import java.awt.geom.AffineTransform;
-import java.io.Serializable;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The TransformAttribute class is a wrapper for the AffineTransform class in
- * order to use it as attribute.
- * 
- * @since Android 1.0
- */
-public final class TransformAttribute implements Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 3356247357827709530L;
-
-    // affine transform of this TransformAttribute instance
-    /**
-     * The transform.
-     */
-    private AffineTransform fTransform;
-
-    /**
-     * Instantiates a new TransformAttribute from the specified AffineTransform.
-     * 
-     * @param transform
-     *            the AffineTransform to be wrapped.
-     */
-    public TransformAttribute(AffineTransform transform) {
-        if (transform == null) {
-            // awt.94=transform can not be null
-            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
-        }
-        if (!transform.isIdentity()) {
-            this.fTransform = new AffineTransform(transform);
-        }
-    }
-
-    /**
-     * Gets the initial AffineTransform which is wrapped.
-     * 
-     * @return the initial AffineTransform which is wrapped.
-     */
-    public AffineTransform getTransform() {
-        if (fTransform != null) {
-            return new AffineTransform(fTransform);
-        }
-        return new AffineTransform();
-    }
-
-    /**
-     * Checks if this transform is an identity transform.
-     * 
-     * @return true, if this transform is an identity transform, false
-     *         otherwise.
-     */
-    public boolean isIdentity() {
-        return (fTransform == null);
-    }
-
-}
diff --git a/awt/java/awt/font/package.html b/awt/java/awt/font/package.html
deleted file mode 100644
index 788dcc0..0000000
--- a/awt/java/awt/font/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes to support the representation of different types of fonts for example TrueType fonts.
-    </p>
-    @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/geom/AffineTransform.java b/awt/java/awt/geom/AffineTransform.java
deleted file mode 100644
index 8a6938c..0000000
--- a/awt/java/awt/geom/AffineTransform.java
+++ /dev/null
@@ -1,1267 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.awt.Shape;
-import java.io.IOException;
-import java.io.Serializable;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.misc.HashCode;
-
-/**
- * The Class AffineTransform represents a linear transformation (rotation,
- * scaling, or shear) followed by a translation that acts on a coordinate space.
- * It preserves collinearity of points and ratios of distances between collinear
- * points: so if A, B, and C are on a line, then after the space has been
- * transformed via the affine transform, the images of the three points will
- * still be on a line, and the ratio of the distance from A to B with the
- * distance from B to C will be the same as the corresponding ratio in the image
- * space.
- * 
- * @since Android 1.0
- */
-public class AffineTransform implements Cloneable, Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 1330973210523860834L;
-
-    /**
-     * The Constant TYPE_IDENTITY.
-     */
-    public static final int TYPE_IDENTITY = 0;
-
-    /**
-     * The Constant TYPE_TRANSLATION.
-     */
-    public static final int TYPE_TRANSLATION = 1;
-
-    /**
-     * The Constant TYPE_UNIFORM_SCALE.
-     */
-    public static final int TYPE_UNIFORM_SCALE = 2;
-
-    /**
-     * The Constant TYPE_GENERAL_SCALE.
-     */
-    public static final int TYPE_GENERAL_SCALE = 4;
-
-    /**
-     * The Constant TYPE_QUADRANT_ROTATION.
-     */
-    public static final int TYPE_QUADRANT_ROTATION = 8;
-
-    /**
-     * The Constant TYPE_GENERAL_ROTATION.
-     */
-    public static final int TYPE_GENERAL_ROTATION = 16;
-
-    /**
-     * The Constant TYPE_GENERAL_TRANSFORM.
-     */
-    public static final int TYPE_GENERAL_TRANSFORM = 32;
-
-    /**
-     * The Constant TYPE_FLIP.
-     */
-    public static final int TYPE_FLIP = 64;
-
-    /**
-     * The Constant TYPE_MASK_SCALE.
-     */
-    public static final int TYPE_MASK_SCALE = TYPE_UNIFORM_SCALE | TYPE_GENERAL_SCALE;
-
-    /**
-     * The Constant TYPE_MASK_ROTATION.
-     */
-    public static final int TYPE_MASK_ROTATION = TYPE_QUADRANT_ROTATION | TYPE_GENERAL_ROTATION;
-
-    /**
-     * The <code>TYPE_UNKNOWN</code> is an initial type value.
-     */
-    static final int TYPE_UNKNOWN = -1;
-
-    /**
-     * The min value equivalent to zero. If absolute value less then ZERO it
-     * considered as zero.
-     */
-    static final double ZERO = 1E-10;
-
-    /**
-     * The values of transformation matrix.
-     */
-    double m00;
-
-    /**
-     * The m10.
-     */
-    double m10;
-
-    /**
-     * The m01.
-     */
-    double m01;
-
-    /**
-     * The m11.
-     */
-    double m11;
-
-    /**
-     * The m02.
-     */
-    double m02;
-
-    /**
-     * The m12.
-     */
-    double m12;
-
-    /**
-     * The transformation <code>type</code>.
-     */
-    transient int type;
-
-    /**
-     * Instantiates a new affine transform of type <code>TYPE_IDENTITY</code>
-     * (which leaves coordinates unchanged).
-     */
-    public AffineTransform() {
-        type = TYPE_IDENTITY;
-        m00 = m11 = 1.0;
-        m10 = m01 = m02 = m12 = 0.0;
-    }
-
-    /**
-     * Instantiates a new affine transform that has the same data as the given
-     * AffineTransform.
-     * 
-     * @param t
-     *            the transform to copy.
-     */
-    public AffineTransform(AffineTransform t) {
-        this.type = t.type;
-        this.m00 = t.m00;
-        this.m10 = t.m10;
-        this.m01 = t.m01;
-        this.m11 = t.m11;
-        this.m02 = t.m02;
-        this.m12 = t.m12;
-    }
-
-    /**
-     * Instantiates a new affine transform by specifying the values of the 2x3
-     * transformation matrix as floats. The type is set to the default type:
-     * <code>TYPE_UNKNOWN</code>
-     * 
-     * @param m00
-     *            the m00 entry in the transformation matrix.
-     * @param m10
-     *            the m10 entry in the transformation matrix.
-     * @param m01
-     *            the m01 entry in the transformation matrix.
-     * @param m11
-     *            the m11 entry in the transformation matrix.
-     * @param m02
-     *            the m02 entry in the transformation matrix.
-     * @param m12
-     *            the m12 entry in the transformation matrix.
-     */
-    public AffineTransform(float m00, float m10, float m01, float m11, float m02, float m12) {
-        this.type = TYPE_UNKNOWN;
-        this.m00 = m00;
-        this.m10 = m10;
-        this.m01 = m01;
-        this.m11 = m11;
-        this.m02 = m02;
-        this.m12 = m12;
-    }
-
-    /**
-     * Instantiates a new affine transform by specifying the values of the 2x3
-     * transformation matrix as doubles. The type is set to the default type:
-     * <code>TYPE_UNKNOWN</code>
-     * 
-     * @param m00
-     *            the m00 entry in the transformation matrix.
-     * @param m10
-     *            the m10 entry in the transformation matrix.
-     * @param m01
-     *            the m01 entry in the transformation matrix.
-     * @param m11
-     *            the m11 entry in the transformation matrix.
-     * @param m02
-     *            the m02 entry in the transformation matrix.
-     * @param m12
-     *            the m12 entry in the transformation matrix.
-     */
-    public AffineTransform(double m00, double m10, double m01, double m11, double m02, double m12) {
-        this.type = TYPE_UNKNOWN;
-        this.m00 = m00;
-        this.m10 = m10;
-        this.m01 = m01;
-        this.m11 = m11;
-        this.m02 = m02;
-        this.m12 = m12;
-    }
-
-    /**
-     * Instantiates a new affine transform by reading the values of the
-     * transformation matrix from an array of floats. The mapping from the array
-     * to the matrix starts with <code>matrix[0]</code> giving the top-left
-     * entry of the matrix and proceeds with the usual left-to-right and
-     * top-down ordering.
-     * <p>
-     * If the array has only four entries, then the two entries of the last row
-     * of the transformation matrix default to zero.
-     * 
-     * @param matrix
-     *            the array of four or six floats giving the values of the
-     *            matrix.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if the size of the array is 0, 1, 2, 3, or 5.
-     */
-    public AffineTransform(float[] matrix) {
-        this.type = TYPE_UNKNOWN;
-        m00 = matrix[0];
-        m10 = matrix[1];
-        m01 = matrix[2];
-        m11 = matrix[3];
-        if (matrix.length > 4) {
-            m02 = matrix[4];
-            m12 = matrix[5];
-        }
-    }
-
-    /**
-     * Instantiates a new affine transform by reading the values of the
-     * transformation matrix from an array of doubles. The mapping from the
-     * array to the matrix starts with <code>matrix[0]</code> giving the
-     * top-left entry of the matrix and proceeds with the usual left-to-right
-     * and top-down ordering.
-     * <p>
-     * If the array has only four entries, then the two entries of the last row
-     * of the transformation matrix default to zero.
-     * 
-     * @param matrix
-     *            the array of four or six doubles giving the values of the
-     *            matrix.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if the size of the array is 0, 1, 2, 3, or 5.
-     */
-    public AffineTransform(double[] matrix) {
-        this.type = TYPE_UNKNOWN;
-        m00 = matrix[0];
-        m10 = matrix[1];
-        m01 = matrix[2];
-        m11 = matrix[3];
-        if (matrix.length > 4) {
-            m02 = matrix[4];
-            m12 = matrix[5];
-        }
-    }
-
-    /**
-     * Returns type of the affine transformation.
-     * <p>
-     * The type is computed as follows: Label the entries of the transformation
-     * matrix as three rows (m00, m01), (m10, m11), and (m02, m12). Then if the
-     * original basis vectors are (1, 0) and (0, 1), the new basis vectors after
-     * transformation are given by (m00, m01) and (m10, m11), and the
-     * translation vector is (m02, m12).
-     * <p>
-     * The types are classified as follows: <br/> TYPE_IDENTITY - no change<br/>
-     * TYPE_TRANSLATION - The translation vector isn't zero<br/>
-     * TYPE_UNIFORM_SCALE - The new basis vectors have equal length<br/>
-     * TYPE_GENERAL_SCALE - The new basis vectors dont' have equal length<br/>
-     * TYPE_FLIP - The new basis vector orientation differs from the original
-     * one<br/> TYPE_QUADRANT_ROTATION - The new basis is a rotation of the
-     * original by 90, 180, 270, or 360 degrees<br/> TYPE_GENERAL_ROTATION - The
-     * new basis is a rotation of the original by an arbitrary angle<br/>
-     * TYPE_GENERAL_TRANSFORM - The transformation can't be inverted.<br/>
-     * <p>
-     * Note that multiple types are possible, thus the types can be combined
-     * using bitwise combinations.
-     * 
-     * @return the type of the Affine Transform.
-     */
-    public int getType() {
-        if (type != TYPE_UNKNOWN) {
-            return type;
-        }
-
-        int type = 0;
-
-        if (m00 * m01 + m10 * m11 != 0.0) {
-            type |= TYPE_GENERAL_TRANSFORM;
-            return type;
-        }
-
-        if (m02 != 0.0 || m12 != 0.0) {
-            type |= TYPE_TRANSLATION;
-        } else if (m00 == 1.0 && m11 == 1.0 && m01 == 0.0 && m10 == 0.0) {
-            type = TYPE_IDENTITY;
-            return type;
-        }
-
-        if (m00 * m11 - m01 * m10 < 0.0) {
-            type |= TYPE_FLIP;
-        }
-
-        double dx = m00 * m00 + m10 * m10;
-        double dy = m01 * m01 + m11 * m11;
-        if (dx != dy) {
-            type |= TYPE_GENERAL_SCALE;
-        } else if (dx != 1.0) {
-            type |= TYPE_UNIFORM_SCALE;
-        }
-
-        if ((m00 == 0.0 && m11 == 0.0) || (m10 == 0.0 && m01 == 0.0 && (m00 < 0.0 || m11 < 0.0))) {
-            type |= TYPE_QUADRANT_ROTATION;
-        } else if (m01 != 0.0 || m10 != 0.0) {
-            type |= TYPE_GENERAL_ROTATION;
-        }
-
-        return type;
-    }
-
-    /**
-     * Gets the scale x entry of the transformation matrix (the upper left
-     * matrix entry).
-     * 
-     * @return the scale x value.
-     */
-    public double getScaleX() {
-        return m00;
-    }
-
-    /**
-     * Gets the scale y entry of the transformation matrix (the lower right
-     * entry of the linear transformation).
-     * 
-     * @return the scale y value.
-     */
-    public double getScaleY() {
-        return m11;
-    }
-
-    /**
-     * Gets the shear x entry of the transformation matrix (the upper right
-     * entry of the linear transformation).
-     * 
-     * @return the shear x value.
-     */
-    public double getShearX() {
-        return m01;
-    }
-
-    /**
-     * Gets the shear y entry of the transformation matrix (the lower left entry
-     * of the linear transformation).
-     * 
-     * @return the shear y value.
-     */
-    public double getShearY() {
-        return m10;
-    }
-
-    /**
-     * Gets the x coordinate of the translation vector.
-     * 
-     * @return the x coordinate of the translation vector.
-     */
-    public double getTranslateX() {
-        return m02;
-    }
-
-    /**
-     * Gets the y coordinate of the translation vector.
-     * 
-     * @return the y coordinate of the translation vector.
-     */
-    public double getTranslateY() {
-        return m12;
-    }
-
-    /**
-     * Checks if the AffineTransformation is the identity.
-     * 
-     * @return true, if the AffineTransformation is the identity.
-     */
-    public boolean isIdentity() {
-        return getType() == TYPE_IDENTITY;
-    }
-
-    /**
-     * Writes the values of the transformation matrix into the given array of
-     * doubles. If the array has length 4, only the linear transformation part
-     * will be written into it. If it has length greater than 4, the translation
-     * vector will be included as well.
-     * 
-     * @param matrix
-     *            the array to fill with the values of the matrix.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if the size of the array is 0, 1, 2, 3, or 5.
-     */
-    public void getMatrix(double[] matrix) {
-        matrix[0] = m00;
-        matrix[1] = m10;
-        matrix[2] = m01;
-        matrix[3] = m11;
-        if (matrix.length > 4) {
-            matrix[4] = m02;
-            matrix[5] = m12;
-        }
-    }
-
-    /**
-     * Gets the determinant of the linear transformation matrix.
-     * 
-     * @return the determinant of the linear transformation matrix.
-     */
-    public double getDeterminant() {
-        return m00 * m11 - m01 * m10;
-    }
-
-    /**
-     * Sets the transform in terms of a list of double values.
-     * 
-     * @param m00
-     *            the m00 coordinate of the transformation matrix.
-     * @param m10
-     *            the m10 coordinate of the transformation matrix.
-     * @param m01
-     *            the m01 coordinate of the transformation matrix.
-     * @param m11
-     *            the m11 coordinate of the transformation matrix.
-     * @param m02
-     *            the m02 coordinate of the transformation matrix.
-     * @param m12
-     *            the m12 coordinate of the transformation matrix.
-     */
-    public void setTransform(double m00, double m10, double m01, double m11, double m02, double m12) {
-        this.type = TYPE_UNKNOWN;
-        this.m00 = m00;
-        this.m10 = m10;
-        this.m01 = m01;
-        this.m11 = m11;
-        this.m02 = m02;
-        this.m12 = m12;
-    }
-
-    /**
-     * Sets the transform's data to match the data of the transform sent as a
-     * parameter.
-     * 
-     * @param t
-     *            the transform that gives the new values.
-     */
-    public void setTransform(AffineTransform t) {
-        type = t.type;
-        setTransform(t.m00, t.m10, t.m01, t.m11, t.m02, t.m12);
-    }
-
-    /**
-     * Sets the transform to the identity transform.
-     */
-    public void setToIdentity() {
-        type = TYPE_IDENTITY;
-        m00 = m11 = 1.0;
-        m10 = m01 = m02 = m12 = 0.0;
-    }
-
-    /**
-     * Sets the transformation to a translation alone. Sets the linear part of
-     * the transformation to identity and the translation vector to the values
-     * sent as parameters. Sets the type to <code>TYPE_IDENTITY</code> if the
-     * resulting AffineTransformation is the identity transformation, otherwise
-     * sets it to <code>TYPE_TRANSLATION</code>.
-     * 
-     * @param mx
-     *            the distance to translate in the x direction.
-     * @param my
-     *            the distance to translate in the y direction.
-     */
-    public void setToTranslation(double mx, double my) {
-        m00 = m11 = 1.0;
-        m01 = m10 = 0.0;
-        m02 = mx;
-        m12 = my;
-        if (mx == 0.0 && my == 0.0) {
-            type = TYPE_IDENTITY;
-        } else {
-            type = TYPE_TRANSLATION;
-        }
-    }
-
-    /**
-     * Sets the transformation to being a scale alone, eliminating rotation,
-     * shear, and translation elements. Sets the type to
-     * <code>TYPE_IDENTITY</code> if the resulting AffineTransformation is the
-     * identity transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
-     * 
-     * @param scx
-     *            the scaling factor in the x direction.
-     * @param scy
-     *            the scaling factor in the y direction.
-     */
-    public void setToScale(double scx, double scy) {
-        m00 = scx;
-        m11 = scy;
-        m10 = m01 = m02 = m12 = 0.0;
-        if (scx != 1.0 || scy != 1.0) {
-            type = TYPE_UNKNOWN;
-        } else {
-            type = TYPE_IDENTITY;
-        }
-    }
-
-    /**
-     * Sets the transformation to being a shear alone, eliminating rotation,
-     * scaling, and translation elements. Sets the type to
-     * <code>TYPE_IDENTITY</code> if the resulting AffineTransformation is the
-     * identity transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
-     * 
-     * @param shx
-     *            the shearing factor in the x direction.
-     * @param shy
-     *            the shearing factor in the y direction.
-     */
-    public void setToShear(double shx, double shy) {
-        m00 = m11 = 1.0;
-        m02 = m12 = 0.0;
-        m01 = shx;
-        m10 = shy;
-        if (shx != 0.0 || shy != 0.0) {
-            type = TYPE_UNKNOWN;
-        } else {
-            type = TYPE_IDENTITY;
-        }
-    }
-
-    /**
-     * Sets the transformation to being a rotation alone, eliminating shearing,
-     * scaling, and translation elements. Sets the type to
-     * <code>TYPE_IDENTITY</code> if the resulting AffineTransformation is the
-     * identity transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
-     * 
-     * @param angle
-     *            the angle of rotation in radians.
-     */
-    public void setToRotation(double angle) {
-        double sin = Math.sin(angle);
-        double cos = Math.cos(angle);
-        if (Math.abs(cos) < ZERO) {
-            cos = 0.0;
-            sin = sin > 0.0 ? 1.0 : -1.0;
-        } else if (Math.abs(sin) < ZERO) {
-            sin = 0.0;
-            cos = cos > 0.0 ? 1.0 : -1.0;
-        }
-        m00 = m11 = cos;
-        m01 = -sin;
-        m10 = sin;
-        m02 = m12 = 0.0;
-        type = TYPE_UNKNOWN;
-    }
-
-    /**
-     * Sets the transformation to being a rotation followed by a translation.
-     * Sets the type to <code>TYPE_UNKNOWN</code>.
-     * 
-     * @param angle
-     *            the angle of rotation in radians.
-     * @param px
-     *            the distance to translate in the x direction.
-     * @param py
-     *            the distance to translate in the y direction.
-     */
-    public void setToRotation(double angle, double px, double py) {
-        setToRotation(angle);
-        m02 = px * (1.0 - m00) + py * m10;
-        m12 = py * (1.0 - m00) - px * m10;
-        type = TYPE_UNKNOWN;
-    }
-
-    /**
-     * Creates a new AffineTransformation that is a translation alone with the
-     * translation vector given by the values sent as parameters. The new
-     * transformation's type is <code>TYPE_IDENTITY</code> if the
-     * AffineTransformation is the identity transformation, otherwise it's
-     * <code>TYPE_TRANSLATION</code>.
-     * 
-     * @param mx
-     *            the distance to translate in the x direction.
-     * @param my
-     *            the distance to translate in the y direction.
-     * @return the new AffineTransformation.
-     */
-    public static AffineTransform getTranslateInstance(double mx, double my) {
-        AffineTransform t = new AffineTransform();
-        t.setToTranslation(mx, my);
-        return t;
-    }
-
-    /**
-     * Creates a new AffineTransformation that is a scale alone. The new
-     * transformation's type is <code>TYPE_IDENTITY</code> if the
-     * AffineTransformation is the identity transformation, otherwise it's
-     * <code>TYPE_UNKNOWN</code>.
-     * 
-     * @param scx
-     *            the scaling factor in the x direction.
-     * @param scY
-     *            the scaling factor in the y direction.
-     * @return the new AffineTransformation.
-     */
-    public static AffineTransform getScaleInstance(double scx, double scY) {
-        AffineTransform t = new AffineTransform();
-        t.setToScale(scx, scY);
-        return t;
-    }
-
-    /**
-     * Creates a new AffineTransformation that is a shear alone. The new
-     * transformation's type is <code>TYPE_IDENTITY</code> if the
-     * AffineTransformation is the identity transformation, otherwise it's
-     * <code>TYPE_UNKNOWN</code>.
-     * 
-     * @param shx
-     *            the shearing factor in the x direction.
-     * @param shy
-     *            the shearing factor in the y direction.
-     * @return the new AffineTransformation.
-     */
-    public static AffineTransform getShearInstance(double shx, double shy) {
-        AffineTransform m = new AffineTransform();
-        m.setToShear(shx, shy);
-        return m;
-    }
-
-    /**
-     * Creates a new AffineTransformation that is a rotation alone. The new
-     * transformation's type is <code>TYPE_IDENTITY</code> if the
-     * AffineTransformation is the identity transformation, otherwise it's
-     * <code>TYPE_UNKNOWN</code>.
-     * 
-     * @param angle
-     *            the angle of rotation in radians.
-     * @return the new AffineTransformation.
-     */
-    public static AffineTransform getRotateInstance(double angle) {
-        AffineTransform t = new AffineTransform();
-        t.setToRotation(angle);
-        return t;
-    }
-
-    /**
-     * Creates a new AffineTransformation that is a rotation followed by a
-     * translation. Sets the type to <code>TYPE_UNKNOWN</code>.
-     * 
-     * @param angle
-     *            the angle of rotation in radians.
-     * @param x
-     *            the distance to translate in the x direction.
-     * @param y
-     *            the distance to translate in the y direction.
-     * @return the new AffineTransformation.
-     */
-    public static AffineTransform getRotateInstance(double angle, double x, double y) {
-        AffineTransform t = new AffineTransform();
-        t.setToRotation(angle, x, y);
-        return t;
-    }
-
-    /**
-     * Applies a translation to this AffineTransformation.
-     * 
-     * @param mx
-     *            the distance to translate in the x direction.
-     * @param my
-     *            the distance to translate in the y direction.
-     */
-    public void translate(double mx, double my) {
-        concatenate(AffineTransform.getTranslateInstance(mx, my));
-    }
-
-    /**
-     * Applies a scaling transformation to this AffineTransformation.
-     * 
-     * @param scx
-     *            the scaling factor in the x direction.
-     * @param scy
-     *            the scaling factor in the y direction.
-     */
-    public void scale(double scx, double scy) {
-        concatenate(AffineTransform.getScaleInstance(scx, scy));
-    }
-
-    /**
-     * Applies a shearing transformation to this AffineTransformation.
-     * 
-     * @param shx
-     *            the shearing factor in the x direction.
-     * @param shy
-     *            the shearing factor in the y direction.
-     */
-    public void shear(double shx, double shy) {
-        concatenate(AffineTransform.getShearInstance(shx, shy));
-    }
-
-    /**
-     * Applies a rotation transformation to this AffineTransformation.
-     * 
-     * @param angle
-     *            the angle of rotation in radians.
-     */
-    public void rotate(double angle) {
-        concatenate(AffineTransform.getRotateInstance(angle));
-    }
-
-    /**
-     * Applies a rotation and translation transformation to this
-     * AffineTransformation.
-     * 
-     * @param angle
-     *            the angle of rotation in radians.
-     * @param px
-     *            the distance to translate in the x direction.
-     * @param py
-     *            the distance to translate in the y direction.
-     */
-    public void rotate(double angle, double px, double py) {
-        concatenate(AffineTransform.getRotateInstance(angle, px, py));
-    }
-
-    /**
-     * Multiplies the matrix representations of two AffineTransform objects.
-     * 
-     * @param t1
-     *            - the AffineTransform object is a multiplicand
-     * @param t2
-     *            - the AffineTransform object is a multiplier
-     * @return an AffineTransform object that is the result of t1 multiplied by
-     *         the matrix t2.
-     */
-    AffineTransform multiply(AffineTransform t1, AffineTransform t2) {
-        return new AffineTransform(t1.m00 * t2.m00 + t1.m10 * t2.m01, // m00
-                t1.m00 * t2.m10 + t1.m10 * t2.m11, // m01
-                t1.m01 * t2.m00 + t1.m11 * t2.m01, // m10
-                t1.m01 * t2.m10 + t1.m11 * t2.m11, // m11
-                t1.m02 * t2.m00 + t1.m12 * t2.m01 + t2.m02, // m02
-                t1.m02 * t2.m10 + t1.m12 * t2.m11 + t2.m12);// m12
-    }
-
-    /**
-     * Applies the given AffineTransform to this AffineTransform via matrix
-     * multiplication.
-     * 
-     * @param t
-     *            the AffineTransform to apply to this AffineTransform.
-     */
-    public void concatenate(AffineTransform t) {
-        setTransform(multiply(t, this));
-    }
-
-    /**
-     * Changes the current AffineTransform the one obtained by taking the
-     * transform t and applying this AffineTransform to it.
-     * 
-     * @param t
-     *            the AffineTransform that this AffineTransform is multiplied
-     *            by.
-     */
-    public void preConcatenate(AffineTransform t) {
-        setTransform(multiply(this, t));
-    }
-
-    /**
-     * Creates an AffineTransform that is the inverse of this transform.
-     * 
-     * @return the affine transform that is the inverse of this AffineTransform.
-     * @throws NoninvertibleTransformException
-     *             if this AffineTransform cannot be inverted (the determinant
-     *             of the linear transformation part is zero).
-     */
-    public AffineTransform createInverse() throws NoninvertibleTransformException {
-        double det = getDeterminant();
-        if (Math.abs(det) < ZERO) {
-            // awt.204=Determinant is zero
-            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
-        }
-        return new AffineTransform(m11 / det, // m00
-                -m10 / det, // m10
-                -m01 / det, // m01
-                m00 / det, // m11
-                (m01 * m12 - m11 * m02) / det, // m02
-                (m10 * m02 - m00 * m12) / det // m12
-        );
-    }
-
-    /**
-     * Apply the current AffineTransform to the point.
-     * 
-     * @param src
-     *            the original point.
-     * @param dst
-     *            Point2D object to be filled with the destination coordinates
-     *            (where the original point is sent by this AffineTransform).
-     *            May be null.
-     * @return the point in the AffineTransform's image space where the original
-     *         point is sent.
-     */
-    public Point2D transform(Point2D src, Point2D dst) {
-        if (dst == null) {
-            if (src instanceof Point2D.Double) {
-                dst = new Point2D.Double();
-            } else {
-                dst = new Point2D.Float();
-            }
-        }
-
-        double x = src.getX();
-        double y = src.getY();
-
-        dst.setLocation(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12);
-        return dst;
-    }
-
-    /**
-     * Applies this AffineTransform to an array of points.
-     * 
-     * @param src
-     *            the array of points to be transformed.
-     * @param srcOff
-     *            the offset in the source point array of the first point to be
-     *            transformed.
-     * @param dst
-     *            the point array where the images of the points (after applying
-     *            the AffineTransformation) should be placed.
-     * @param dstOff
-     *            the offset in the destination array where the new values
-     *            should be written.
-     * @param length
-     *            the number of points to transform.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if <code>srcOff + length > src.length</code> or
-     *             <code>dstOff + length > dst.length</code>.
-     */
-    public void transform(Point2D[] src, int srcOff, Point2D[] dst, int dstOff, int length) {
-        while (--length >= 0) {
-            Point2D srcPoint = src[srcOff++];
-            double x = srcPoint.getX();
-            double y = srcPoint.getY();
-            Point2D dstPoint = dst[dstOff];
-            if (dstPoint == null) {
-                if (srcPoint instanceof Point2D.Double) {
-                    dstPoint = new Point2D.Double();
-                } else {
-                    dstPoint = new Point2D.Float();
-                }
-            }
-            dstPoint.setLocation(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12);
-            dst[dstOff++] = dstPoint;
-        }
-    }
-
-    /**
-     * Applies this AffineTransform to a set of points given as an array of
-     * double values where every two values in the array give the coordinates of
-     * a point; the even-indexed values giving the x coordinates and the
-     * odd-indexed values giving the y coordinates.
-     * 
-     * @param src
-     *            the array of points to be transformed.
-     * @param srcOff
-     *            the offset in the source point array of the first point to be
-     *            transformed.
-     * @param dst
-     *            the point array where the images of the points (after applying
-     *            the AffineTransformation) should be placed.
-     * @param dstOff
-     *            the offset in the destination array where the new values
-     *            should be written.
-     * @param length
-     *            the number of points to transform.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if <code>srcOff + length*2 > src.length</code> or
-     *             <code>dstOff + length*2 > dst.length</code>.
-     */
-    public void transform(double[] src, int srcOff, double[] dst, int dstOff, int length) {
-        int step = 2;
-        if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) {
-            srcOff = srcOff + length * 2 - 2;
-            dstOff = dstOff + length * 2 - 2;
-            step = -2;
-        }
-        while (--length >= 0) {
-            double x = src[srcOff + 0];
-            double y = src[srcOff + 1];
-            dst[dstOff + 0] = x * m00 + y * m01 + m02;
-            dst[dstOff + 1] = x * m10 + y * m11 + m12;
-            srcOff += step;
-            dstOff += step;
-        }
-    }
-
-    /**
-     * Applies this AffineTransform to a set of points given as an array of
-     * float values where every two values in the array give the coordinates of
-     * a point; the even-indexed values giving the x coordinates and the
-     * odd-indexed values giving the y coordinates.
-     * 
-     * @param src
-     *            the array of points to be transformed.
-     * @param srcOff
-     *            the offset in the source point array of the first point to be
-     *            transformed.
-     * @param dst
-     *            the point array where the images of the points (after applying
-     *            the AffineTransformation) should be placed.
-     * @param dstOff
-     *            the offset in the destination array where the new values
-     *            should be written.
-     * @param length
-     *            the number of points to transform.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if <code>srcOff + length*2 > src.length</code> or
-     *             <code>dstOff + length*2 > dst.length</code>.
-     */
-    public void transform(float[] src, int srcOff, float[] dst, int dstOff, int length) {
-        int step = 2;
-        if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) {
-            srcOff = srcOff + length * 2 - 2;
-            dstOff = dstOff + length * 2 - 2;
-            step = -2;
-        }
-        while (--length >= 0) {
-            float x = src[srcOff + 0];
-            float y = src[srcOff + 1];
-            dst[dstOff + 0] = (float)(x * m00 + y * m01 + m02);
-            dst[dstOff + 1] = (float)(x * m10 + y * m11 + m12);
-            srcOff += step;
-            dstOff += step;
-        }
-    }
-
-    /**
-     * Applies this AffineTransform to a set of points given as an array of
-     * float values where every two values in the array give the coordinates of
-     * a point; the even-indexed values giving the x coordinates and the
-     * odd-indexed values giving the y coordinates. The destination coordinates
-     * are given as values of type <code>double</code>.
-     * 
-     * @param src
-     *            the array of points to be transformed.
-     * @param srcOff
-     *            the offset in the source point array of the first point to be
-     *            transformed.
-     * @param dst
-     *            the point array where the images of the points (after applying
-     *            the AffineTransformation) should be placed.
-     * @param dstOff
-     *            the offset in the destination array where the new values
-     *            should be written.
-     * @param length
-     *            the number of points to transform.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if <code>srcOff + length*2 > src.length</code> or
-     *             <code>dstOff + length*2 > dst.length</code>.
-     */
-    public void transform(float[] src, int srcOff, double[] dst, int dstOff, int length) {
-        while (--length >= 0) {
-            float x = src[srcOff++];
-            float y = src[srcOff++];
-            dst[dstOff++] = x * m00 + y * m01 + m02;
-            dst[dstOff++] = x * m10 + y * m11 + m12;
-        }
-    }
-
-    /**
-     * Applies this AffineTransform to a set of points given as an array of
-     * double values where every two values in the array give the coordinates of
-     * a point; the even-indexed values giving the x coordinates and the
-     * odd-indexed values giving the y coordinates. The destination coordinates
-     * are given as values of type <code>float</code>.
-     * 
-     * @param src
-     *            the array of points to be transformed.
-     * @param srcOff
-     *            the offset in the source point array of the first point to be
-     *            transformed.
-     * @param dst
-     *            the point array where the images of the points (after applying
-     *            the AffineTransformation) should be placed.
-     * @param dstOff
-     *            the offset in the destination array where the new values
-     *            should be written.
-     * @param length
-     *            the number of points to transform.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if <code>srcOff + length*2 > src.length</code> or
-     *             <code>dstOff + length*2 > dst.length</code>.
-     */
-    public void transform(double[] src, int srcOff, float[] dst, int dstOff, int length) {
-        while (--length >= 0) {
-            double x = src[srcOff++];
-            double y = src[srcOff++];
-            dst[dstOff++] = (float)(x * m00 + y * m01 + m02);
-            dst[dstOff++] = (float)(x * m10 + y * m11 + m12);
-        }
-    }
-
-    /**
-     * Transforms the point according to the linear transformation part of this
-     * AffineTransformation (without applying the translation).
-     * 
-     * @param src
-     *            the original point.
-     * @param dst
-     *            the point object where the result of the delta transform is
-     *            written.
-     * @return the result of applying the delta transform (linear part only) to
-     *         the original point.
-     */
-    // TODO: is this right? if dst is null, we check what it's an
-    // instance of? Shouldn't it be src instanceof Point2D.Double?
-    public Point2D deltaTransform(Point2D src, Point2D dst) {
-        if (dst == null) {
-            if (dst instanceof Point2D.Double) {
-                dst = new Point2D.Double();
-            } else {
-                dst = new Point2D.Float();
-            }
-        }
-
-        double x = src.getX();
-        double y = src.getY();
-
-        dst.setLocation(x * m00 + y * m01, x * m10 + y * m11);
-        return dst;
-    }
-
-    /**
-     * Applies the linear transformation part of this AffineTransform (ignoring
-     * the translation part) to a set of points given as an array of double
-     * values where every two values in the array give the coordinates of a
-     * point; the even-indexed values giving the x coordinates and the
-     * odd-indexed values giving the y coordinates.
-     * 
-     * @param src
-     *            the array of points to be transformed.
-     * @param srcOff
-     *            the offset in the source point array of the first point to be
-     *            transformed.
-     * @param dst
-     *            the point array where the images of the points (after applying
-     *            the delta transformation) should be placed.
-     * @param dstOff
-     *            the offset in the destination array where the new values
-     *            should be written.
-     * @param length
-     *            the number of points to transform.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if <code>srcOff + length*2 > src.length</code> or
-     *             <code>dstOff + length*2 > dst.length</code>.
-     */
-    public void deltaTransform(double[] src, int srcOff, double[] dst, int dstOff, int length) {
-        while (--length >= 0) {
-            double x = src[srcOff++];
-            double y = src[srcOff++];
-            dst[dstOff++] = x * m00 + y * m01;
-            dst[dstOff++] = x * m10 + y * m11;
-        }
-    }
-
-    /**
-     * Transforms the point according to the inverse of this
-     * AffineTransformation.
-     * 
-     * @param src
-     *            the original point.
-     * @param dst
-     *            the point object where the result of the inverse transform is
-     *            written (may be null).
-     * @return the result of applying the inverse transform. Inverse transform.
-     * @throws NoninvertibleTransformException
-     *             if this AffineTransform cannot be inverted (the determinant
-     *             of the linear transformation part is zero).
-     */
-    public Point2D inverseTransform(Point2D src, Point2D dst)
-            throws NoninvertibleTransformException {
-        double det = getDeterminant();
-        if (Math.abs(det) < ZERO) {
-            // awt.204=Determinant is zero
-            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
-        }
-
-        if (dst == null) {
-            if (src instanceof Point2D.Double) {
-                dst = new Point2D.Double();
-            } else {
-                dst = new Point2D.Float();
-            }
-        }
-
-        double x = src.getX() - m02;
-        double y = src.getY() - m12;
-
-        dst.setLocation((x * m11 - y * m01) / det, (y * m00 - x * m10) / det);
-        return dst;
-    }
-
-    /**
-     * Applies the inverse of this AffineTransform to a set of points given as
-     * an array of double values where every two values in the array give the
-     * coordinates of a point; the even-indexed values giving the x coordinates
-     * and the odd-indexed values giving the y coordinates.
-     * 
-     * @param src
-     *            the array of points to be transformed.
-     * @param srcOff
-     *            the offset in the source point array of the first point to be
-     *            transformed.
-     * @param dst
-     *            the point array where the images of the points (after applying
-     *            the inverse of the AffineTransformation) should be placed.
-     * @param dstOff
-     *            the offset in the destination array where the new values
-     *            should be written.
-     * @param length
-     *            the number of points to transform.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if <code>srcOff + length*2 > src.length</code> or
-     *             <code>dstOff + length*2 > dst.length</code>.
-     * @throws NoninvertibleTransformException
-     *             if this AffineTransform cannot be inverted (the determinant
-     *             of the linear transformation part is zero).
-     */
-    public void inverseTransform(double[] src, int srcOff, double[] dst, int dstOff, int length)
-            throws NoninvertibleTransformException {
-        double det = getDeterminant();
-        if (Math.abs(det) < ZERO) {
-            // awt.204=Determinant is zero
-            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
-        }
-
-        while (--length >= 0) {
-            double x = src[srcOff++] - m02;
-            double y = src[srcOff++] - m12;
-            dst[dstOff++] = (x * m11 - y * m01) / det;
-            dst[dstOff++] = (y * m00 - x * m10) / det;
-        }
-    }
-
-    /**
-     * Creates a new shape whose data is given by applying this AffineTransform
-     * to the specified shape.
-     * 
-     * @param src
-     *            the original shape whose data is to be transformed.
-     * @return the new shape found by applying this AffineTransform to the
-     *         original shape.
-     */
-    public Shape createTransformedShape(Shape src) {
-        if (src == null) {
-            return null;
-        }
-        if (src instanceof GeneralPath) {
-            return ((GeneralPath)src).createTransformedShape(this);
-        }
-        PathIterator path = src.getPathIterator(this);
-        GeneralPath dst = new GeneralPath(path.getWindingRule());
-        dst.append(path, false);
-        return dst;
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getName() + "[[" + m00 + ", " + m01 + ", " + m02 + "], [" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-                + m10 + ", " + m11 + ", " + m12 + "]]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    }
-
-    @Override
-    public Object clone() {
-        try {
-            return super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new InternalError();
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        HashCode hash = new HashCode();
-        hash.append(m00);
-        hash.append(m01);
-        hash.append(m02);
-        hash.append(m10);
-        hash.append(m11);
-        hash.append(m12);
-        return hash.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (obj instanceof AffineTransform) {
-            AffineTransform t = (AffineTransform)obj;
-            return m00 == t.m00 && m01 == t.m01 && m02 == t.m02 && m10 == t.m10 && m11 == t.m11
-                    && m12 == t.m12;
-        }
-        return false;
-    }
-
-    /**
-     * Writes the AffineTrassform object to the output steam.
-     * 
-     * @param stream
-     *            - the output stream.
-     * @throws IOException
-     *             - if there are I/O errors while writing to the output stream.
-     */
-    private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
-        stream.defaultWriteObject();
-    }
-
-    /**
-     * Read the AffineTransform object from the input stream.
-     * 
-     * @param stream
-     *            - the input stream.
-     * @throws IOException
-     *             - if there are I/O errors while reading from the input
-     *             stream.
-     * @throws ClassNotFoundException
-     *             - if class could not be found.
-     */
-    private void readObject(java.io.ObjectInputStream stream) throws IOException,
-            ClassNotFoundException {
-        stream.defaultReadObject();
-        type = TYPE_UNKNOWN;
-    }
-
-}
diff --git a/awt/java/awt/geom/Arc2D.java b/awt/java/awt/geom/Arc2D.java
deleted file mode 100644
index 56f5cd3..0000000
--- a/awt/java/awt/geom/Arc2D.java
+++ /dev/null
@@ -1,1157 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class Arc2D represents a segment of a curve inscribed in a rectangle. The
- * curve is defined by a start angle and an extent angle (the end angle minus
- * the start angle) as a pie wedge whose point is in the center of the
- * rectangle. The Arc2D as a shape may be either OPEN (including nothing but the
- * curved arc segment itself), CHORD (the curved arc segment closed by a
- * connecting segment from the end to the beginning of the arc, or PIE (the
- * segments from the end of the arc to the center of the rectangle and from the
- * center of the rectangle back to the arc's start point are included).
- * 
- * @since Android 1.0
- */
-public abstract class Arc2D extends RectangularShape {
-
-    /**
-     * The arc type OPEN indicates that the shape includes only the curved arc
-     * segment.
-     */
-    public final static int OPEN = 0;
-
-    /**
-     * The arc type CHORD indicates that as a shape the connecting segment from
-     * the end point of the curved arc to the beginning point is included.
-     */
-    public final static int CHORD = 1;
-
-    /**
-     * The arc type PIE indicates that as a shape the two segments from the
-     * arc's endpoint to the center of the rectangle and from the center of the
-     * rectangle to the arc's endpoint are included.
-     */
-    public final static int PIE = 2;
-
-    /**
-     * The Class Float is a subclass of Arc2D in which all of the data values
-     * are given as floats.
-     * 
-     * @see Arc2D.Double
-     * @since Android 1.0
-     */
-    public static class Float extends Arc2D {
-
-        /**
-         * The x coordinate of the upper left corner of the rectangle that
-         * contains the arc.
-         */
-        public float x;
-
-        /**
-         * The y coordinate of the upper left corner of the rectangle that
-         * contains the arc.
-         */
-        public float y;
-
-        /**
-         * The width of the rectangle that contains the arc.
-         */
-        public float width;
-
-        /**
-         * The height of the rectangle that contains the arc.
-         */
-        public float height;
-
-        /**
-         * The start angle of the arc in degrees.
-         */
-        public float start;
-
-        /**
-         * The width angle of the arc in degrees.
-         */
-        public float extent;
-
-        /**
-         * Instantiates a new Arc2D of type OPEN with float values.
-         */
-        public Float() {
-            super(OPEN);
-        }
-
-        /**
-         * Instantiates a new Arc2D of the specified type with float values.
-         * 
-         * @param type
-         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
-         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
-         */
-        public Float(int type) {
-            super(type);
-        }
-
-        /**
-         * Instantiates a Arc2D with the specified float-valued data.
-         * 
-         * @param x
-         *            the x coordinate of the upper left corner of the rectangle
-         *            that contains the arc.
-         * @param y
-         *            the y coordinate of the upper left corner of the rectangle
-         *            that contains the arc.
-         * @param width
-         *            the width of the rectangle that contains the arc.
-         * @param height
-         *            the height of the rectangle that contains the arc.
-         * @param start
-         *            the start angle of the arc in degrees.
-         * @param extent
-         *            the width angle of the arc in degrees.
-         * @param type
-         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
-         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
-         */
-        public Float(float x, float y, float width, float height, float start, float extent,
-                int type) {
-            super(type);
-            this.x = x;
-            this.y = y;
-            this.width = width;
-            this.height = height;
-            this.start = start;
-            this.extent = extent;
-        }
-
-        /**
-         * Instantiates a new Angle2D with the specified float-valued data and
-         * the bounding rectangle given by the parameter bounds.
-         * 
-         * @param bounds
-         *            the bounding rectangle of the Angle2D.
-         * @param start
-         *            the start angle of the arc in degrees.
-         * @param extent
-         *            the width angle of the arc in degrees.
-         * @param type
-         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
-         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
-         */
-        public Float(Rectangle2D bounds, float start, float extent, int type) {
-            super(type);
-            this.x = (float)bounds.getX();
-            this.y = (float)bounds.getY();
-            this.width = (float)bounds.getWidth();
-            this.height = (float)bounds.getHeight();
-            this.start = start;
-            this.extent = extent;
-        }
-
-        @Override
-        public double getX() {
-            return x;
-        }
-
-        @Override
-        public double getY() {
-            return y;
-        }
-
-        @Override
-        public double getWidth() {
-            return width;
-        }
-
-        @Override
-        public double getHeight() {
-            return height;
-        }
-
-        @Override
-        public double getAngleStart() {
-            return start;
-        }
-
-        @Override
-        public double getAngleExtent() {
-            return extent;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return width <= 0.0f || height <= 0.0f;
-        }
-
-        @Override
-        public void setArc(double x, double y, double width, double height, double start,
-                double extent, int type) {
-            this.setArcType(type);
-            this.x = (float)x;
-            this.y = (float)y;
-            this.width = (float)width;
-            this.height = (float)height;
-            this.start = (float)start;
-            this.extent = (float)extent;
-        }
-
-        @Override
-        public void setAngleStart(double start) {
-            this.start = (float)start;
-        }
-
-        @Override
-        public void setAngleExtent(double extent) {
-            this.extent = (float)extent;
-        }
-
-        @Override
-        protected Rectangle2D makeBounds(double x, double y, double width, double height) {
-            return new Rectangle2D.Float((float)x, (float)y, (float)width, (float)height);
-        }
-
-    }
-
-    /**
-     * The Class Double is a subclass of Arc2D in which all of the data values
-     * are given as doubles.
-     * 
-     * @see Arc2D.Float
-     * @since Android 1.0
-     */
-    public static class Double extends Arc2D {
-
-        /**
-         * The x coordinate of the upper left corner of the rectangle that
-         * contains the arc.
-         */
-        public double x;
-
-        /**
-         * The y coordinate of the upper left corner of the rectangle that
-         * contains the arc.
-         */
-        public double y;
-
-        /**
-         * The width of the rectangle that contains the arc.
-         */
-        public double width;
-
-        /**
-         * The height of the rectangle that contains the arc.
-         */
-        public double height;
-
-        /**
-         * The start angle of the arc in degrees.
-         */
-        public double start;
-
-        /**
-         * The width angle of the arc in degrees.
-         */
-        public double extent;
-
-        /**
-         * Instantiates a new Arc2D of type OPEN with double values.
-         */
-        public Double() {
-            super(OPEN);
-        }
-
-        /**
-         * Instantiates a new Arc2D of the specified type with double values.
-         * 
-         * @param type
-         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
-         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
-         */
-        public Double(int type) {
-            super(type);
-        }
-
-        /**
-         * Instantiates a Arc2D with the specified double-valued data.
-         * 
-         * @param x
-         *            the x coordinate of the upper left corner of the rectangle
-         *            that contains the arc.
-         * @param y
-         *            the y coordinate of the upper left corner of the rectangle
-         *            that contains the arc.
-         * @param width
-         *            the width of the rectangle that contains the arc.
-         * @param height
-         *            the height of the rectangle that contains the arc.
-         * @param start
-         *            the start angle of the arc in degrees.
-         * @param extent
-         *            the width angle of the arc in degrees.
-         * @param type
-         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
-         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
-         */
-        public Double(double x, double y, double width, double height, double start, double extent,
-                int type) {
-            super(type);
-            this.x = x;
-            this.y = y;
-            this.width = width;
-            this.height = height;
-            this.start = start;
-            this.extent = extent;
-        }
-
-        /**
-         * Instantiates a new Angle2D with the specified float-valued data and
-         * the bounding rectangle given by the parameter bounds.
-         * 
-         * @param bounds
-         *            the bounding rectangle of the Angle2D.
-         * @param start
-         *            the start angle of the arc in degrees.
-         * @param extent
-         *            the width angle of the arc in degrees.
-         * @param type
-         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
-         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
-         */
-        public Double(Rectangle2D bounds, double start, double extent, int type) {
-            super(type);
-            this.x = bounds.getX();
-            this.y = bounds.getY();
-            this.width = bounds.getWidth();
-            this.height = bounds.getHeight();
-            this.start = start;
-            this.extent = extent;
-        }
-
-        @Override
-        public double getX() {
-            return x;
-        }
-
-        @Override
-        public double getY() {
-            return y;
-        }
-
-        @Override
-        public double getWidth() {
-            return width;
-        }
-
-        @Override
-        public double getHeight() {
-            return height;
-        }
-
-        @Override
-        public double getAngleStart() {
-            return start;
-        }
-
-        @Override
-        public double getAngleExtent() {
-            return extent;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return width <= 0.0 || height <= 0.0;
-        }
-
-        @Override
-        public void setArc(double x, double y, double width, double height, double start,
-                double extent, int type) {
-            this.setArcType(type);
-            this.x = x;
-            this.y = y;
-            this.width = width;
-            this.height = height;
-            this.start = start;
-            this.extent = extent;
-        }
-
-        @Override
-        public void setAngleStart(double start) {
-            this.start = start;
-        }
-
-        @Override
-        public void setAngleExtent(double extent) {
-            this.extent = extent;
-        }
-
-        @Override
-        protected Rectangle2D makeBounds(double x, double y, double width, double height) {
-            return new Rectangle2D.Double(x, y, width, height);
-        }
-
-    }
-
-    /**
-     * The Class Iterator is the subclass of PathIterator that is used to
-     * traverse the boundary of a shape of type Arc2D.
-     */
-    class Iterator implements PathIterator {
-
-        /**
-         * The x coordinate of the center of the arc's bounding rectangle.
-         */
-        double x;
-
-        /**
-         * The y coordinate of the center of the arc's bounding rectangle.
-         */
-        double y;
-
-        /**
-         * Half of the width of the arc's bounding rectangle (the radius in the
-         * case of a circular arc).
-         */
-        double width;
-
-        /**
-         * Half of the height of the arc's bounding rectangle (the radius in the
-         * case of a circular arc).
-         */
-        double height;
-
-        /**
-         * The start angle of the arc in degrees.
-         */
-        double angle;
-
-        /**
-         * The angle extent in degrees.
-         */
-        double extent;
-
-        /**
-         * The closure type of the arc.
-         */
-        int type;
-
-        /**
-         * The path iterator transformation.
-         */
-        AffineTransform t;
-
-        /**
-         * The current segment index.
-         */
-        int index;
-
-        /**
-         * The number of arc segments the source arc subdivided to be
-         * approximated by Bezier curves. Depends on extent value.
-         */
-        int arcCount;
-
-        /**
-         * The number of line segments. Depends on closure type.
-         */
-        int lineCount;
-
-        /**
-         * The step to calculate next arc subdivision point.
-         */
-        double step;
-
-        /**
-         * The temporary value of cosinus of the current angle.
-         */
-        double cos;
-
-        /**
-         * The temporary value of sinus of the current angle.
-         */
-        double sin;
-
-        /** The coefficient to calculate control points of Bezier curves. */
-        double k;
-
-        /**
-         * The temporary value of x coordinate of the Bezier curve control
-         * vector.
-         */
-        double kx;
-
-        /**
-         * The temporary value of y coordinate of the Bezier curve control
-         * vector.
-         */
-        double ky;
-
-        /**
-         * The x coordinate of the first path point (MOVE_TO).
-         */
-        double mx;
-
-        /**
-         * The y coordinate of the first path point (MOVE_TO).
-         */
-        double my;
-
-        /**
-         * Constructs a new Arc2D.Iterator for given line and transformation
-         * 
-         * @param a
-         *            the source Arc2D object.
-         * @param t
-         *            the AffineTransformation.
-         */
-        Iterator(Arc2D a, AffineTransform t) {
-            if (width < 0 || height < 0) {
-                arcCount = 0;
-                lineCount = 0;
-                index = 1;
-                return;
-            }
-
-            this.width = a.getWidth() / 2.0;
-            this.height = a.getHeight() / 2.0;
-            this.x = a.getX() + width;
-            this.y = a.getY() + height;
-            this.angle = -Math.toRadians(a.getAngleStart());
-            this.extent = -a.getAngleExtent();
-            this.type = a.getArcType();
-            this.t = t;
-
-            if (Math.abs(extent) >= 360.0) {
-                arcCount = 4;
-                k = 4.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
-                step = Math.PI / 2.0;
-                if (extent < 0.0) {
-                    step = -step;
-                    k = -k;
-                }
-            } else {
-                arcCount = (int)Math.rint(Math.abs(extent) / 90.0);
-                step = Math.toRadians(extent / arcCount);
-                k = 4.0 / 3.0 * (1.0 - Math.cos(step / 2.0)) / Math.sin(step / 2.0);
-            }
-
-            lineCount = 0;
-            if (type == Arc2D.CHORD) {
-                lineCount++;
-            } else if (type == Arc2D.PIE) {
-                lineCount += 2;
-            }
-        }
-
-        public int getWindingRule() {
-            return WIND_NON_ZERO;
-        }
-
-        public boolean isDone() {
-            return index > arcCount + lineCount;
-        }
-
-        public void next() {
-            index++;
-        }
-
-        public int currentSegment(double[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type;
-            int count;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                count = 1;
-                cos = Math.cos(angle);
-                sin = Math.sin(angle);
-                kx = k * width * sin;
-                ky = k * height * cos;
-                coords[0] = mx = x + cos * width;
-                coords[1] = my = y + sin * height;
-            } else if (index <= arcCount) {
-                type = SEG_CUBICTO;
-                count = 3;
-                coords[0] = mx - kx;
-                coords[1] = my + ky;
-                angle += step;
-                cos = Math.cos(angle);
-                sin = Math.sin(angle);
-                kx = k * width * sin;
-                ky = k * height * cos;
-                coords[4] = mx = x + cos * width;
-                coords[5] = my = y + sin * height;
-                coords[2] = mx + kx;
-                coords[3] = my - ky;
-            } else if (index == arcCount + lineCount) {
-                type = SEG_CLOSE;
-                count = 0;
-            } else {
-                type = SEG_LINETO;
-                count = 1;
-                coords[0] = x;
-                coords[1] = y;
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, count);
-            }
-            return type;
-        }
-
-        public int currentSegment(float[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type;
-            int count;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                count = 1;
-                cos = Math.cos(angle);
-                sin = Math.sin(angle);
-                kx = k * width * sin;
-                ky = k * height * cos;
-                coords[0] = (float)(mx = x + cos * width);
-                coords[1] = (float)(my = y + sin * height);
-            } else if (index <= arcCount) {
-                type = SEG_CUBICTO;
-                count = 3;
-                coords[0] = (float)(mx - kx);
-                coords[1] = (float)(my + ky);
-                angle += step;
-                cos = Math.cos(angle);
-                sin = Math.sin(angle);
-                kx = k * width * sin;
-                ky = k * height * cos;
-                coords[4] = (float)(mx = x + cos * width);
-                coords[5] = (float)(my = y + sin * height);
-                coords[2] = (float)(mx + kx);
-                coords[3] = (float)(my - ky);
-            } else if (index == arcCount + lineCount) {
-                type = SEG_CLOSE;
-                count = 0;
-            } else {
-                type = SEG_LINETO;
-                count = 1;
-                coords[0] = (float)x;
-                coords[1] = (float)y;
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, count);
-            }
-            return type;
-        }
-
-    }
-
-    /**
-     * The closure type of the arc.
-     */
-    private int type;
-
-    /**
-     * Instantiates a new arc2D.
-     * 
-     * @param type
-     *            the closure type.
-     */
-    protected Arc2D(int type) {
-        setArcType(type);
-    }
-
-    /**
-     * Takes the double-valued data and creates the corresponding Rectangle2D
-     * object with values either of type float or of type double depending on
-     * whether this Arc2D instance is of type Float or Double.
-     * 
-     * @param x
-     *            the x coordinate of the upper left corner of the bounding
-     *            rectangle.
-     * @param y
-     *            the y coordinate of the upper left corner of the bounding
-     *            rectangle.
-     * @param width
-     *            the width of the bounding rectangle.
-     * @param height
-     *            the height of the bounding rectangle.
-     * @return the corresponding Rectangle2D object.
-     */
-    protected abstract Rectangle2D makeBounds(double x, double y, double width, double height);
-
-    /**
-     * Gets the start angle.
-     * 
-     * @return the start angle.
-     */
-    public abstract double getAngleStart();
-
-    /**
-     * Gets the width angle.
-     * 
-     * @return the width angle.
-     */
-    public abstract double getAngleExtent();
-
-    /**
-     * Sets the start angle.
-     * 
-     * @param start
-     *            the new start angle.
-     */
-    public abstract void setAngleStart(double start);
-
-    /**
-     * Sets the width angle.
-     * 
-     * @param extent
-     *            the new width angle.
-     */
-    public abstract void setAngleExtent(double extent);
-
-    /**
-     * Sets the data values that define the arc.
-     * 
-     * @param x
-     *            the x coordinate of the upper left corner of the rectangle
-     *            that contains the arc.
-     * @param y
-     *            the y coordinate of the upper left corner of the rectangle
-     *            that contains the arc.
-     * @param width
-     *            the width of the rectangle that contains the arc.
-     * @param height
-     *            the height of the rectangle that contains the arc.
-     * @param start
-     *            the start angle of the arc in degrees.
-     * @param extent
-     *            the width angle of the arc in degrees.
-     * @param type
-     *            the type of the new Arc2D, either {@link Arc2D#OPEN},
-     *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
-     */
-    public abstract void setArc(double x, double y, double width, double height, double start,
-            double extent, int type);
-
-    /**
-     * Gets the arc type, either {@link Arc2D#OPEN}, {@link Arc2D#CHORD}, or
-     * {@link Arc2D#PIE}.
-     * 
-     * @return the arc type.
-     */
-    public int getArcType() {
-        return type;
-    }
-
-    /**
-     * Sets the arc type, either {@link Arc2D#OPEN}, {@link Arc2D#CHORD}, or
-     * {@link Arc2D#PIE}.
-     * 
-     * @param type
-     *            the new arc type.
-     */
-    public void setArcType(int type) {
-        if (type != OPEN && type != CHORD && type != PIE) {
-            // awt.205=Invalid type of Arc: {0}
-            throw new IllegalArgumentException(Messages.getString("awt.205", type)); //$NON-NLS-1$
-        }
-        this.type = type;
-    }
-
-    /**
-     * Gets the start point of the arc as a Point2D.
-     * 
-     * @return the start point of the curved arc segment.
-     */
-    public Point2D getStartPoint() {
-        double a = Math.toRadians(getAngleStart());
-        return new Point2D.Double(getX() + (1.0 + Math.cos(a)) * getWidth() / 2.0, getY()
-                + (1.0 - Math.sin(a)) * getHeight() / 2.0);
-    }
-
-    /**
-     * Gets the end point of the arc as a Point2D.
-     * 
-     * @return the end point of the curved arc segment.
-     */
-    public Point2D getEndPoint() {
-        double a = Math.toRadians(getAngleStart() + getAngleExtent());
-        return new Point2D.Double(getX() + (1.0 + Math.cos(a)) * getWidth() / 2.0, getY()
-                + (1.0 - Math.sin(a)) * getHeight() / 2.0);
-    }
-
-    public Rectangle2D getBounds2D() {
-        if (isEmpty()) {
-            return makeBounds(getX(), getY(), getWidth(), getHeight());
-        }
-        double rx1 = getX();
-        double ry1 = getY();
-        double rx2 = rx1 + getWidth();
-        double ry2 = ry1 + getHeight();
-
-        Point2D p1 = getStartPoint();
-        Point2D p2 = getEndPoint();
-
-        double bx1 = containsAngle(180.0) ? rx1 : Math.min(p1.getX(), p2.getX());
-        double by1 = containsAngle(90.0) ? ry1 : Math.min(p1.getY(), p2.getY());
-        double bx2 = containsAngle(0.0) ? rx2 : Math.max(p1.getX(), p2.getX());
-        double by2 = containsAngle(270.0) ? ry2 : Math.max(p1.getY(), p2.getY());
-
-        if (type == PIE) {
-            double cx = getCenterX();
-            double cy = getCenterY();
-            bx1 = Math.min(bx1, cx);
-            by1 = Math.min(by1, cy);
-            bx2 = Math.max(bx2, cx);
-            by2 = Math.max(by2, cy);
-        }
-        return makeBounds(bx1, by1, bx2 - bx1, by2 - by1);
-    }
-
-    @Override
-    public void setFrame(double x, double y, double width, double height) {
-        setArc(x, y, width, height, getAngleStart(), getAngleExtent(), type);
-    }
-
-    /**
-     * Sets the data that defines the arc.
-     * 
-     * @param point
-     *            the upper left corner of the bounding rectangle.
-     * @param size
-     *            the size of the bounding rectangle.
-     * @param start
-     *            the start angle of the arc in degrees.
-     * @param extent
-     *            the angle width of the arc in degrees.
-     * @param type
-     *            the closure type, either {@link Arc2D#OPEN},
-     *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
-     */
-    public void setArc(Point2D point, Dimension2D size, double start, double extent, int type) {
-        setArc(point.getX(), point.getY(), size.getWidth(), size.getHeight(), start, extent, type);
-    }
-
-    /**
-     * Sets the data that defines the arc.
-     * 
-     * @param rect
-     *            the arc's bounding rectangle.
-     * @param start
-     *            the start angle of the arc in degrees.
-     * @param extent
-     *            the angle width of the arc in degrees.
-     * @param type
-     *            the closure type, either {@link Arc2D#OPEN},
-     *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
-     */
-    public void setArc(Rectangle2D rect, double start, double extent, int type) {
-        setArc(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), start, extent, type);
-    }
-
-    /**
-     * Sets the data that defines the arc by copying it from another Arc2D.
-     * 
-     * @param arc
-     *            the arc whose data is copied into this arc.
-     */
-    public void setArc(Arc2D arc) {
-        setArc(arc.getX(), arc.getY(), arc.getWidth(), arc.getHeight(), arc.getAngleStart(), arc
-                .getAngleExtent(), arc.getArcType());
-    }
-
-    /**
-     * Sets the data for a circular arc by giving its center and radius.
-     * 
-     * @param x
-     *            the x coordinate of the center of the circle.
-     * @param y
-     *            the y coordinate of the center of the circle.
-     * @param radius
-     *            the radius of the circle.
-     * @param start
-     *            the start angle of the arc in degrees.
-     * @param extent
-     *            the angle width of the arc in degrees.
-     * @param type
-     *            the closure type, either {@link Arc2D#OPEN},
-     *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
-     */
-    public void setArcByCenter(double x, double y, double radius, double start, double extent,
-            int type) {
-        setArc(x - radius, y - radius, radius * 2.0, radius * 2.0, start, extent, type);
-    }
-
-    /**
-     * Sets the arc data for a circular arc based on two tangent lines and the
-     * radius. The two tangent lines are the lines from p1 to p2 and from p2 to
-     * p3, which determine a unique circle with the given radius. The start and
-     * end points of the arc are the points where the circle touches the two
-     * lines, and the arc itself is the shorter of the two circle segments
-     * determined by the two points (in other words, it is the piece of the
-     * circle that is closer to the lines' intersection point p2 and forms a
-     * concave shape with the segments from p1 to p2 and from p2 to p3).
-     * 
-     * @param p1
-     *            a point which determines one of the two tangent lines (with
-     *            p2).
-     * @param p2
-     *            the point of intersection of the two tangent lines.
-     * @param p3
-     *            a point which determines one of the two tangent lines (with
-     *            p2).
-     * @param radius
-     *            the radius of the circular arc.
-     */
-    public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double radius) {
-        // Used simple geometric calculations of arc center, radius and angles
-        // by tangents
-        double a1 = -Math.atan2(p1.getY() - p2.getY(), p1.getX() - p2.getX());
-        double a2 = -Math.atan2(p3.getY() - p2.getY(), p3.getX() - p2.getX());
-        double am = (a1 + a2) / 2.0;
-        double ah = a1 - am;
-        double d = radius / Math.abs(Math.sin(ah));
-        double x = p2.getX() + d * Math.cos(am);
-        double y = p2.getY() - d * Math.sin(am);
-        ah = ah >= 0.0 ? Math.PI * 1.5 - ah : Math.PI * 0.5 - ah;
-        a1 = getNormAngle(Math.toDegrees(am - ah));
-        a2 = getNormAngle(Math.toDegrees(am + ah));
-        double delta = a2 - a1;
-        if (delta <= 0.0) {
-            delta += 360.0;
-        }
-        setArcByCenter(x, y, radius, a1, delta, type);
-    }
-
-    /**
-     * Sets a new start angle to be the angle given by the the vector from the
-     * current center point to the specified point.
-     * 
-     * @param point
-     *            the point that determines the new start angle.
-     */
-    public void setAngleStart(Point2D point) {
-        double angle = Math.atan2(point.getY() - getCenterY(), point.getX() - getCenterX());
-        setAngleStart(getNormAngle(-Math.toDegrees(angle)));
-    }
-
-    /**
-     * Sets the angles in terms of vectors from the current arc center to the
-     * points (x1, y1) and (x2, y2). The start angle is given by the vector from
-     * the current center to the point (x1, y1) and the end angle is given by
-     * the vector from the center to the point (x2, y2).
-     * 
-     * @param x1
-     *            the x coordinate of the point whose vector from the center
-     *            point determines the new start angle of the arc.
-     * @param y1
-     *            the y coordinate of the point whose vector from the center
-     *            point determines the new start angle of the arc.
-     * @param x2
-     *            the x coordinate of the point whose vector from the center
-     *            point determines the new end angle of the arc.
-     * @param y2
-     *            the y coordinate of the point whose vector from the center
-     *            point determines the new end angle of the arc.
-     */
-    public void setAngles(double x1, double y1, double x2, double y2) {
-        double cx = getCenterX();
-        double cy = getCenterY();
-        double a1 = getNormAngle(-Math.toDegrees(Math.atan2(y1 - cy, x1 - cx)));
-        double a2 = getNormAngle(-Math.toDegrees(Math.atan2(y2 - cy, x2 - cx)));
-        a2 -= a1;
-        if (a2 <= 0.0) {
-            a2 += 360.0;
-        }
-        setAngleStart(a1);
-        setAngleExtent(a2);
-    }
-
-    /**
-     * Sets the angles in terms of vectors from the current arc center to the
-     * points p1 and p2. The start angle is given by the vector from the current
-     * center to the point p1 and the end angle is given by the vector from the
-     * center to the point p2.
-     * 
-     * @param p1
-     *            the point whose vector from the center point determines the
-     *            new start angle of the arc.
-     * @param p2
-     *            the point whose vector from the center point determines the
-     *            new end angle of the arc.
-     */
-    public void setAngles(Point2D p1, Point2D p2) {
-        setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
-    }
-
-    /**
-     * Normalizes the angle by removing extra winding (past 360 degrees) and
-     * placing it in the positive degree range.
-     * 
-     * @param angle
-     *            the source angle in degrees.
-     * @return an angle between 0 and 360 degrees which corresponds to the same
-     *         direction vector as the source angle.
-     */
-    double getNormAngle(double angle) {
-        double n = Math.floor(angle / 360.0);
-        return angle - n * 360.0;
-    }
-
-    /**
-     * Determines whether the given angle is contained in the span of the arc.
-     * 
-     * @param angle
-     *            the angle to test in degrees.
-     * @return true, if the given angle is between the start angle and the end
-     *         angle of the arc.
-     */
-    public boolean containsAngle(double angle) {
-        double extent = getAngleExtent();
-        if (extent >= 360.0) {
-            return true;
-        }
-        angle = getNormAngle(angle);
-        double a1 = getNormAngle(getAngleStart());
-        double a2 = a1 + extent;
-        if (a2 > 360.0) {
-            return angle >= a1 || angle <= a2 - 360.0;
-        }
-        if (a2 < 0.0) {
-            return angle >= a2 + 360.0 || angle <= a1;
-        }
-        return extent > 0.0 ? a1 <= angle && angle <= a2 : a2 <= angle && angle <= a1;
-    }
-
-    public boolean contains(double px, double py) {
-        // Normalize point
-        double nx = (px - getX()) / getWidth() - 0.5;
-        double ny = (py - getY()) / getHeight() - 0.5;
-
-        if ((nx * nx + ny * ny) > 0.25) {
-            return false;
-        }
-
-        double extent = getAngleExtent();
-        double absExtent = Math.abs(extent);
-        if (absExtent >= 360.0) {
-            return true;
-        }
-
-        boolean containsAngle = containsAngle(Math.toDegrees(-Math.atan2(ny, nx)));
-        if (type == PIE) {
-            return containsAngle;
-        }
-        if (absExtent <= 180.0 && !containsAngle) {
-            return false;
-        }
-
-        Line2D l = new Line2D.Double(getStartPoint(), getEndPoint());
-        int ccw1 = l.relativeCCW(px, py);
-        int ccw2 = l.relativeCCW(getCenterX(), getCenterY());
-        return ccw1 == 0 || ccw2 == 0 || ((ccw1 + ccw2) == 0 ^ absExtent > 180.0);
-    }
-
-    public boolean contains(double rx, double ry, double rw, double rh) {
-
-        if (!(contains(rx, ry) && contains(rx + rw, ry) && contains(rx + rw, ry + rh) && contains(
-                rx, ry + rh))) {
-            return false;
-        }
-
-        double absExtent = Math.abs(getAngleExtent());
-        if (type != PIE || absExtent <= 180.0 || absExtent >= 360.0) {
-            return true;
-        }
-
-        Rectangle2D r = new Rectangle2D.Double(rx, ry, rw, rh);
-
-        double cx = getCenterX();
-        double cy = getCenterY();
-        if (r.contains(cx, cy)) {
-            return false;
-        }
-
-        Point2D p1 = getStartPoint();
-        Point2D p2 = getEndPoint();
-
-        return !r.intersectsLine(cx, cy, p1.getX(), p1.getY())
-                && !r.intersectsLine(cx, cy, p2.getX(), p2.getY());
-    }
-
-    @Override
-    public boolean contains(Rectangle2D rect) {
-        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
-    }
-
-    public boolean intersects(double rx, double ry, double rw, double rh) {
-
-        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
-            return false;
-        }
-
-        // Check: Does arc contain rectangle's points
-        if (contains(rx, ry) || contains(rx + rw, ry) || contains(rx, ry + rh)
-                || contains(rx + rw, ry + rh)) {
-            return true;
-        }
-
-        double cx = getCenterX();
-        double cy = getCenterY();
-        Point2D p1 = getStartPoint();
-        Point2D p2 = getEndPoint();
-        Rectangle2D r = new Rectangle2D.Double(rx, ry, rw, rh);
-
-        // Check: Does rectangle contain arc's points
-        if (r.contains(p1) || r.contains(p2) || (type == PIE && r.contains(cx, cy))) {
-            return true;
-        }
-
-        if (type == PIE) {
-            if (r.intersectsLine(p1.getX(), p1.getY(), cx, cy)
-                    || r.intersectsLine(p2.getX(), p2.getY(), cx, cy)) {
-                return true;
-            }
-        } else {
-            if (r.intersectsLine(p1.getX(), p1.getY(), p2.getX(), p2.getY())) {
-                return true;
-            }
-        }
-
-        // Nearest rectangle point
-        double nx = cx < rx ? rx : (cx > rx + rw ? rx + rw : cx);
-        double ny = cy < ry ? ry : (cy > ry + rh ? ry + rh : cy);
-        return contains(nx, ny);
-    }
-
-    public PathIterator getPathIterator(AffineTransform at) {
-        return new Iterator(this, at);
-    }
-
-}
diff --git a/awt/java/awt/geom/Area.java b/awt/java/awt/geom/Area.java
deleted file mode 100644
index e6619e3..0000000
--- a/awt/java/awt/geom/Area.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Rectangle2D;
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.luni.util.NotImplementedException;
-
-/**
- * The Class Area provides a minimal implementation for a generic shape.
- * 
- * @since Android 1.0
- */
-public class Area implements Shape, Cloneable {
-
-    /**
-     * The source Shape object.
-     */
-    Shape s;
-
-    /**
-     * The Class NullIterator.
-     */
-    private static class NullIterator implements PathIterator {
-
-        /**
-         * Instantiates a new null iterator.
-         */
-        NullIterator() {
-        }
-
-        public int getWindingRule() {
-            return WIND_NON_ZERO;
-        }
-
-        public boolean isDone() {
-            return true;
-        }
-
-        public void next() {
-            // nothing
-        }
-
-        public int currentSegment(double[] coords) {
-            // awt.4B=Iterator out of bounds
-            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-        }
-
-        public int currentSegment(float[] coords) {
-            // awt.4B=Iterator out of bounds
-            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-        }
-
-    }
-
-    /**
-     * Instantiates a new area with no data.
-     */
-    public Area() {
-    }
-
-    /**
-     * Instantiates a new area with data given by the specified shape.
-     * 
-     * @param s
-     *            the shape that gives the data for this Area.
-     */
-    public Area(Shape s) {
-        if (s == null) {
-            throw new NullPointerException();
-        }
-        this.s = s;
-    }
-
-    public boolean contains(double x, double y) {
-        return s == null ? false : s.contains(x, y);
-    }
-
-    public boolean contains(double x, double y, double width, double height) {
-        return s == null ? false : s.contains(x, y, width, height);
-    }
-
-    public boolean contains(Point2D p) {
-        if (p == null) {
-            throw new NullPointerException();
-        }
-        return s == null ? false : s.contains(p);
-    }
-
-    public boolean contains(Rectangle2D r) {
-        if (r == null) {
-            throw new NullPointerException();
-        }
-        return s == null ? false : s.contains(r);
-    }
-
-    /**
-     * Tests whether the object is equal to this Area.
-     * 
-     * @param obj
-     *            the object to compare.
-     * @return true, if successful.
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public boolean equals(Area obj) throws org.apache.harmony.luni.util.NotImplementedException {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    public boolean intersects(double x, double y, double width, double height) {
-        return s == null ? false : s.intersects(x, y, width, height);
-    }
-
-    public boolean intersects(Rectangle2D r) {
-        if (r == null) {
-            throw new NullPointerException();
-        }
-        return s == null ? false : s.intersects(r);
-    }
-
-    public Rectangle getBounds() {
-        return s == null ? new Rectangle() : s.getBounds();
-    }
-
-    public Rectangle2D getBounds2D() {
-        return s == null ? new Rectangle2D.Double() : s.getBounds2D();
-    }
-
-    public PathIterator getPathIterator(AffineTransform t) {
-        return s == null ? new NullIterator() : s.getPathIterator(t);
-    }
-
-    public PathIterator getPathIterator(AffineTransform t, double flatness) {
-        return s == null ? new NullIterator() : s.getPathIterator(t, flatness);
-    }
-
-    /**
-     * Adds the specified area to this area.
-     * 
-     * @param area
-     *            the area to add to this area.
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public void add(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    /**
-     * Performs an exclusive or operation between this shape and the specified
-     * shape.
-     * 
-     * @param area
-     *            the area to XOR against this area.
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public void exclusiveOr(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    /**
-     * Extracts a Rectangle2D from the source shape if the underlying shape data
-     * describes a rectangle.
-     * 
-     * @return a Rectangle2D object if the source shape is rectangle, or null if
-     *         shape is empty or not rectangle.
-     */
-    Rectangle2D extractRectangle() {
-        if (s == null) {
-            return null;
-        }
-        float[] points = new float[12];
-        int count = 0;
-        PathIterator p = s.getPathIterator(null);
-        float[] coords = new float[6];
-        while (!p.isDone()) {
-            int type = p.currentSegment(coords);
-            if (count > 12 || type == PathIterator.SEG_QUADTO || type == PathIterator.SEG_CUBICTO) {
-                return null;
-            }
-            points[count++] = coords[0];
-            points[count++] = coords[1];
-            p.next();
-        }
-        if (points[0] == points[6] && points[6] == points[8] && points[2] == points[4]
-                && points[1] == points[3] && points[3] == points[9] && points[5] == points[7]) {
-            return new Rectangle2D.Float(points[0], points[1], points[2] - points[0], points[7]
-                    - points[1]);
-        }
-        return null;
-    }
-
-    /**
-     * Reduces the size of this Area by intersecting it with the specified Area
-     * if they are both rectangles.
-     * 
-     * @see java.awt.geom.Rectangle2D#intersect(Rectangle2D, Rectangle2D,
-     *      Rectangle2D)
-     * @param area
-     *            the area.
-     */
-    public void intersect(Area area) {
-        Rectangle2D src1 = extractRectangle();
-        Rectangle2D src2 = area.extractRectangle();
-        if (src1 != null && src2 != null) {
-            Rectangle2D.intersect(src1, src2, (Rectangle2D)s);
-        }
-    }
-
-    /**
-     * Subtract the specified area from this area.
-     * 
-     * @param area
-     *            the area to subtract.
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public void subtract(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    /**
-     * Checks if this Area is empty.
-     * 
-     * @return true, if this Area is empty.
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public boolean isEmpty() throws org.apache.harmony.luni.util.NotImplementedException {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    /**
-     * Checks if this Area is polygonal.
-     * 
-     * @return true, if this Area is polygonal.
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public boolean isPolygonal() throws org.apache.harmony.luni.util.NotImplementedException {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    /**
-     * Checks if this Area is rectangular.
-     * 
-     * @return true, if this Area is rectangular.
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public boolean isRectangular() throws org.apache.harmony.luni.util.NotImplementedException {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    /**
-     * Checks if this Area is singular.
-     * 
-     * @return true, if this Area is singular.
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public boolean isSingular() throws org.apache.harmony.luni.util.NotImplementedException {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    /**
-     * Resets the data of this Area.
-     * 
-     * @throws NotImplementedException
-     *             if this method is not implemented.
-     */
-    public void reset() throws org.apache.harmony.luni.util.NotImplementedException {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    /**
-     * Transforms the data of this Area according to the specified
-     * AffineTransform.
-     * 
-     * @param t
-     *            the transform to use to transform the data.
-     */
-    public void transform(AffineTransform t) {
-        s = t.createTransformedShape(s);
-    }
-
-    /**
-     * Creates a new Area that is the result of transforming the data of this
-     * Area according to the specified AffineTransform.
-     * 
-     * @param t
-     *            the transform to use to transform the data.
-     * @return the new Area that is the result of transforming the data of this
-     *         Area according to the specified AffineTransform.
-     */
-    public Area createTransformedArea(AffineTransform t) {
-        return s == null ? new Area() : new Area(t.createTransformedShape(s));
-    }
-
-    @Override
-    public Object clone() {
-        return new Area(this);
-    }
-
-}
diff --git a/awt/java/awt/geom/CubicCurve2D.java b/awt/java/awt/geom/CubicCurve2D.java
deleted file mode 100644
index 1ddedf3..0000000
--- a/awt/java/awt/geom/CubicCurve2D.java
+++ /dev/null
@@ -1,1047 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.gl.Crossing;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class CubicCurve2D is a Shape that represents a segment of a quadratic
- * (Bezier) curve. The curved segment is determined by four points: a start
- * point, an end point, and two control points. The control points give
- * information about the tangent and next derivative at the endpoints according
- * to the standard theory of Bezier curves. For more information on Bezier
- * curves, see <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">this
- * article</a>.
- * 
- * @since Android 1.0
- */
-public abstract class CubicCurve2D implements Shape, Cloneable {
-
-    /**
-     * The Class Float is the subclass of CubicCurve2D that has all of its data
-     * values stored with float-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Float extends CubicCurve2D {
-
-        /**
-         * The x coordinate of the starting point.
-         */
-        public float x1;
-
-        /**
-         * The y coordinate of the starting point.
-         */
-        public float y1;
-
-        /**
-         * The x coordinate of the first control point.
-         */
-        public float ctrlx1;
-
-        /**
-         * The y coordinate of the first control point.
-         */
-        public float ctrly1;
-
-        /**
-         * The x coordinate of the second control point.
-         */
-        public float ctrlx2;
-
-        /**
-         * The y coordinate of the second control point.
-         */
-        public float ctrly2;
-
-        /**
-         * The x coordinate of the end point.
-         */
-        public float x2;
-
-        /**
-         * The y coordinate of the end point.
-         */
-        public float y2;
-
-        /**
-         * Instantiates a new float-valued CubicCurve2D with all coordinate
-         * values set to zero.
-         */
-        public Float() {
-        }
-
-        /**
-         * Instantiates a new float-valued CubicCurve2D with the specified
-         * coordinate values.
-         * 
-         * @param x1
-         *            the x coordinate of the starting point.
-         * @param y1
-         *            the y coordinate of the starting point.
-         * @param ctrlx1
-         *            the x coordinate of the first control point.
-         * @param ctrly1
-         *            the y coordinate of the first control point.
-         * @param ctrlx2
-         *            the x coordinate of the second control point.
-         * @param ctrly2
-         *            the y coordinate of the second control point.
-         * @param x2
-         *            the x coordinate of the end point.
-         * @param y2
-         *            the y coordinate of the end point.
-         */
-        public Float(float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2, float ctrly2,
-                float x2, float y2) {
-            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
-        }
-
-        @Override
-        public double getX1() {
-            return x1;
-        }
-
-        @Override
-        public double getY1() {
-            return y1;
-        }
-
-        @Override
-        public double getCtrlX1() {
-            return ctrlx1;
-        }
-
-        @Override
-        public double getCtrlY1() {
-            return ctrly1;
-        }
-
-        @Override
-        public double getCtrlX2() {
-            return ctrlx2;
-        }
-
-        @Override
-        public double getCtrlY2() {
-            return ctrly2;
-        }
-
-        @Override
-        public double getX2() {
-            return x2;
-        }
-
-        @Override
-        public double getY2() {
-            return y2;
-        }
-
-        @Override
-        public Point2D getP1() {
-            return new Point2D.Float(x1, y1);
-        }
-
-        @Override
-        public Point2D getCtrlP1() {
-            return new Point2D.Float(ctrlx1, ctrly1);
-        }
-
-        @Override
-        public Point2D getCtrlP2() {
-            return new Point2D.Float(ctrlx2, ctrly2);
-        }
-
-        @Override
-        public Point2D getP2() {
-            return new Point2D.Float(x2, y2);
-        }
-
-        @Override
-        public void setCurve(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2,
-                double ctrly2, double x2, double y2) {
-            this.x1 = (float)x1;
-            this.y1 = (float)y1;
-            this.ctrlx1 = (float)ctrlx1;
-            this.ctrly1 = (float)ctrly1;
-            this.ctrlx2 = (float)ctrlx2;
-            this.ctrly2 = (float)ctrly2;
-            this.x2 = (float)x2;
-            this.y2 = (float)y2;
-        }
-
-        /**
-         * Sets the data values of the curve.
-         * 
-         * @param x1
-         *            the x coordinate of the starting point.
-         * @param y1
-         *            the y coordinate of the starting point.
-         * @param ctrlx1
-         *            the x coordinate of the first control point.
-         * @param ctrly1
-         *            the y coordinate of the first control point.
-         * @param ctrlx2
-         *            the x coordinate of the second control point.
-         * @param ctrly2
-         *            the y coordinate of the second control point.
-         * @param x2
-         *            the x coordinate of the end point.
-         * @param y2
-         *            the y coordinate of the end point.
-         */
-        public void setCurve(float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2,
-                float ctrly2, float x2, float y2) {
-            this.x1 = x1;
-            this.y1 = y1;
-            this.ctrlx1 = ctrlx1;
-            this.ctrly1 = ctrly1;
-            this.ctrlx2 = ctrlx2;
-            this.ctrly2 = ctrly2;
-            this.x2 = x2;
-            this.y2 = y2;
-        }
-
-        public Rectangle2D getBounds2D() {
-            float rx1 = Math.min(Math.min(x1, x2), Math.min(ctrlx1, ctrlx2));
-            float ry1 = Math.min(Math.min(y1, y2), Math.min(ctrly1, ctrly2));
-            float rx2 = Math.max(Math.max(x1, x2), Math.max(ctrlx1, ctrlx2));
-            float ry2 = Math.max(Math.max(y1, y2), Math.max(ctrly1, ctrly2));
-            return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
-        }
-    }
-
-    /**
-     * The Class Double is the subclass of CubicCurve2D that has all of its data
-     * values stored with double-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Double extends CubicCurve2D {
-
-        /**
-         * The x coordinate of the starting point.
-         */
-        public double x1;
-
-        /**
-         * The y coordinate of the starting point.
-         */
-        public double y1;
-
-        /**
-         * The x coordinate of the first control point.
-         */
-        public double ctrlx1;
-
-        /**
-         * The y coordinate of the first control point.
-         */
-        public double ctrly1;
-
-        /**
-         * The x coordinate of the second control point.
-         */
-        public double ctrlx2;
-
-        /**
-         * The y coordinate of the second control point.
-         */
-        public double ctrly2;
-
-        /**
-         * The x coordinate of the end point.
-         */
-        public double x2;
-
-        /**
-         * The y coordinate of the end point.
-         */
-        public double y2;
-
-        /**
-         * Instantiates a new double-valued CubicCurve2D with all coordinate
-         * values set to zero.
-         */
-        public Double() {
-        }
-
-        /**
-         * Instantiates a new double-valued CubicCurve2D with the specified
-         * coordinate values.
-         * 
-         * @param x1
-         *            the x coordinate of the starting point.
-         * @param y1
-         *            the y coordinate of the starting point.
-         * @param ctrlx1
-         *            the x coordinate of the first control point.
-         * @param ctrly1
-         *            the y coordinate of the first control point.
-         * @param ctrlx2
-         *            the x coordinate of the second control point.
-         * @param ctrly2
-         *            the y coordinate of the second control point.
-         * @param x2
-         *            the x coordinate of the end point.
-         * @param y2
-         *            the y coordinate of the end point.
-         */
-        public Double(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2,
-                double ctrly2, double x2, double y2) {
-            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
-        }
-
-        @Override
-        public double getX1() {
-            return x1;
-        }
-
-        @Override
-        public double getY1() {
-            return y1;
-        }
-
-        @Override
-        public double getCtrlX1() {
-            return ctrlx1;
-        }
-
-        @Override
-        public double getCtrlY1() {
-            return ctrly1;
-        }
-
-        @Override
-        public double getCtrlX2() {
-            return ctrlx2;
-        }
-
-        @Override
-        public double getCtrlY2() {
-            return ctrly2;
-        }
-
-        @Override
-        public double getX2() {
-            return x2;
-        }
-
-        @Override
-        public double getY2() {
-            return y2;
-        }
-
-        @Override
-        public Point2D getP1() {
-            return new Point2D.Double(x1, y1);
-        }
-
-        @Override
-        public Point2D getCtrlP1() {
-            return new Point2D.Double(ctrlx1, ctrly1);
-        }
-
-        @Override
-        public Point2D getCtrlP2() {
-            return new Point2D.Double(ctrlx2, ctrly2);
-        }
-
-        @Override
-        public Point2D getP2() {
-            return new Point2D.Double(x2, y2);
-        }
-
-        @Override
-        public void setCurve(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2,
-                double ctrly2, double x2, double y2) {
-            this.x1 = x1;
-            this.y1 = y1;
-            this.ctrlx1 = ctrlx1;
-            this.ctrly1 = ctrly1;
-            this.ctrlx2 = ctrlx2;
-            this.ctrly2 = ctrly2;
-            this.x2 = x2;
-            this.y2 = y2;
-        }
-
-        public Rectangle2D getBounds2D() {
-            double rx1 = Math.min(Math.min(x1, x2), Math.min(ctrlx1, ctrlx2));
-            double ry1 = Math.min(Math.min(y1, y2), Math.min(ctrly1, ctrly2));
-            double rx2 = Math.max(Math.max(x1, x2), Math.max(ctrlx1, ctrlx2));
-            double ry2 = Math.max(Math.max(y1, y2), Math.max(ctrly1, ctrly2));
-            return new Rectangle2D.Double(rx1, ry1, rx2 - rx1, ry2 - ry1);
-        }
-    }
-
-    /*
-     * CubicCurve2D path iterator
-     */
-    /**
-     * The Iterator class for the Shape CubicCurve2D.
-     */
-    class Iterator implements PathIterator {
-
-        /**
-         * The source CubicCurve2D object.
-         */
-        CubicCurve2D c;
-
-        /**
-         * The path iterator transformation.
-         */
-        AffineTransform t;
-
-        /**
-         * The current segment index.
-         */
-        int index;
-
-        /**
-         * Constructs a new CubicCurve2D.Iterator for given line and
-         * transformation
-         * 
-         * @param c
-         *            the source CubicCurve2D object.
-         * @param t
-         *            the affine transformation object.
-         */
-        Iterator(CubicCurve2D c, AffineTransform t) {
-            this.c = c;
-            this.t = t;
-        }
-
-        public int getWindingRule() {
-            return WIND_NON_ZERO;
-        }
-
-        public boolean isDone() {
-            return index > 1;
-        }
-
-        public void next() {
-            index++;
-        }
-
-        public int currentSegment(double[] coords) {
-            if (isDone()) {
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type;
-            int count;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                coords[0] = c.getX1();
-                coords[1] = c.getY1();
-                count = 1;
-            } else {
-                type = SEG_CUBICTO;
-                coords[0] = c.getCtrlX1();
-                coords[1] = c.getCtrlY1();
-                coords[2] = c.getCtrlX2();
-                coords[3] = c.getCtrlY2();
-                coords[4] = c.getX2();
-                coords[5] = c.getY2();
-                count = 3;
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, count);
-            }
-            return type;
-        }
-
-        public int currentSegment(float[] coords) {
-            if (isDone()) {
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type;
-            int count;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                coords[0] = (float)c.getX1();
-                coords[1] = (float)c.getY1();
-                count = 1;
-            } else {
-                type = SEG_CUBICTO;
-                coords[0] = (float)c.getCtrlX1();
-                coords[1] = (float)c.getCtrlY1();
-                coords[2] = (float)c.getCtrlX2();
-                coords[3] = (float)c.getCtrlY2();
-                coords[4] = (float)c.getX2();
-                coords[5] = (float)c.getY2();
-                count = 3;
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, count);
-            }
-            return type;
-        }
-
-    }
-
-    /**
-     * Instantiates a new 2-D cubic curve.
-     */
-    protected CubicCurve2D() {
-    }
-
-    /**
-     * Gets the x coordinate of the starting point.
-     * 
-     * @return the x coordinate of the starting point.
-     */
-    public abstract double getX1();
-
-    /**
-     * Gets the y coordinate of the starting point.
-     * 
-     * @return the y coordinate of the starting point.
-     */
-    public abstract double getY1();
-
-    /**
-     * Gets the starting point.
-     * 
-     * @return the starting point.
-     */
-    public abstract Point2D getP1();
-
-    /**
-     * Gets the x coordinate of the first control point.
-     * 
-     * @return the x coordinate of the first control point.
-     */
-    public abstract double getCtrlX1();
-
-    /**
-     * Gets the y coordinate of the first control point.
-     * 
-     * @return the y coordinate of the first control point.
-     */
-    public abstract double getCtrlY1();
-
-    /**
-     * Gets the second control point.
-     * 
-     * @return the second control point.
-     */
-    public abstract Point2D getCtrlP1();
-
-    /**
-     * Gets the x coordinate of the second control point.
-     * 
-     * @return the x coordinate of the second control point
-     */
-    public abstract double getCtrlX2();
-
-    /**
-     * Gets the y coordinate of the second control point.
-     * 
-     * @return the y coordinate of the second control point
-     */
-    public abstract double getCtrlY2();
-
-    /**
-     * Gets the second control point.
-     * 
-     * @return the second control point.
-     */
-    public abstract Point2D getCtrlP2();
-
-    /**
-     * Gets the x coordinate of the end point.
-     * 
-     * @return the x coordinate of the end point.
-     */
-    public abstract double getX2();
-
-    /**
-     * Gets the y coordinate of the end point.
-     * 
-     * @return the y coordinate of the end point.
-     */
-    public abstract double getY2();
-
-    /**
-     * Gets the end point.
-     * 
-     * @return the end point.
-     */
-    public abstract Point2D getP2();
-
-    /**
-     * Sets the data of the curve.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point.
-     * @param y1
-     *            the y coordinate of the starting point.
-     * @param ctrlx1
-     *            the x coordinate of the first control point.
-     * @param ctrly1
-     *            the y coordinate of the first control point.
-     * @param ctrlx2
-     *            the x coordinate of the second control point.
-     * @param ctrly2
-     *            the y coordinate of the second control point.
-     * @param x2
-     *            the x coordinate of the end point.
-     * @param y2
-     *            the y coordinate of the end point.
-     */
-    public abstract void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
-            double ctrlx2, double ctrly2, double x2, double y2);
-
-    /**
-     * Sets the data of the curve as point objects.
-     * 
-     * @param p1
-     *            the starting point.
-     * @param cp1
-     *            the first control point.
-     * @param cp2
-     *            the second control point.
-     * @param p2
-     *            the end point.
-     * @throws NullPointerException
-     *             if any of the points is null.
-     */
-    public void setCurve(Point2D p1, Point2D cp1, Point2D cp2, Point2D p2) {
-        setCurve(p1.getX(), p1.getY(), cp1.getX(), cp1.getY(), cp2.getX(), cp2.getY(), p2.getX(),
-                p2.getY());
-    }
-
-    /**
-     * Sets the data of the curve by reading the data from an array of values.
-     * The values are read in the same order as the arguments of the method
-     * {@link CubicCurve2D#setCurve(double, double, double, double, double, double, double, double)}
-     * .
-     * 
-     * @param coords
-     *            the array of values containing the new coordinates.
-     * @param offset
-     *            the offset of the data to read within the array.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {@code coords.length} < offset + 8.
-     * @throws NullPointerException
-     *             if the coordinate array is null.
-     */
-    public void setCurve(double[] coords, int offset) {
-        setCurve(coords[offset + 0], coords[offset + 1], coords[offset + 2], coords[offset + 3],
-                coords[offset + 4], coords[offset + 5], coords[offset + 6], coords[offset + 7]);
-    }
-
-    /**
-     * Sets the data of the curve by reading the data from an array of points.
-     * The values are read in the same order as the arguments of the method
-     * {@link CubicCurve2D#setCurve(Point2D, Point2D, Point2D, Point2D)}
-     * 
-     * @param points
-     *            the array of points containing the new coordinates.
-     * @param offset
-     *            the offset of the data to read within the array.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {@code points.length} < offset + .
-     * @throws NullPointerException
-     *             if the point array is null.
-     */
-    public void setCurve(Point2D[] points, int offset) {
-        setCurve(points[offset + 0].getX(), points[offset + 0].getY(), points[offset + 1].getX(),
-                points[offset + 1].getY(), points[offset + 2].getX(), points[offset + 2].getY(),
-                points[offset + 3].getX(), points[offset + 3].getY());
-    }
-
-    /**
-     * Sets the data of the curve by copying it from another CubicCurve2D.
-     * 
-     * @param curve
-     *            the curve to copy the data points from.
-     * @throws NullPointerException
-     *             if the curve is null.
-     */
-    public void setCurve(CubicCurve2D curve) {
-        setCurve(curve.getX1(), curve.getY1(), curve.getCtrlX1(), curve.getCtrlY1(), curve
-                .getCtrlX2(), curve.getCtrlY2(), curve.getX2(), curve.getY2());
-    }
-
-    /**
-     * Gets the square of the flatness of this curve, where the flatness is the
-     * maximum distance from the curves control points to the line segment
-     * connecting the two points.
-     * 
-     * @return the square of the flatness.
-     */
-    public double getFlatnessSq() {
-        return getFlatnessSq(getX1(), getY1(), getCtrlX1(), getCtrlY1(), getCtrlX2(), getCtrlY2(),
-                getX2(), getY2());
-    }
-
-    /**
-     * Gets the square of the flatness of the cubic curve segment defined by the
-     * specified values.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point.
-     * @param y1
-     *            the y coordinate of the starting point.
-     * @param ctrlx1
-     *            the x coordinate of the first control point.
-     * @param ctrly1
-     *            the y coordinate of the first control point.
-     * @param ctrlx2
-     *            the x coordinate of the second control point.
-     * @param ctrly2
-     *            the y coordinate of the second control point.
-     * @param x2
-     *            the x coordinate of the end point.
-     * @param y2
-     *            the y coordinate of the end point.
-     * @return the square of the flatness.
-     */
-    public static double getFlatnessSq(double x1, double y1, double ctrlx1, double ctrly1,
-            double ctrlx2, double ctrly2, double x2, double y2) {
-        return Math.max(Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx1, ctrly1), Line2D.ptSegDistSq(x1,
-                y1, x2, y2, ctrlx2, ctrly2));
-    }
-
-    /**
-     * Gets the square of the flatness of the cubic curve segment defined by the
-     * specified values. The values are read in the same order as the arguments
-     * of the method
-     * {@link CubicCurve2D#getFlatnessSq(double, double, double, double, double, double, double, double)}
-     * .
-     * 
-     * @param coords
-     *            the array of points containing the new coordinates.
-     * @param offset
-     *            the offset of the data to read within the array.
-     * @return the square of the flatness.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if points.length < offset + .
-     * @throws NullPointerException
-     *             if the point array is null.
-     */
-    public static double getFlatnessSq(double coords[], int offset) {
-        return getFlatnessSq(coords[offset + 0], coords[offset + 1], coords[offset + 2],
-                coords[offset + 3], coords[offset + 4], coords[offset + 5], coords[offset + 6],
-                coords[offset + 7]);
-    }
-
-    /**
-     * Gets the flatness of this curve, where the flatness is the maximum
-     * distance from the curves control points to the line segment connecting
-     * the two points.
-     * 
-     * @return the flatness of this curve.
-     */
-    public double getFlatness() {
-        return getFlatness(getX1(), getY1(), getCtrlX1(), getCtrlY1(), getCtrlX2(), getCtrlY2(),
-                getX2(), getY2());
-    }
-
-    /**
-     * Gets the flatness of the cubic curve segment defined by the specified
-     * values.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point.
-     * @param y1
-     *            the y coordinate of the starting point.
-     * @param ctrlx1
-     *            the x coordinate of the first control point.
-     * @param ctrly1
-     *            the y coordinate of the first control point.
-     * @param ctrlx2
-     *            the x coordinate of the second control point.
-     * @param ctrly2
-     *            the y coordinate of the second control point.
-     * @param x2
-     *            the x coordinate of the end point.
-     * @param y2
-     *            the y coordinate of the end point.
-     * @return the flatness.
-     */
-    public static double getFlatness(double x1, double y1, double ctrlx1, double ctrly1,
-            double ctrlx2, double ctrly2, double x2, double y2) {
-        return Math.sqrt(getFlatnessSq(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2));
-    }
-
-    /**
-     * Gets the flatness of the cubic curve segment defined by the specified
-     * values. The values are read in the same order as the arguments of the
-     * method
-     * {@link CubicCurve2D#getFlatness(double, double, double, double, double, double, double, double)}
-     * .
-     * 
-     * @param coords
-     *            the array of points containing the new coordinates.
-     * @param offset
-     *            the offset of the data to read within the array.
-     * @return the flatness.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if points.length < offset + .
-     * @throws NullPointerException
-     *             if the point array is null.
-     */
-    public static double getFlatness(double coords[], int offset) {
-        return getFlatness(coords[offset + 0], coords[offset + 1], coords[offset + 2],
-                coords[offset + 3], coords[offset + 4], coords[offset + 5], coords[offset + 6],
-                coords[offset + 7]);
-    }
-
-    /**
-     * Creates the data for two cubic curves by dividing this curve in two. The
-     * division point is the point on the curve that is closest to the average
-     * of curve's two control points. The two new control points (nearest the
-     * new endpoint) are computed by averaging the original control points with
-     * the new endpoint. The data of this curve is left unchanged.
-     * 
-     * @param left
-     *            the CubicCurve2D where the left (start) segment's data is
-     *            written.
-     * @param right
-     *            the CubicCurve2D where the right (end) segment's data is
-     *            written.
-     * @throws NullPointerException
-     *             if either curve is null.
-     */
-    public void subdivide(CubicCurve2D left, CubicCurve2D right) {
-        subdivide(this, left, right);
-    }
-
-    /**
-     * Creates the data for two cubic curves by dividing the specified curve in
-     * two. The division point is the point on the curve that is closest to the
-     * average of curve's two control points. The two new control points
-     * (nearest the new endpoint) are computed by averaging the original control
-     * points with the new endpoint. The data of the source curve is left
-     * unchanged.
-     * 
-     * @param src
-     *            the original curve to be divided in two.
-     * @param left
-     *            the CubicCurve2D where the left (start) segment's data is
-     *            written.
-     * @param right
-     *            the CubicCurve2D where the right (end) segment's data is
-     *            written.
-     * @throws NullPointerException
-     *             if either curve is null.
-     */
-    public static void subdivide(CubicCurve2D src, CubicCurve2D left, CubicCurve2D right) {
-        double x1 = src.getX1();
-        double y1 = src.getY1();
-        double cx1 = src.getCtrlX1();
-        double cy1 = src.getCtrlY1();
-        double cx2 = src.getCtrlX2();
-        double cy2 = src.getCtrlY2();
-        double x2 = src.getX2();
-        double y2 = src.getY2();
-        double cx = (cx1 + cx2) / 2.0;
-        double cy = (cy1 + cy2) / 2.0;
-        cx1 = (x1 + cx1) / 2.0;
-        cy1 = (y1 + cy1) / 2.0;
-        cx2 = (x2 + cx2) / 2.0;
-        cy2 = (y2 + cy2) / 2.0;
-        double ax = (cx1 + cx) / 2.0;
-        double ay = (cy1 + cy) / 2.0;
-        double bx = (cx2 + cx) / 2.0;
-        double by = (cy2 + cy) / 2.0;
-        cx = (ax + bx) / 2.0;
-        cy = (ay + by) / 2.0;
-        if (left != null) {
-            left.setCurve(x1, y1, cx1, cy1, ax, ay, cx, cy);
-        }
-        if (right != null) {
-            right.setCurve(cx, cy, bx, by, cx2, cy2, x2, y2);
-        }
-    }
-
-    /**
-     * Creates the data for two cubic curves by dividing the specified curve in
-     * two. The division point is the point on the curve that is closest to the
-     * average of curve's two control points. The two new control points
-     * (nearest the new endpoint) are computed by averaging the original control
-     * points with the new endpoint. The data of the source curve is left
-     * unchanged. The data for the three curves is read/written in the usual
-     * order: { x1, y1, ctrlx1, ctrly1, ctrlx2, crtry2, x2, y3 }
-     * 
-     * @param src
-     *            the array that gives the data values for the source curve.
-     * @param srcOff
-     *            the offset in the src array to read the values from.
-     * @param left
-     *            the array where the coordinates of the start curve should be
-     *            written.
-     * @param leftOff
-     *            the offset in the left array to start writing the values.
-     * @param right
-     *            the array where the coordinates of the end curve should be
-     *            written.
-     * @param rightOff
-     *            the offset in the right array to start writing the values.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if src.length < srcoff + 8 or if left.length < leftOff + 8 or
-     *             if right.length < rightOff + 8.
-     * @throws NullPointerException
-     *             if one of the arrays is null.
-     */
-    public static void subdivide(double src[], int srcOff, double left[], int leftOff,
-            double right[], int rightOff) {
-        double x1 = src[srcOff + 0];
-        double y1 = src[srcOff + 1];
-        double cx1 = src[srcOff + 2];
-        double cy1 = src[srcOff + 3];
-        double cx2 = src[srcOff + 4];
-        double cy2 = src[srcOff + 5];
-        double x2 = src[srcOff + 6];
-        double y2 = src[srcOff + 7];
-        double cx = (cx1 + cx2) / 2.0;
-        double cy = (cy1 + cy2) / 2.0;
-        cx1 = (x1 + cx1) / 2.0;
-        cy1 = (y1 + cy1) / 2.0;
-        cx2 = (x2 + cx2) / 2.0;
-        cy2 = (y2 + cy2) / 2.0;
-        double ax = (cx1 + cx) / 2.0;
-        double ay = (cy1 + cy) / 2.0;
-        double bx = (cx2 + cx) / 2.0;
-        double by = (cy2 + cy) / 2.0;
-        cx = (ax + bx) / 2.0;
-        cy = (ay + by) / 2.0;
-        if (left != null) {
-            left[leftOff + 0] = x1;
-            left[leftOff + 1] = y1;
-            left[leftOff + 2] = cx1;
-            left[leftOff + 3] = cy1;
-            left[leftOff + 4] = ax;
-            left[leftOff + 5] = ay;
-            left[leftOff + 6] = cx;
-            left[leftOff + 7] = cy;
-        }
-        if (right != null) {
-            right[rightOff + 0] = cx;
-            right[rightOff + 1] = cy;
-            right[rightOff + 2] = bx;
-            right[rightOff + 3] = by;
-            right[rightOff + 4] = cx2;
-            right[rightOff + 5] = cy2;
-            right[rightOff + 6] = x2;
-            right[rightOff + 7] = y2;
-        }
-    }
-
-    /**
-     * Finds the roots of the cubic polynomial. This is accomplished by finding
-     * the (real) values of x that solve the following equation: eqn[3]*x*x*x +
-     * eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written back into
-     * the array eqn starting from the index 0 in the array. The return value
-     * tells how many array elements have been changed by this method call.
-     * 
-     * @param eqn
-     *            an array containing the coefficients of the cubic polynomial
-     *            to solve.
-     * @return the number of roots of the cubic polynomial.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if eqn.length < 4.
-     * @throws NullPointerException
-     *             if the array is null.
-     */
-    public static int solveCubic(double eqn[]) {
-        return solveCubic(eqn, eqn);
-    }
-
-    /**
-     * Finds the roots of the cubic polynomial. This is accomplished by finding
-     * the (real) values of x that solve the following equation: eqn[3]*x*x*x +
-     * eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written into the
-     * array res starting from the index 0 in the array. The return value tells
-     * how many array elements have been changed by this method call.
-     * 
-     * @param eqn
-     *            an array containing the coefficients of the cubic polynomial
-     *            to solve.
-     * @param res
-     *            the array that this method writes the results into.
-     * @return the number of roots of the cubic polynomial.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if eqn.length < 4 or if res.length is less than the number of
-     *             roots.
-     * @throws NullPointerException
-     *             if either array is null.
-     */
-    public static int solveCubic(double eqn[], double res[]) {
-        return Crossing.solveCubic(eqn, res);
-    }
-
-    public boolean contains(double px, double py) {
-        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
-    }
-
-    public boolean contains(double rx, double ry, double rw, double rh) {
-        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
-        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
-    }
-
-    public boolean intersects(double rx, double ry, double rw, double rh) {
-        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
-        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
-    }
-
-    public boolean contains(Point2D p) {
-        return contains(p.getX(), p.getY());
-    }
-
-    public boolean intersects(Rectangle2D r) {
-        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
-    }
-
-    public boolean contains(Rectangle2D r) {
-        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
-    }
-
-    public Rectangle getBounds() {
-        return getBounds2D().getBounds();
-    }
-
-    public PathIterator getPathIterator(AffineTransform t) {
-        return new Iterator(this, t);
-    }
-
-    public PathIterator getPathIterator(AffineTransform at, double flatness) {
-        return new FlatteningPathIterator(getPathIterator(at), flatness);
-    }
-
-    @Override
-    public Object clone() {
-        try {
-            return super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new InternalError();
-        }
-    }
-}
\ No newline at end of file
diff --git a/awt/java/awt/geom/Dimension2D.java b/awt/java/awt/geom/Dimension2D.java
deleted file mode 100644
index ea081c5..0000000
--- a/awt/java/awt/geom/Dimension2D.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-/**
- * The Class Dimension2D represents a size (width and height) of a geometric
- * object. It stores double-valued data in order to be compatible with
- * high-precision geometric operations.
- * 
- * @since Android 1.0
- */
-public abstract class Dimension2D implements Cloneable {
-
-    /**
-     * Instantiates a new dimension 2d with no data.
-     */
-    protected Dimension2D() {
-    }
-
-    /**
-     * Gets the width.
-     * 
-     * @return the width.
-     */
-    public abstract double getWidth();
-
-    /**
-     * Gets the height.
-     * 
-     * @return the height.
-     */
-    public abstract double getHeight();
-
-    /**
-     * Sets the width and height.
-     * 
-     * @param width
-     *            the width.
-     * @param height
-     *            the height.
-     */
-    public abstract void setSize(double width, double height);
-
-    /**
-     * Sets the width and height based on the data of another Dimension2D
-     * object.
-     * 
-     * @param d
-     *            the Dimension2D object providing the data to copy into this
-     *            Dimension2D object.
-     */
-    public void setSize(Dimension2D d) {
-        setSize(d.getWidth(), d.getHeight());
-    }
-
-    @Override
-    public Object clone() {
-        try {
-            return super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new InternalError();
-        }
-    }
-}
diff --git a/awt/java/awt/geom/Ellipse2D.java b/awt/java/awt/geom/Ellipse2D.java
deleted file mode 100644
index 89fd0d0..0000000
--- a/awt/java/awt/geom/Ellipse2D.java
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class Ellipse2D describes an ellipse defined by a rectangular area in
- * which it is inscribed.
- * 
- * @since Android 1.0
- */
-public abstract class Ellipse2D extends RectangularShape {
-
-    /**
-     * The Class Float is the subclass of Ellipse2D that has all of its data
-     * values stored with float-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Float extends Ellipse2D {
-
-        /**
-         * The x coordinate of the upper left corner of the ellipse's bounding
-         * rectangle.
-         */
-        public float x;
-
-        /**
-         * The y coordinate of the upper left corner of the ellipse's bounding
-         * rectangle.
-         */
-        public float y;
-
-        /**
-         * The width of the ellipse's bounding rectangle.
-         */
-        public float width;
-
-        /**
-         * The height of the ellipse's bounding rectangle.
-         */
-        public float height;
-
-        /**
-         * Instantiates a new float-valued Ellipse2D.
-         */
-        public Float() {
-        }
-
-        /**
-         * Instantiates a new float-valued Ellipse2D with the specified data.
-         * 
-         * @param x
-         *            the x coordinate of the upper left corner of the ellipse's
-         *            bounding rectangle.
-         * @param y
-         *            the y coordinate of the upper left corner of the ellipse's
-         *            bounding rectangle.
-         * @param width
-         *            the width of the ellipse's bounding rectangle.
-         * @param height
-         *            the height of the ellipse's bounding rectangle.
-         */
-        public Float(float x, float y, float width, float height) {
-            setFrame(x, y, width, height);
-        }
-
-        @Override
-        public double getX() {
-            return x;
-        }
-
-        @Override
-        public double getY() {
-            return y;
-        }
-
-        @Override
-        public double getWidth() {
-            return width;
-        }
-
-        @Override
-        public double getHeight() {
-            return height;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return width <= 0.0 || height <= 0.0;
-        }
-
-        /**
-         * Sets the data of the ellipse's bounding rectangle.
-         * 
-         * @param x
-         *            the x coordinate of the upper left corner of the ellipse's
-         *            bounding rectangle.
-         * @param y
-         *            the y coordinate of the upper left corner of the ellipse's
-         *            bounding rectangle.
-         * @param width
-         *            the width of the ellipse's bounding rectangle.
-         * @param height
-         *            the height of the ellipse's bounding rectangle.
-         */
-        public void setFrame(float x, float y, float width, float height) {
-            this.x = x;
-            this.y = y;
-            this.width = width;
-            this.height = height;
-        }
-
-        @Override
-        public void setFrame(double x, double y, double width, double height) {
-            this.x = (float)x;
-            this.y = (float)y;
-            this.width = (float)width;
-            this.height = (float)height;
-        }
-
-        public Rectangle2D getBounds2D() {
-            return new Rectangle2D.Float(x, y, width, height);
-        }
-    }
-
-    /**
-     * The Class Double is the subclass of Ellipse2D that has all of its data
-     * values stored with double-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Double extends Ellipse2D {
-
-        /**
-         * The x coordinate of the upper left corner of the ellipse's bounding
-         * rectangle.
-         */
-        public double x;
-
-        /**
-         * The y coordinate of the upper left corner of the ellipse's bounding
-         * rectangle.
-         */
-        public double y;
-
-        /**
-         * The width of the ellipse's bounding rectangle.
-         */
-        public double width;
-
-        /**
-         * The height of the ellipse's bounding rectangle.
-         */
-        public double height;
-
-        /**
-         * Instantiates a new double-valued Ellipse2D.
-         */
-        public Double() {
-        }
-
-        /**
-         * Instantiates a new double-valued Ellipse2D with the specified data.
-         * 
-         * @param x
-         *            the x coordinate of the upper left corner of the ellipse's
-         *            bounding rectangle.
-         * @param y
-         *            the y coordinate of the upper left corner of the ellipse's
-         *            bounding rectangle.
-         * @param width
-         *            the width of the ellipse's bounding rectangle.
-         * @param height
-         *            the height of the ellipse's bounding rectangle.
-         */
-        public Double(double x, double y, double width, double height) {
-            setFrame(x, y, width, height);
-        }
-
-        @Override
-        public double getX() {
-            return x;
-        }
-
-        @Override
-        public double getY() {
-            return y;
-        }
-
-        @Override
-        public double getWidth() {
-            return width;
-        }
-
-        @Override
-        public double getHeight() {
-            return height;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return width <= 0.0 || height <= 0.0;
-        }
-
-        @Override
-        public void setFrame(double x, double y, double width, double height) {
-            this.x = x;
-            this.y = y;
-            this.width = width;
-            this.height = height;
-        }
-
-        public Rectangle2D getBounds2D() {
-            return new Rectangle2D.Double(x, y, width, height);
-        }
-    }
-
-    /*
-     * Ellipse2D path iterator
-     */
-    /**
-     * The subclass of PathIterator to traverse an Ellipse2D.
-     */
-    class Iterator implements PathIterator {
-
-        /*
-         * Ellipse is subdivided into four quarters by x and y axis. Each part
-         * approximated by cubic Bezier curve. Arc in first quarter is started
-         * in (a, 0) and finished in (0, b) points. Control points for cubic
-         * curve wiil be (a, 0), (a, m), (n, b) and (0, b) where n and m are
-         * calculated based on requirement Bezier curve in point 0.5 should lay
-         * on the arc.
-         */
-
-        /**
-         * The coefficient to calculate control points of Bezier curves.
-         */
-        final double u = 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
-
-        /**
-         * The points coordinates calculation table.
-         */
-        final double points[][] = {
-                {
-                        1.0, 0.5 + u, 0.5 + u, 1.0, 0.5, 1.0
-                }, {
-                        0.5 - u, 1.0, 0.0, 0.5 + u, 0.0, 0.5
-                }, {
-                        0.0, 0.5 - u, 0.5 - u, 0.0, 0.5, 0.0
-                }, {
-                        0.5 + u, 0.0, 1.0, 0.5 - u, 1.0, 0.5
-                }
-        };
-
-        /**
-         * The x coordinate of left-upper corner of the ellipse bounds.
-         */
-        double x;
-
-        /**
-         * The y coordinate of left-upper corner of the ellipse bounds.
-         */
-        double y;
-
-        /**
-         * The width of the ellipse bounds.
-         */
-        double width;
-
-        /**
-         * The height of the ellipse bounds.
-         */
-        double height;
-
-        /**
-         * The path iterator transformation.
-         */
-        AffineTransform t;
-
-        /**
-         * The current segment index.
-         */
-        int index;
-
-        /**
-         * Constructs a new Ellipse2D.Iterator for given ellipse and
-         * transformation
-         * 
-         * @param e
-         *            the source Ellipse2D object.
-         * @param t
-         *            the affine transformation object.
-         */
-        Iterator(Ellipse2D e, AffineTransform t) {
-            this.x = e.getX();
-            this.y = e.getY();
-            this.width = e.getWidth();
-            this.height = e.getHeight();
-            this.t = t;
-            if (width < 0.0 || height < 0.0) {
-                index = 6;
-            }
-        }
-
-        public int getWindingRule() {
-            return WIND_NON_ZERO;
-        }
-
-        public boolean isDone() {
-            return index > 5;
-        }
-
-        public void next() {
-            index++;
-        }
-
-        public int currentSegment(double[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            if (index == 5) {
-                return SEG_CLOSE;
-            }
-            int type;
-            int count;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                count = 1;
-                double p[] = points[3];
-                coords[0] = x + p[4] * width;
-                coords[1] = y + p[5] * height;
-            } else {
-                type = SEG_CUBICTO;
-                count = 3;
-                double p[] = points[index - 1];
-                int j = 0;
-                for (int i = 0; i < 3; i++) {
-                    coords[j] = x + p[j++] * width;
-                    coords[j] = y + p[j++] * height;
-                }
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, count);
-            }
-            return type;
-        }
-
-        public int currentSegment(float[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            if (index == 5) {
-                return SEG_CLOSE;
-            }
-            int type;
-            int count;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                count = 1;
-                double p[] = points[3];
-                coords[0] = (float)(x + p[4] * width);
-                coords[1] = (float)(y + p[5] * height);
-            } else {
-                type = SEG_CUBICTO;
-                count = 3;
-                int j = 0;
-                double p[] = points[index - 1];
-                for (int i = 0; i < 3; i++) {
-                    coords[j] = (float)(x + p[j++] * width);
-                    coords[j] = (float)(y + p[j++] * height);
-                }
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, count);
-            }
-            return type;
-        }
-
-    }
-
-    /**
-     * Instantiates a new Ellipse2D.
-     */
-    protected Ellipse2D() {
-    }
-
-    public boolean contains(double px, double py) {
-        if (isEmpty()) {
-            return false;
-        }
-
-        double a = (px - getX()) / getWidth() - 0.5;
-        double b = (py - getY()) / getHeight() - 0.5;
-
-        return a * a + b * b < 0.25;
-    }
-
-    public boolean intersects(double rx, double ry, double rw, double rh) {
-        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
-            return false;
-        }
-
-        double cx = getX() + getWidth() / 2.0;
-        double cy = getY() + getHeight() / 2.0;
-
-        double rx1 = rx;
-        double ry1 = ry;
-        double rx2 = rx + rw;
-        double ry2 = ry + rh;
-
-        double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
-        double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
-
-        return contains(nx, ny);
-    }
-
-    public boolean contains(double rx, double ry, double rw, double rh) {
-        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
-            return false;
-        }
-
-        double rx1 = rx;
-        double ry1 = ry;
-        double rx2 = rx + rw;
-        double ry2 = ry + rh;
-
-        return contains(rx1, ry1) && contains(rx2, ry1) && contains(rx2, ry2) && contains(rx1, ry2);
-    }
-
-    public PathIterator getPathIterator(AffineTransform at) {
-        return new Iterator(this, at);
-    }
-}
diff --git a/awt/java/awt/geom/FlatteningPathIterator.java b/awt/java/awt/geom/FlatteningPathIterator.java
deleted file mode 100644
index 8208f39..0000000
--- a/awt/java/awt/geom/FlatteningPathIterator.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class FlatteningPathIterator takes a PathIterator for traversing a curved
- * shape and flattens it by estimating the curve as a series of line segments.
- * The flattening factor indicates how far the estimating line segments are
- * allowed to be from the actual curve: the FlatteningPathIterator will keep
- * dividing each curved segment into smaller and smaller flat segments until
- * either the segments are within the flattening factor of the curve or until
- * the buffer limit is reached.
- * 
- * @since Android 1.0
- */
-public class FlatteningPathIterator implements PathIterator {
-
-    /**
-     * The default points buffer size.
-     */
-    private static final int BUFFER_SIZE = 16;
-
-    /**
-     * The default curve subdivision limit.
-     */
-    private static final int BUFFER_LIMIT = 16;
-
-    /**
-     * The points buffer capacity.
-     */
-    private static final int BUFFER_CAPACITY = 16;
-
-    /**
-     * The type of current segment to be flat.
-     */
-    int bufType;
-
-    /**
-     * The curve subdivision limit.
-     */
-    int bufLimit;
-
-    /**
-     * The current points buffer size.
-     */
-    int bufSize;
-
-    /**
-     * The inner cursor position in points buffer.
-     */
-    int bufIndex;
-
-    /**
-     * The current subdivision count.
-     */
-    int bufSubdiv;
-
-    /**
-     * The points buffer.
-     */
-    double buf[];
-
-    /**
-     * The indicator of empty points buffer.
-     */
-    boolean bufEmpty = true;
-
-    /**
-     * The source PathIterator.
-     */
-    PathIterator p;
-
-    /**
-     * The flatness of new path.
-     */
-    double flatness;
-
-    /**
-     * The square of flatness.
-     */
-    double flatness2;
-
-    /**
-     * The x coordinate of previous path segment.
-     */
-    double px;
-
-    /**
-     * The y coordinate of previous path segment.
-     */
-    double py;
-
-    /**
-     * The temporary buffer for getting points from PathIterator.
-     */
-    double coords[] = new double[6];
-
-    /**
-     * Instantiates a new flattening path iterator given the path iterator for a
-     * (possibly) curved path and a flattening factor which indicates how close
-     * together the points on the curve should be chosen. The buffer limit
-     * defaults to 16 which means that each curve will be divided into no more
-     * than 16 segments regardless of the flattening factor.
-     * 
-     * @param path
-     *            the path iterator of the original curve.
-     * @param flatness
-     *            the flattening factor that indicates how far the flat path is
-     *            allowed to be from the actual curve in order to decide when to
-     *            stop dividing the path into smaller and smaller segments.
-     * @throws IllegalArgumentException
-     *             if the flatness is less than zero.
-     * @throws NullPointerException
-     *             if the path is null.
-     */
-    public FlatteningPathIterator(PathIterator path, double flatness) {
-        this(path, flatness, BUFFER_LIMIT);
-    }
-
-    /**
-     * Instantiates a new flattening path iterator given the path iterator for a
-     * (possibly) curved path and a flattening factor and a buffer limit. The
-     * FlatteningPathIterator will keep dividing each curved segment into
-     * smaller and smaller flat segments until either the segments are within
-     * the flattening factor of the curve or until the buffer limit is reached.
-     * 
-     * @param path
-     *            the path iterator of the original curve.
-     * @param flatness
-     *            the flattening factor that indicates how far the flat path is
-     *            allowed to be from the actual curve in order to decide when to
-     *            stop dividing the path into smaller and smaller segments.
-     * @param limit
-     *            the maximum number of flat segments to divide each curve into.
-     * @throws IllegalArgumentException
-     *             if the flatness or limit is less than zero.
-     * @throws NullPointerException
-     *             if the path is null.
-     */
-    public FlatteningPathIterator(PathIterator path, double flatness, int limit) {
-        if (flatness < 0.0) {
-            // awt.206=Flatness is less then zero
-            throw new IllegalArgumentException(Messages.getString("awt.206")); //$NON-NLS-1$
-        }
-        if (limit < 0) {
-            // awt.207=Limit is less then zero
-            throw new IllegalArgumentException(Messages.getString("awt.207")); //$NON-NLS-1$
-        }
-        if (path == null) {
-            // awt.208=Path is null
-            throw new NullPointerException(Messages.getString("awt.208")); //$NON-NLS-1$
-        }
-        this.p = path;
-        this.flatness = flatness;
-        this.flatness2 = flatness * flatness;
-        this.bufLimit = limit;
-        this.bufSize = Math.min(bufLimit, BUFFER_SIZE);
-        this.buf = new double[bufSize];
-        this.bufIndex = bufSize;
-    }
-
-    /**
-     * Gets the flattening factor.
-     * 
-     * @return the flattening factor.
-     */
-    public double getFlatness() {
-        return flatness;
-    }
-
-    /**
-     * Gets the maximum number of subdivisions per curved segment.
-     * 
-     * @return the maximum number of subdivisions per curved segment.
-     */
-    public int getRecursionLimit() {
-        return bufLimit;
-    }
-
-    public int getWindingRule() {
-        return p.getWindingRule();
-    }
-
-    public boolean isDone() {
-        return bufEmpty && p.isDone();
-    }
-
-    /**
-     * Calculates flat path points for current segment of the source shape. Line
-     * segment is flat by itself. Flatness of quad and cubic curves evaluated by
-     * getFlatnessSq() method. Curves subdivided until current flatness is
-     * bigger than user defined and subdivision limit isn't exhausted. Single
-     * source segment translated to series of buffer points. The less flatness
-     * the bigger series. Every currentSegment() call extract one point from the
-     * buffer. When series completed evaluate() takes next source shape segment.
-     */
-    void evaluate() {
-        if (bufEmpty) {
-            bufType = p.currentSegment(coords);
-        }
-
-        switch (bufType) {
-            case SEG_MOVETO:
-            case SEG_LINETO:
-                px = coords[0];
-                py = coords[1];
-                break;
-            case SEG_QUADTO:
-                if (bufEmpty) {
-                    bufIndex -= 6;
-                    buf[bufIndex + 0] = px;
-                    buf[bufIndex + 1] = py;
-                    System.arraycopy(coords, 0, buf, bufIndex + 2, 4);
-                    bufSubdiv = 0;
-                }
-
-                while (bufSubdiv < bufLimit) {
-                    if (QuadCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
-                        break;
-                    }
-
-                    // Realloc buffer
-                    if (bufIndex <= 4) {
-                        double tmp[] = new double[bufSize + BUFFER_CAPACITY];
-                        System.arraycopy(buf, bufIndex, tmp, bufIndex + BUFFER_CAPACITY, bufSize
-                                - bufIndex);
-                        buf = tmp;
-                        bufSize += BUFFER_CAPACITY;
-                        bufIndex += BUFFER_CAPACITY;
-                    }
-
-                    QuadCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 4, buf, bufIndex);
-
-                    bufIndex -= 4;
-                    bufSubdiv++;
-                }
-
-                bufIndex += 4;
-                px = buf[bufIndex];
-                py = buf[bufIndex + 1];
-
-                bufEmpty = (bufIndex == bufSize - 2);
-                if (bufEmpty) {
-                    bufIndex = bufSize;
-                    bufType = SEG_LINETO;
-                } else {
-                    bufSubdiv--;
-                }
-                break;
-            case SEG_CUBICTO:
-                if (bufEmpty) {
-                    bufIndex -= 8;
-                    buf[bufIndex + 0] = px;
-                    buf[bufIndex + 1] = py;
-                    System.arraycopy(coords, 0, buf, bufIndex + 2, 6);
-                    bufSubdiv = 0;
-                }
-
-                while (bufSubdiv < bufLimit) {
-                    if (CubicCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
-                        break;
-                    }
-
-                    // Realloc buffer
-                    if (bufIndex <= 6) {
-                        double tmp[] = new double[bufSize + BUFFER_CAPACITY];
-                        System.arraycopy(buf, bufIndex, tmp, bufIndex + BUFFER_CAPACITY, bufSize
-                                - bufIndex);
-                        buf = tmp;
-                        bufSize += BUFFER_CAPACITY;
-                        bufIndex += BUFFER_CAPACITY;
-                    }
-
-                    CubicCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 6, buf, bufIndex);
-
-                    bufIndex -= 6;
-                    bufSubdiv++;
-                }
-
-                bufIndex += 6;
-                px = buf[bufIndex];
-                py = buf[bufIndex + 1];
-
-                bufEmpty = (bufIndex == bufSize - 2);
-                if (bufEmpty) {
-                    bufIndex = bufSize;
-                    bufType = SEG_LINETO;
-                } else {
-                    bufSubdiv--;
-                }
-                break;
-        }
-
-    }
-
-    public void next() {
-        if (bufEmpty) {
-            p.next();
-        }
-    }
-
-    public int currentSegment(float[] coords) {
-        if (isDone()) {
-            // awt.4B=Iterator out of bounds
-            throw new NoSuchElementException(Messages.getString("awt.4Bx")); //$NON-NLS-1$
-        }
-        evaluate();
-        int type = bufType;
-        if (type != SEG_CLOSE) {
-            coords[0] = (float)px;
-            coords[1] = (float)py;
-            if (type != SEG_MOVETO) {
-                type = SEG_LINETO;
-            }
-        }
-        return type;
-    }
-
-    public int currentSegment(double[] coords) {
-        if (isDone()) {
-            // awt.4B=Iterator out of bounds
-            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-        }
-        evaluate();
-        int type = bufType;
-        if (type != SEG_CLOSE) {
-            coords[0] = px;
-            coords[1] = py;
-            if (type != SEG_MOVETO) {
-                type = SEG_LINETO;
-            }
-        }
-        return type;
-    }
-}
diff --git a/awt/java/awt/geom/GeneralPath.java b/awt/java/awt/geom/GeneralPath.java
deleted file mode 100644
index 0669bc7..0000000
--- a/awt/java/awt/geom/GeneralPath.java
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.gl.Crossing;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The class GeneralPath represents a shape whose outline is given by different
- * types of curved and straight segments.
- * 
- * @since Android 1.0
- */
-public final class GeneralPath implements Shape, Cloneable {
-
-    /**
-     * The Constant WIND_EVEN_ODD see {@link PathIterator#WIND_EVEN_ODD}.
-     */
-    public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;
-
-    /**
-     * The Constant WIND_NON_ZERO see {@link PathIterator#WIND_NON_ZERO}.
-     */
-    public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
-
-    /**
-     * The buffers size.
-     */
-    private static final int BUFFER_SIZE = 10;
-
-    /**
-     * The buffers capacity.
-     */
-    private static final int BUFFER_CAPACITY = 10;
-
-    /**
-     * The point's types buffer.
-     */
-    byte[] types;
-
-    /**
-     * The points buffer.
-     */
-    float[] points;
-
-    /**
-     * The point's type buffer size.
-     */
-    int typeSize;
-
-    /**
-     * The points buffer size.
-     */
-    int pointSize;
-
-    /**
-     * The path rule.
-     */
-    int rule;
-
-    /**
-     * The space amount in points buffer for different segmenet's types.
-     */
-    static int pointShift[] = {
-            2, // MOVETO
-            2, // LINETO
-            4, // QUADTO
-            6, // CUBICTO
-            0
-    }; // CLOSE
-
-    /*
-     * GeneralPath path iterator
-     */
-    /**
-     * The Class Iterator is the subclass of Iterator for traversing the outline
-     * of a GeneralPath.
-     */
-    class Iterator implements PathIterator {
-
-        /**
-         * The current cursor position in types buffer.
-         */
-        int typeIndex;
-
-        /**
-         * The current cursor position in points buffer.
-         */
-        int pointIndex;
-
-        /**
-         * The source GeneralPath object.
-         */
-        GeneralPath p;
-
-        /**
-         * The path iterator transformation.
-         */
-        AffineTransform t;
-
-        /**
-         * Constructs a new GeneralPath.Iterator for given general path.
-         * 
-         * @param path
-         *            the source GeneralPath object.
-         */
-        Iterator(GeneralPath path) {
-            this(path, null);
-        }
-
-        /**
-         * Constructs a new GeneralPath.Iterator for given general path and
-         * transformation.
-         * 
-         * @param path
-         *            the source GeneralPath object.
-         * @param at
-         *            the AffineTransform object to apply rectangle path.
-         */
-        Iterator(GeneralPath path, AffineTransform at) {
-            this.p = path;
-            this.t = at;
-        }
-
-        public int getWindingRule() {
-            return p.getWindingRule();
-        }
-
-        public boolean isDone() {
-            return typeIndex >= p.typeSize;
-        }
-
-        public void next() {
-            typeIndex++;
-        }
-
-        public int currentSegment(double[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type = p.types[typeIndex];
-            int count = GeneralPath.pointShift[type];
-            for (int i = 0; i < count; i++) {
-                coords[i] = p.points[pointIndex + i];
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, count / 2);
-            }
-            pointIndex += count;
-            return type;
-        }
-
-        public int currentSegment(float[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type = p.types[typeIndex];
-            int count = GeneralPath.pointShift[type];
-            System.arraycopy(p.points, pointIndex, coords, 0, count);
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, count / 2);
-            }
-            pointIndex += count;
-            return type;
-        }
-
-    }
-
-    /**
-     * Instantiates a new general path with the winding rule set to
-     * {@link PathIterator#WIND_NON_ZERO} and the initial capacity (number of
-     * segments) set to the default value 10.
-     */
-    public GeneralPath() {
-        this(WIND_NON_ZERO, BUFFER_SIZE);
-    }
-
-    /**
-     * Instantiates a new general path with the given winding rule and the
-     * initial capacity (number of segments) set to the default value 10.
-     * 
-     * @param rule
-     *            the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
-     *            {@link PathIterator#WIND_NON_ZERO}.
-     */
-    public GeneralPath(int rule) {
-        this(rule, BUFFER_SIZE);
-    }
-
-    /**
-     * Instantiates a new general path with the given winding rule and initial
-     * capacity (number of segments).
-     * 
-     * @param rule
-     *            the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
-     *            {@link PathIterator#WIND_NON_ZERO}.
-     * @param initialCapacity
-     *            the number of segments the path is set to hold.
-     */
-    public GeneralPath(int rule, int initialCapacity) {
-        setWindingRule(rule);
-        types = new byte[initialCapacity];
-        points = new float[initialCapacity * 2];
-    }
-
-    /**
-     * Creates a new GeneralPath from the outline of the given shape.
-     * 
-     * @param shape
-     *            the shape.
-     */
-    public GeneralPath(Shape shape) {
-        this(WIND_NON_ZERO, BUFFER_SIZE);
-        PathIterator p = shape.getPathIterator(null);
-        setWindingRule(p.getWindingRule());
-        append(p, false);
-    }
-
-    /**
-     * Sets the winding rule, which determines how to decide whether a point
-     * that isn't on the path itself is inside or outside of the shape.
-     * 
-     * @param rule
-     *            the new winding rule.
-     * @throws IllegalArgumentException
-     *             if the winding rule is neither
-     *             {@link PathIterator#WIND_EVEN_ODD} nor
-     *             {@link PathIterator#WIND_NON_ZERO}.
-     */
-    public void setWindingRule(int rule) {
-        if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) {
-            // awt.209=Invalid winding rule value
-            throw new java.lang.IllegalArgumentException(Messages.getString("awt.209")); //$NON-NLS-1$
-        }
-        this.rule = rule;
-    }
-
-    /**
-     * Gets the winding rule.
-     * 
-     * @return the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
-     *         {@link PathIterator#WIND_NON_ZERO}.
-     */
-    public int getWindingRule() {
-        return rule;
-    }
-
-    /**
-     * Checks the point data buffer sizes to see whether pointCount additional
-     * point-data elements can fit. (Note that the number of point data elements
-     * to add is more than one per point -- it depends on the type of point
-     * being added.) Reallocates the buffers to enlarge the size if necessary.
-     * 
-     * @param pointCount
-     *            the number of point data elements to be added.
-     * @param checkMove
-     *            whether to check for existing points.
-     * @throws IllegalPathStateException
-     *             checkMove is true and the path is currently empty.
-     */
-    void checkBuf(int pointCount, boolean checkMove) {
-        if (checkMove && typeSize == 0) {
-            // awt.20A=First segment should be SEG_MOVETO type
-            throw new IllegalPathStateException(Messages.getString("awt.20A")); //$NON-NLS-1$
-        }
-        if (typeSize == types.length) {
-            byte tmp[] = new byte[typeSize + BUFFER_CAPACITY];
-            System.arraycopy(types, 0, tmp, 0, typeSize);
-            types = tmp;
-        }
-        if (pointSize + pointCount > points.length) {
-            float tmp[] = new float[pointSize + Math.max(BUFFER_CAPACITY * 2, pointCount)];
-            System.arraycopy(points, 0, tmp, 0, pointSize);
-            points = tmp;
-        }
-    }
-
-    /**
-     * Appends a new point to the end of this general path, disconnected from
-     * the existing path.
-     * 
-     * @param x
-     *            the x coordinate of the next point to append.
-     * @param y
-     *            the y coordinate of the next point to append.
-     */
-    public void moveTo(float x, float y) {
-        if (typeSize > 0 && types[typeSize - 1] == PathIterator.SEG_MOVETO) {
-            points[pointSize - 2] = x;
-            points[pointSize - 1] = y;
-        } else {
-            checkBuf(2, false);
-            types[typeSize++] = PathIterator.SEG_MOVETO;
-            points[pointSize++] = x;
-            points[pointSize++] = y;
-        }
-    }
-
-    /**
-     * Appends a new segment to the end of this general path by making a
-     * straight line segment from the current endpoint to the given new point.
-     * 
-     * @param x
-     *            the x coordinate of the next point to append.
-     * @param y
-     *            the y coordinate of the next point to append.
-     */
-    public void lineTo(float x, float y) {
-        checkBuf(2, true);
-        types[typeSize++] = PathIterator.SEG_LINETO;
-        points[pointSize++] = x;
-        points[pointSize++] = y;
-    }
-
-    /**
-     * Appends a new segment to the end of this general path by making a
-     * quadratic curve from the current endpoint to the point (x2, y2) using the
-     * point (x1, y1) as the quadratic curve's control point.
-     * 
-     * @param x1
-     *            the x coordinate of the quadratic curve's control point.
-     * @param y1
-     *            the y coordinate of the quadratic curve's control point.
-     * @param x2
-     *            the x coordinate of the quadratic curve's end point.
-     * @param y2
-     *            the y coordinate of the quadratic curve's end point.
-     */
-    public void quadTo(float x1, float y1, float x2, float y2) {
-        checkBuf(4, true);
-        types[typeSize++] = PathIterator.SEG_QUADTO;
-        points[pointSize++] = x1;
-        points[pointSize++] = y1;
-        points[pointSize++] = x2;
-        points[pointSize++] = y2;
-    }
-
-    /**
-     * Appends a new segment to the end of this general path by making a cubic
-     * curve from the current endpoint to the point (x3, y3) using (x1, y1) and
-     * (x2, y2) as control points.
-     * 
-     * @see java.awt.geom.CubicCurve2D
-     * @param x1
-     *            the x coordinate of the new cubic segment's first control
-     *            point.
-     * @param y1
-     *            the y coordinate of the new cubic segment's first control
-     *            point.
-     * @param x2
-     *            the x coordinate of the new cubic segment's second control
-     *            point.
-     * @param y2
-     *            the y coordinate of the new cubic segment's second control
-     *            point.
-     * @param x3
-     *            the x coordinate of the new cubic segment's end point.
-     * @param y3
-     *            the y coordinate of the new cubic segment's end point.
-     */
-    public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) {
-        checkBuf(6, true);
-        types[typeSize++] = PathIterator.SEG_CUBICTO;
-        points[pointSize++] = x1;
-        points[pointSize++] = y1;
-        points[pointSize++] = x2;
-        points[pointSize++] = y2;
-        points[pointSize++] = x3;
-        points[pointSize++] = y3;
-    }
-
-    /**
-     * Appends the type information to declare that the current endpoint closes
-     * the curve.
-     */
-    public void closePath() {
-        if (typeSize == 0 || types[typeSize - 1] != PathIterator.SEG_CLOSE) {
-            checkBuf(0, true);
-            types[typeSize++] = PathIterator.SEG_CLOSE;
-        }
-    }
-
-    /**
-     * Appends the outline of the specified shape onto the end of this
-     * GeneralPath.
-     * 
-     * @param shape
-     *            the shape whose outline is to be appended.
-     * @param connect
-     *            true to connect this path's current endpoint to the first
-     *            point of the shape's outline or false to append the shape's
-     *            outline without connecting it.
-     * @throws NullPointerException
-     *             if the shape parameter is null.
-     */
-    public void append(Shape shape, boolean connect) {
-        PathIterator p = shape.getPathIterator(null);
-        append(p, connect);
-    }
-
-    /**
-     * Appends the path defined by the specified PathIterator onto the end of
-     * this GeneralPath.
-     * 
-     * @param path
-     *            the PathIterator that defines the new path to append.
-     * @param connect
-     *            true to connect this path's current endpoint to the first
-     *            point of the shape's outline or false to append the shape's
-     *            outline without connecting it.
-     */
-    public void append(PathIterator path, boolean connect) {
-        while (!path.isDone()) {
-            float coords[] = new float[6];
-            switch (path.currentSegment(coords)) {
-                case PathIterator.SEG_MOVETO:
-                    if (!connect || typeSize == 0) {
-                        moveTo(coords[0], coords[1]);
-                        break;
-                    }
-                    if (types[typeSize - 1] != PathIterator.SEG_CLOSE
-                            && points[pointSize - 2] == coords[0]
-                            && points[pointSize - 1] == coords[1]) {
-                        break;
-                    }
-                    // NO BREAK;
-                case PathIterator.SEG_LINETO:
-                    lineTo(coords[0], coords[1]);
-                    break;
-                case PathIterator.SEG_QUADTO:
-                    quadTo(coords[0], coords[1], coords[2], coords[3]);
-                    break;
-                case PathIterator.SEG_CUBICTO:
-                    curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
-                    break;
-                case PathIterator.SEG_CLOSE:
-                    closePath();
-                    break;
-            }
-            path.next();
-            connect = false;
-        }
-    }
-
-    /**
-     * Gets the current end point of the path.
-     * 
-     * @return the current end point of the path.
-     */
-    public Point2D getCurrentPoint() {
-        if (typeSize == 0) {
-            return null;
-        }
-        int j = pointSize - 2;
-        if (types[typeSize - 1] == PathIterator.SEG_CLOSE) {
-
-            for (int i = typeSize - 2; i > 0; i--) {
-                int type = types[i];
-                if (type == PathIterator.SEG_MOVETO) {
-                    break;
-                }
-                j -= pointShift[type];
-            }
-        }
-        return new Point2D.Float(points[j], points[j + 1]);
-    }
-
-    /**
-     * Resets the GeneralPath to being an empty path. The underlying point and
-     * segment data is not deleted but rather the end indices of the data arrays
-     * are set to zero.
-     */
-    public void reset() {
-        typeSize = 0;
-        pointSize = 0;
-    }
-
-    /**
-     * Transform all of the coordinates of this path according to the specified
-     * AffineTransform.
-     * 
-     * @param t
-     *            the AffineTransform.
-     */
-    public void transform(AffineTransform t) {
-        t.transform(points, 0, points, 0, pointSize / 2);
-    }
-
-    /**
-     * Creates a new GeneralPath whose data is given by this path's data
-     * transformed according to the specified AffineTransform.
-     * 
-     * @param t
-     *            the AffineTransform.
-     * @return the new GeneralPath whose data is given by this path's data
-     *         transformed according to the specified AffineTransform.
-     */
-    public Shape createTransformedShape(AffineTransform t) {
-        GeneralPath p = (GeneralPath)clone();
-        if (t != null) {
-            p.transform(t);
-        }
-        return p;
-    }
-
-    public Rectangle2D getBounds2D() {
-        float rx1, ry1, rx2, ry2;
-        if (pointSize == 0) {
-            rx1 = ry1 = rx2 = ry2 = 0.0f;
-        } else {
-            int i = pointSize - 1;
-            ry1 = ry2 = points[i--];
-            rx1 = rx2 = points[i--];
-            while (i > 0) {
-                float y = points[i--];
-                float x = points[i--];
-                if (x < rx1) {
-                    rx1 = x;
-                } else if (x > rx2) {
-                    rx2 = x;
-                }
-                if (y < ry1) {
-                    ry1 = y;
-                } else if (y > ry2) {
-                    ry2 = y;
-                }
-            }
-        }
-        return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
-    }
-
-    public Rectangle getBounds() {
-        return getBounds2D().getBounds();
-    }
-
-    /**
-     * Checks the cross count (number of times a ray from the point crosses the
-     * shape's boundary) to determine whether the number of crossings
-     * corresponds to a point inside the shape or not (according to the shape's
-     * path rule).
-     * 
-     * @param cross
-     *            the point's cross count.
-     * @return true if the point is inside the path, or false otherwise.
-     */
-    boolean isInside(int cross) {
-        if (rule == WIND_NON_ZERO) {
-            return Crossing.isInsideNonZero(cross);
-        }
-        return Crossing.isInsideEvenOdd(cross);
-    }
-
-    public boolean contains(double px, double py) {
-        return isInside(Crossing.crossShape(this, px, py));
-    }
-
-    public boolean contains(double rx, double ry, double rw, double rh) {
-        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
-        return cross != Crossing.CROSSING && isInside(cross);
-    }
-
-    public boolean intersects(double rx, double ry, double rw, double rh) {
-        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
-        return cross == Crossing.CROSSING || isInside(cross);
-    }
-
-    public boolean contains(Point2D p) {
-        return contains(p.getX(), p.getY());
-    }
-
-    public boolean contains(Rectangle2D r) {
-        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
-    }
-
-    public boolean intersects(Rectangle2D r) {
-        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
-    }
-
-    public PathIterator getPathIterator(AffineTransform t) {
-        return new Iterator(this, t);
-    }
-
-    public PathIterator getPathIterator(AffineTransform t, double flatness) {
-        return new FlatteningPathIterator(getPathIterator(t), flatness);
-    }
-
-    @Override
-    public Object clone() {
-        try {
-            GeneralPath p = (GeneralPath)super.clone();
-            p.types = types.clone();
-            p.points = points.clone();
-            return p;
-        } catch (CloneNotSupportedException e) {
-            throw new InternalError();
-        }
-    }
-
-}
diff --git a/awt/java/awt/geom/IllegalPathStateException.java b/awt/java/awt/geom/IllegalPathStateException.java
deleted file mode 100644
index 750ba29..0000000
--- a/awt/java/awt/geom/IllegalPathStateException.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-/**
- * The Class IllegalPathStateException indicates errors where the current state
- * of a path object is incompatible with the desired action, such as performing
- * non-trivial actions on an empty path.
- * 
- * @since Android 1.0
- */
-public class IllegalPathStateException extends RuntimeException {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -5158084205220481094L;
-
-    /**
-     * Instantiates a new illegal path state exception.
-     */
-    public IllegalPathStateException() {
-    }
-
-    /**
-     * Instantiates a new illegal path state exception with the specified detail
-     * message.
-     * 
-     * @param s
-     *            the details of the error.
-     */
-    public IllegalPathStateException(String s) {
-        super(s);
-    }
-
-}
diff --git a/awt/java/awt/geom/Line2D.java b/awt/java/awt/geom/Line2D.java
deleted file mode 100644
index fcd51b6..0000000
--- a/awt/java/awt/geom/Line2D.java
+++ /dev/null
@@ -1,948 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class Line2D represents a line whose data is given in high-precision
- * values appropriate for graphical operations.
- * 
- * @since Android 1.0
- */
-public abstract class Line2D implements Shape, Cloneable {
-
-    /**
-     * The Class Float is the subclass of Line2D that has all of its data values
-     * stored with float-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Float extends Line2D {
-
-        /**
-         * The x coordinate of the starting point.
-         */
-        public float x1;
-
-        /**
-         * The y coordinate of the starting point.
-         */
-        public float y1;
-
-        /**
-         * The x coordinate of the end point.
-         */
-        public float x2;
-
-        /**
-         * The y coordinate of the end point.
-         */
-        public float y2;
-
-        /**
-         * Instantiates a new float-valued Line2D with its data values set to
-         * zero.
-         */
-        public Float() {
-        }
-
-        /**
-         * Instantiates a new float-valued Line2D with the specified endpoints.
-         * 
-         * @param x1
-         *            the x coordinate of the starting point.
-         * @param y1
-         *            the y coordinate of the starting point.
-         * @param x2
-         *            the x coordinate of the end point.
-         * @param y2
-         *            the y coordinate of the end point.
-         */
-        public Float(float x1, float y1, float x2, float y2) {
-            setLine(x1, y1, x2, y2);
-        }
-
-        /**
-         * Instantiates a new float-valued Line2D with the specified endpoints.
-         * 
-         * @param p1
-         *            the starting point.
-         * @param p2
-         *            the end point.
-         */
-        public Float(Point2D p1, Point2D p2) {
-            setLine(p1, p2);
-        }
-
-        @Override
-        public double getX1() {
-            return x1;
-        }
-
-        @Override
-        public double getY1() {
-            return y1;
-        }
-
-        @Override
-        public double getX2() {
-            return x2;
-        }
-
-        @Override
-        public double getY2() {
-            return y2;
-        }
-
-        @Override
-        public Point2D getP1() {
-            return new Point2D.Float(x1, y1);
-        }
-
-        @Override
-        public Point2D getP2() {
-            return new Point2D.Float(x2, y2);
-        }
-
-        @Override
-        public void setLine(double x1, double y1, double x2, double y2) {
-            this.x1 = (float)x1;
-            this.y1 = (float)y1;
-            this.x2 = (float)x2;
-            this.y2 = (float)y2;
-        }
-
-        /**
-         * Sets the data values that define the line.
-         * 
-         * @param x1
-         *            the x coordinate of the starting point.
-         * @param y1
-         *            the y coordinate of the starting point.
-         * @param x2
-         *            the x coordinate of the end point.
-         * @param y2
-         *            the y coordinate of the end point.
-         */
-        public void setLine(float x1, float y1, float x2, float y2) {
-            this.x1 = x1;
-            this.y1 = y1;
-            this.x2 = x2;
-            this.y2 = y2;
-        }
-
-        public Rectangle2D getBounds2D() {
-            float rx, ry, rw, rh;
-            if (x1 < x2) {
-                rx = x1;
-                rw = x2 - x1;
-            } else {
-                rx = x2;
-                rw = x1 - x2;
-            }
-            if (y1 < y2) {
-                ry = y1;
-                rh = y2 - y1;
-            } else {
-                ry = y2;
-                rh = y1 - y2;
-            }
-            return new Rectangle2D.Float(rx, ry, rw, rh);
-        }
-    }
-
-    /**
-     * The Class Double is the subclass of Line2D that has all of its data
-     * values stored with double-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Double extends Line2D {
-
-        /**
-         * The x coordinate of the starting point.
-         */
-        public double x1;
-
-        /**
-         * The y coordinate of the starting point.
-         */
-        public double y1;
-
-        /**
-         * The x coordinate of the end point.
-         */
-        public double x2;
-
-        /**
-         * The y coordinate of the end point.
-         */
-        public double y2;
-
-        /**
-         * Instantiates a new double-valued Line2D with its data values set to
-         * zero.
-         */
-        public Double() {
-        }
-
-        /**
-         * Instantiates a new double-valued Line2D with the specified endpoints.
-         * 
-         * @param x1
-         *            the x coordinate of the starting point.
-         * @param y1
-         *            the y coordinate of the starting point.
-         * @param x2
-         *            the x coordinate of the end point.
-         * @param y2
-         *            the y coordinate of the end point.
-         */
-        public Double(double x1, double y1, double x2, double y2) {
-            setLine(x1, y1, x2, y2);
-        }
-
-        /**
-         * Instantiates a new double-valued Line2D with the specified endpoints.
-         * 
-         * @param p1
-         *            the starting point.
-         * @param p2
-         *            the end point.
-         */
-        public Double(Point2D p1, Point2D p2) {
-            setLine(p1, p2);
-        }
-
-        @Override
-        public double getX1() {
-            return x1;
-        }
-
-        @Override
-        public double getY1() {
-            return y1;
-        }
-
-        @Override
-        public double getX2() {
-            return x2;
-        }
-
-        @Override
-        public double getY2() {
-            return y2;
-        }
-
-        @Override
-        public Point2D getP1() {
-            return new Point2D.Double(x1, y1);
-        }
-
-        @Override
-        public Point2D getP2() {
-            return new Point2D.Double(x2, y2);
-        }
-
-        @Override
-        public void setLine(double x1, double y1, double x2, double y2) {
-            this.x1 = x1;
-            this.y1 = y1;
-            this.x2 = x2;
-            this.y2 = y2;
-        }
-
-        public Rectangle2D getBounds2D() {
-            double rx, ry, rw, rh;
-            if (x1 < x2) {
-                rx = x1;
-                rw = x2 - x1;
-            } else {
-                rx = x2;
-                rw = x1 - x2;
-            }
-            if (y1 < y2) {
-                ry = y1;
-                rh = y2 - y1;
-            } else {
-                ry = y2;
-                rh = y1 - y2;
-            }
-            return new Rectangle2D.Double(rx, ry, rw, rh);
-        }
-    }
-
-    /*
-     * Line2D path iterator
-     */
-    /**
-     * The subclass of PathIterator to traverse a Line2D.
-     */
-    class Iterator implements PathIterator {
-
-        /**
-         * The x coordinate of the start line point.
-         */
-        double x1;
-
-        /**
-         * The y coordinate of the start line point.
-         */
-        double y1;
-
-        /**
-         * The x coordinate of the end line point.
-         */
-        double x2;
-
-        /**
-         * The y coordinate of the end line point.
-         */
-        double y2;
-
-        /**
-         * The path iterator transformation.
-         */
-        AffineTransform t;
-
-        /**
-         * The current segment index.
-         */
-        int index;
-
-        /**
-         * Constructs a new Line2D.Iterator for given line and transformation.
-         * 
-         * @param l
-         *            the source Line2D object.
-         * @param at
-         *            the AffineTransform object to apply rectangle path.
-         */
-        Iterator(Line2D l, AffineTransform at) {
-            this.x1 = l.getX1();
-            this.y1 = l.getY1();
-            this.x2 = l.getX2();
-            this.y2 = l.getY2();
-            this.t = at;
-        }
-
-        public int getWindingRule() {
-            return WIND_NON_ZERO;
-        }
-
-        public boolean isDone() {
-            return index > 1;
-        }
-
-        public void next() {
-            index++;
-        }
-
-        public int currentSegment(double[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                coords[0] = x1;
-                coords[1] = y1;
-            } else {
-                type = SEG_LINETO;
-                coords[0] = x2;
-                coords[1] = y2;
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, 1);
-            }
-            return type;
-        }
-
-        public int currentSegment(float[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                coords[0] = (float)x1;
-                coords[1] = (float)y1;
-            } else {
-                type = SEG_LINETO;
-                coords[0] = (float)x2;
-                coords[1] = (float)y2;
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, 1);
-            }
-            return type;
-        }
-
-    }
-
-    /**
-     * Instantiates a new Line2D.
-     */
-    protected Line2D() {
-    }
-
-    /**
-     * Gets the x coordinate of the starting point.
-     * 
-     * @return the x coordinate of the starting point.
-     */
-    public abstract double getX1();
-
-    /**
-     * Gets the y coordinate of the starting point.
-     * 
-     * @return the y coordinate of the starting point.
-     */
-    public abstract double getY1();
-
-    /**
-     * Gets the x coordinate of the end point.
-     * 
-     * @return the x2.
-     */
-    public abstract double getX2();
-
-    /**
-     * Gets the y coordinate of the end point.
-     * 
-     * @return the y coordinate of the end point.
-     */
-    public abstract double getY2();
-
-    /**
-     * Gets the p the starting point.
-     * 
-     * @return the p the starting point.
-     */
-    public abstract Point2D getP1();
-
-    /**
-     * Gets the p end point.
-     * 
-     * @return the p end point.
-     */
-    public abstract Point2D getP2();
-
-    /**
-     * Sets the line's endpoints.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point.
-     * @param y1
-     *            the y coordinate of the starting point.
-     * @param x2
-     *            the x coordinate of the end point.
-     * @param y2
-     *            the y coordinate of the end point.
-     */
-    public abstract void setLine(double x1, double y1, double x2, double y2);
-
-    /**
-     * Sets the line's endpoints.
-     * 
-     * @param p1
-     *            the starting point.
-     * @param p2
-     *            the end point.
-     */
-    public void setLine(Point2D p1, Point2D p2) {
-        setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
-    }
-
-    /**
-     * Sets the line's endpoints by copying the data from another Line2D.
-     * 
-     * @param line
-     *            the Line2D to copy the endpoint data from.
-     */
-    public void setLine(Line2D line) {
-        setLine(line.getX1(), line.getY1(), line.getX2(), line.getY2());
-    }
-
-    public Rectangle getBounds() {
-        return getBounds2D().getBounds();
-    }
-
-    /**
-     * Tells where the point is with respect to the line segment, given the
-     * orientation of the line segment. If the ray found by extending the line
-     * segment from its starting point is rotated, this method tells whether the
-     * ray should rotate in a clockwise direction or a counter-clockwise
-     * direction to hit the point first. The return value is 0 if the point is
-     * on the line segment, it's 1 if the point is on the ray or if the ray
-     * should rotate in a counter-clockwise direction to get to the point, and
-     * it's -1 if the ray should rotate in a clockwise direction to get to the
-     * point or if the point is on the line determined by the line segment but
-     * not on the ray from the segment's starting point and through its end
-     * point.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point of the line segment.
-     * @param y1
-     *            the y coordinate of the starting point of the line segment.
-     * @param x2
-     *            the x coordinate of the end point of the line segment.
-     * @param y2
-     *            the y coordinate of the end point of the line segment.
-     * @param px
-     *            the x coordinate of the test point.
-     * @param py
-     *            the p coordinate of the test point.
-     * @return the value that describes where the point is with respect to the
-     *         line segment, given the orientation of the line segment.
-     */
-    public static int relativeCCW(double x1, double y1, double x2, double y2, double px, double py) {
-        /*
-         * A = (x2-x1, y2-y1) P = (px-x1, py-y1)
-         */
-        x2 -= x1;
-        y2 -= y1;
-        px -= x1;
-        py -= y1;
-        double t = px * y2 - py * x2; // PxA
-        if (t == 0.0) {
-            t = px * x2 + py * y2; // P*A
-            if (t > 0.0) {
-                px -= x2; // B-A
-                py -= y2;
-                t = px * x2 + py * y2; // (P-A)*A
-                if (t < 0.0) {
-                    t = 0.0;
-                }
-            }
-        }
-
-        return t < 0.0 ? -1 : (t > 0.0 ? 1 : 0);
-    }
-
-    /**
-     * Tells where the point is with respect to this line segment, given the
-     * orientation of this line segment. If the ray found by extending the line
-     * segment from its starting point is rotated, this method tells whether the
-     * ray should rotate in a clockwise direction or a counter-clockwise
-     * direction to hit the point first. The return value is 0 if the point is
-     * on the line segment, it's 1 if the point is on the ray or if the ray
-     * should rotate in a counter-clockwise direction to get to the point, and
-     * it's -1 if the ray should rotate in a clockwise direction to get to the
-     * point or if the point is on the line determined by the line segment but
-     * not on the ray from the segment's starting point and through its end
-     * point.
-     * 
-     * @param px
-     *            the x coordinate of the test point.
-     * @param py
-     *            the p coordinate of the test point.
-     * @return the value that describes where the point is with respect to this
-     *         line segment, given the orientation of this line segment.
-     */
-    public int relativeCCW(double px, double py) {
-        return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
-    }
-
-    /**
-     * Tells where the point is with respect to this line segment, given the
-     * orientation of this line segment. If the ray found by extending the line
-     * segment from its starting point is rotated, this method tells whether the
-     * ray should rotate in a clockwise direction or a counter-clockwise
-     * direction to hit the point first. The return value is 0 if the point is
-     * on the line segment, it's 1 if the point is on the ray or if the ray
-     * should rotate in a counter-clockwise direction to get to the point, and
-     * it's -1 if the ray should rotate in a clockwise direction to get to the
-     * point or if the point is on the line determined by the line segment but
-     * not on the ray from the segment's starting point and through its end
-     * point.
-     * 
-     * @param p
-     *            the test point.
-     * @return the value that describes where the point is with respect to this
-     *         line segment, given the orientation of this line segment.
-     */
-    public int relativeCCW(Point2D p) {
-        return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
-    }
-
-    /**
-     * Tells whether the two line segments cross.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point of the first segment.
-     * @param y1
-     *            the y coordinate of the starting point of the first segment.
-     * @param x2
-     *            the x coordinate of the end point of the first segment.
-     * @param y2
-     *            the y coordinate of the end point of the first segment.
-     * @param x3
-     *            the x coordinate of the starting point of the second segment.
-     * @param y3
-     *            the y coordinate of the starting point of the second segment.
-     * @param x4
-     *            the x coordinate of the end point of the second segment.
-     * @param y4
-     *            the y coordinate of the end point of the second segment.
-     * @return true, if the two line segments cross.
-     */
-    public static boolean linesIntersect(double x1, double y1, double x2, double y2, double x3,
-            double y3, double x4, double y4) {
-        /*
-         * A = (x2-x1, y2-y1) B = (x3-x1, y3-y1) C = (x4-x1, y4-y1) D = (x4-x3,
-         * y4-y3) = C-B E = (x1-x3, y1-y3) = -B F = (x2-x3, y2-y3) = A-B Result
-         * is ((AxB) (AxC) <=0) and ((DxE) (DxF) <= 0) DxE = (C-B)x(-B) =
-         * BxB-CxB = BxC DxF = (C-B)x(A-B) = CxA-CxB-BxA+BxB = AxB+BxC-AxC
-         */
-
-        x2 -= x1; // A
-        y2 -= y1;
-        x3 -= x1; // B
-        y3 -= y1;
-        x4 -= x1; // C
-        y4 -= y1;
-
-        double AvB = x2 * y3 - x3 * y2;
-        double AvC = x2 * y4 - x4 * y2;
-
-        // Online
-        if (AvB == 0.0 && AvC == 0.0) {
-            if (x2 != 0.0) {
-                return (x4 * x3 <= 0.0)
-                        || ((x3 * x2 >= 0.0) && (x2 > 0.0 ? x3 <= x2 || x4 <= x2 : x3 >= x2
-                                || x4 >= x2));
-            }
-            if (y2 != 0.0) {
-                return (y4 * y3 <= 0.0)
-                        || ((y3 * y2 >= 0.0) && (y2 > 0.0 ? y3 <= y2 || y4 <= y2 : y3 >= y2
-                                || y4 >= y2));
-            }
-            return false;
-        }
-
-        double BvC = x3 * y4 - x4 * y3;
-
-        return (AvB * AvC <= 0.0) && (BvC * (AvB + BvC - AvC) <= 0.0);
-    }
-
-    /**
-     * Tells whether the specified line segments crosses this line segment.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point of the test segment.
-     * @param y1
-     *            the y coordinate of the starting point of the test segment.
-     * @param x2
-     *            the x coordinate of the end point of the test segment.
-     * @param y2
-     *            the y coordinate of the end point of the test segment.
-     * @return true, if the specified line segments crosses this line segment.
-     */
-    public boolean intersectsLine(double x1, double y1, double x2, double y2) {
-        return linesIntersect(x1, y1, x2, y2, getX1(), getY1(), getX2(), getY2());
-    }
-
-    /**
-     * Tells whether the specified line segments crosses this line segment.
-     * 
-     * @param l
-     *            the test segment.
-     * @return true, if the specified line segments crosses this line segment.
-     * @throws NullPointerException
-     *             if l is null.
-     */
-    public boolean intersectsLine(Line2D l) {
-        return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(), getX1(), getY1(),
-                getX2(), getY2());
-    }
-
-    /**
-     * Gives the square of the distance between the point and the line segment.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point of the line segment.
-     * @param y1
-     *            the y coordinate of the starting point of the line segment.
-     * @param x2
-     *            the x coordinate of the end point of the line segment.
-     * @param y2
-     *            the y coordinate of the end point of the line segment.
-     * @param px
-     *            the x coordinate of the test point.
-     * @param py
-     *            the y coordinate of the test point.
-     * @return the the square of the distance between the point and the line
-     *         segment.
-     */
-    public static double ptSegDistSq(double x1, double y1, double x2, double y2, double px,
-            double py) {
-        /*
-         * A = (x2 - x1, y2 - y1) P = (px - x1, py - y1)
-         */
-        x2 -= x1; // A = (x2, y2)
-        y2 -= y1;
-        px -= x1; // P = (px, py)
-        py -= y1;
-        double dist;
-        if (px * x2 + py * y2 <= 0.0) { // P*A
-            dist = px * px + py * py;
-        } else {
-            px = x2 - px; // P = A - P = (x2 - px, y2 - py)
-            py = y2 - py;
-            if (px * x2 + py * y2 <= 0.0) { // P*A
-                dist = px * px + py * py;
-            } else {
-                dist = px * y2 - py * x2;
-                dist = dist * dist / (x2 * x2 + y2 * y2); // pxA/|A|
-            }
-        }
-        if (dist < 0) {
-            dist = 0;
-        }
-        return dist;
-    }
-
-    /**
-     * Gives the distance between the point and the line segment.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point of the line segment.
-     * @param y1
-     *            the y coordinate of the starting point of the line segment.
-     * @param x2
-     *            the x coordinate of the end point of the line segment.
-     * @param y2
-     *            the y coordinate of the end point of the line segment.
-     * @param px
-     *            the x coordinate of the test point.
-     * @param py
-     *            the y coordinate of the test point.
-     * @return the the distance between the point and the line segment.
-     */
-    public static double ptSegDist(double x1, double y1, double x2, double y2, double px, double py) {
-        return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
-    }
-
-    /**
-     * Gives the square of the distance between the point and this line segment.
-     * 
-     * @param px
-     *            the x coordinate of the test point.
-     * @param py
-     *            the y coordinate of the test point.
-     * @return the the square of the distance between the point and this line
-     *         segment.
-     */
-    public double ptSegDistSq(double px, double py) {
-        return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
-    }
-
-    /**
-     * Gives the square of the distance between the point and this line segment.
-     * 
-     * @param p
-     *            the test point.
-     * @return the square of the distance between the point and this line
-     *         segment.
-     */
-    public double ptSegDistSq(Point2D p) {
-        return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
-    }
-
-    /**
-     * Gives the distance between the point and this line segment.
-     * 
-     * @param px
-     *            the x coordinate of the test point.
-     * @param py
-     *            the y coordinate of the test point.
-     * @return the distance between the point and this line segment.
-     */
-    public double ptSegDist(double px, double py) {
-        return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
-    }
-
-    /**
-     * Gives the distance between the point and this line segment.
-     * 
-     * @param p
-     *            the test point.
-     * @return the distance between the point and this line segment.
-     */
-    public double ptSegDist(Point2D p) {
-        return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
-    }
-
-    /**
-     * Gives the square of the distance between the point and the line.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point of the line segment.
-     * @param y1
-     *            the y coordinate of the starting point of the line segment.
-     * @param x2
-     *            the x coordinate of the end point of the line segment.
-     * @param y2
-     *            the y coordinate of the end point of the line segment.
-     * @param px
-     *            the x coordinate of the test point.
-     * @param py
-     *            the y coordinate of the test point.
-     * @return the square of the distance between the point and the line.
-     */
-    public static double ptLineDistSq(double x1, double y1, double x2, double y2, double px,
-            double py) {
-        x2 -= x1;
-        y2 -= y1;
-        px -= x1;
-        py -= y1;
-        double s = px * y2 - py * x2;
-        return s * s / (x2 * x2 + y2 * y2);
-    }
-
-    /**
-     * Gives the square of the distance between the point and the line.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point of the line segment.
-     * @param y1
-     *            the y coordinate of the starting point of the line segment.
-     * @param x2
-     *            the x coordinate of the end point of the line segment.
-     * @param y2
-     *            the y coordinate of the end point of the line segment.
-     * @param px
-     *            the x coordinate of the test point.
-     * @param py
-     *            the y coordinate of the test point.
-     * @return the square of the distance between the point and the line.
-     */
-    public static double ptLineDist(double x1, double y1, double x2, double y2, double px, double py) {
-        return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
-    }
-
-    /**
-     * Gives the square of the distance between the point and the line
-     * determined by this Line2D.
-     * 
-     * @param px
-     *            the x coordinate of the test point.
-     * @param py
-     *            the y coordinate of the test point.
-     * @return the square of the distance between the point and the line
-     *         determined by this Line2D.
-     */
-    public double ptLineDistSq(double px, double py) {
-        return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
-    }
-
-    /**
-     * Gives the square of the distance between the point and the line
-     * determined by this Line2D.
-     * 
-     * @param p
-     *            the test point.
-     * @return the square of the distance between the point and the line
-     *         determined by this Line2D.
-     */
-    public double ptLineDistSq(Point2D p) {
-        return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
-    }
-
-    /**
-     * Gives the distance between the point and the line determined by this
-     * Line2D.
-     * 
-     * @param px
-     *            the x coordinate of the test point.
-     * @param py
-     *            the y coordinate of the test point.
-     * @return the distance between the point and the line determined by this
-     *         Line2D.
-     */
-    public double ptLineDist(double px, double py) {
-        return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
-    }
-
-    /**
-     * Gives the distance between the point and the line determined by this
-     * Line2D.
-     * 
-     * @param p
-     *            the test point.
-     * @return the distance between the point and the line determined by this
-     *         Line2D.
-     */
-    public double ptLineDist(Point2D p) {
-        return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
-    }
-
-    public boolean contains(double px, double py) {
-        return false;
-    }
-
-    public boolean contains(Point2D p) {
-        return false;
-    }
-
-    public boolean contains(Rectangle2D r) {
-        return false;
-    }
-
-    public boolean contains(double rx, double ry, double rw, double rh) {
-        return false;
-    }
-
-    public boolean intersects(double rx, double ry, double rw, double rh) {
-        return intersects(new Rectangle2D.Double(rx, ry, rw, rh));
-    }
-
-    public boolean intersects(Rectangle2D r) {
-        return r.intersectsLine(getX1(), getY1(), getX2(), getY2());
-    }
-
-    public PathIterator getPathIterator(AffineTransform at) {
-        return new Iterator(this, at);
-    }
-
-    public PathIterator getPathIterator(AffineTransform at, double flatness) {
-        return new Iterator(this, at);
-    }
-
-    @Override
-    public Object clone() {
-        try {
-            return super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new InternalError();
-        }
-    }
-
-}
diff --git a/awt/java/awt/geom/NoninvertibleTransformException.java b/awt/java/awt/geom/NoninvertibleTransformException.java
deleted file mode 100644
index a4e6f0f..0000000
--- a/awt/java/awt/geom/NoninvertibleTransformException.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-/**
- * The Class NoninvertibleTransformException is the exception that is thrown
- * when an action requires inverting an {@link AffineTransform} that is not
- * invertible (has determinant 0).
- * 
- * @since Android 1.0
- */
-public class NoninvertibleTransformException extends java.lang.Exception {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 6137225240503990466L;
-
-    /**
-     * Instantiates a new non-invertible transform exception.
-     * 
-     * @param s
-     *            the error message.
-     */
-    public NoninvertibleTransformException(String s) {
-        super(s);
-    }
-
-}
diff --git a/awt/java/awt/geom/PathIterator.java b/awt/java/awt/geom/PathIterator.java
deleted file mode 100644
index 2d1c0ff..0000000
--- a/awt/java/awt/geom/PathIterator.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-/**
- * The Interface PathIterator represents an iterator object that can be used to
- * traverse the outline of a {@link java.awt.Shape}. It returns points along the
- * boundary of the Shape which may be actual vertices (in the case of a shape
- * made of line segments) or may be points on a curved segment with the distance
- * between the points determined by a chosen flattening factor.
- * <p>
- * If the shape is closed, the outline is traversed in the counter-clockwise
- * direction. That means that moving forward along the boundary is to travel in
- * such a way that the interior of the shape is to the left of the outline path
- * and the exterior of the shape is to the right of the outline path. The
- * interior and exterior of the shape are determined by a winding rule.
- * </p>
- * 
- * @since Android 1.0
- */
-public interface PathIterator {
-
-    /**
-     * The Constant WIND_EVEN_ODD indicates the winding rule that says that a
-     * point is outside the shape if any infinite ray from the point crosses the
-     * outline of the shape an even number of times, otherwise it is inside.
-     */
-    public static final int WIND_EVEN_ODD = 0;
-
-    /**
-     * The Constant WIND_NON_ZERO indicates the winding rule that says that a
-     * point is inside the shape if every infinite ray starting from that point
-     * crosses the outline of the shape a non-zero number of times.
-     */
-    public static final int WIND_NON_ZERO = 1;
-
-    /**
-     * The Constant SEG_MOVETO indicates that to follow the shape's outline from
-     * the previous point to the current point, the cursor (traversal point)
-     * should be placed directly on the current point.
-     */
-    public static final int SEG_MOVETO = 0;
-
-    /**
-     * The Constant SEG_LINETO indicates that to follow the shape's outline from
-     * the previous point to the current point, the cursor (traversal point)
-     * should follow a straight line.
-     */
-    public static final int SEG_LINETO = 1;
-
-    /**
-     * The Constant SEG_QUADTO indicates that to follow the shape's outline from
-     * the previous point to the current point, the cursor (traversal point)
-     * should follow a quadratic curve.
-     */
-    public static final int SEG_QUADTO = 2;
-
-    /**
-     * The Constant SEG_CUBICTO indicates that to follow the shape's outline
-     * from the previous point to the current point, the cursor (traversal
-     * point) should follow a cubic curve.
-     */
-    public static final int SEG_CUBICTO = 3;
-
-    /**
-     * The Constant SEG_CLOSE indicates that the previous point was the end of
-     * the shape's outline.
-     */
-    public static final int SEG_CLOSE = 4;
-
-    /**
-     * Gets the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
-     * {@link PathIterator#WIND_NON_ZERO}.
-     * 
-     * @return the winding rule.
-     */
-    public int getWindingRule();
-
-    /**
-     * Checks if this PathIterator has been completely traversed.
-     * 
-     * @return true, if this PathIterator has been completely traversed.
-     */
-    public boolean isDone();
-
-    /**
-     * Tells this PathIterator to skip to the next segment.
-     */
-    public void next();
-
-    /**
-     * Gets the coordinates of the next vertex point along the shape's outline
-     * and a flag that indicates what kind of segment to use in order to connect
-     * the previous vertex point to the current vertex point to form the current
-     * segment.
-     * 
-     * @param coords
-     *            the array that the coordinates of the end point of the current
-     *            segment are written into.
-     * @return the flag that indicates how to follow the shape's outline from
-     *         the previous point to the current one, chosen from the following
-     *         constants: {@link PathIterator#SEG_MOVETO},
-     *         {@link PathIterator#SEG_LINETO}, {@link PathIterator#SEG_QUADTO},
-     *         {@link PathIterator#SEG_CUBICTO}, or
-     *         {@link PathIterator#SEG_CLOSE}.
-     */
-    public int currentSegment(float[] coords);
-
-    /**
-     * Gets the coordinates of the next vertex point along the shape's outline
-     * and a flag that indicates what kind of segment to use in order to connect
-     * the previous vertex point to the current vertex point to form the current
-     * segment.
-     * 
-     * @param coords
-     *            the array that the coordinates of the end point of the current
-     *            segment are written into.
-     * @return the flag that indicates how to follow the shape's outline from
-     *         the previous point to the current one, chosen from the following
-     *         constants: {@link PathIterator#SEG_MOVETO},
-     *         {@link PathIterator#SEG_LINETO}, {@link PathIterator#SEG_QUADTO},
-     *         {@link PathIterator#SEG_CUBICTO}, or
-     *         {@link PathIterator#SEG_CLOSE}.
-     */
-    public int currentSegment(double[] coords);
-
-}
diff --git a/awt/java/awt/geom/Point2D.java b/awt/java/awt/geom/Point2D.java
deleted file mode 100644
index f7026c8..0000000
--- a/awt/java/awt/geom/Point2D.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import org.apache.harmony.misc.HashCode;
-
-/**
- * The Class Point2D represents a point whose data is given in high-precision
- * values appropriate for graphical operations.
- * 
- * @since Android 1.0
- */
-public abstract class Point2D implements Cloneable {
-
-    /**
-     * The Class Float is the subclass of Point2D that has all of its data
-     * values stored with float-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Float extends Point2D {
-
-        /**
-         * The x coordinate.
-         */
-        public float x;
-
-        /**
-         * The y coordinate.
-         */
-        public float y;
-
-        /**
-         * Instantiates a new float-valued Point2D with its data set to zero.
-         */
-        public Float() {
-        }
-
-        /**
-         * Instantiates a new float-valued Point2D with the specified
-         * coordinates.
-         * 
-         * @param x
-         *            the x coordinate.
-         * @param y
-         *            the y coordinate.
-         */
-        public Float(float x, float y) {
-            this.x = x;
-            this.y = y;
-        }
-
-        @Override
-        public double getX() {
-            return x;
-        }
-
-        @Override
-        public double getY() {
-            return y;
-        }
-
-        /**
-         * Sets the point's coordinates.
-         * 
-         * @param x
-         *            the x coordinate.
-         * @param y
-         *            the y coordinate.
-         */
-        public void setLocation(float x, float y) {
-            this.x = x;
-            this.y = y;
-        }
-
-        @Override
-        public void setLocation(double x, double y) {
-            this.x = (float)x;
-            this.y = (float)y;
-        }
-
-        @Override
-        public String toString() {
-            return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-    }
-
-    /**
-     * The Class Double is the subclass of Point2D that has all of its data
-     * values stored with double-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Double extends Point2D {
-
-        /**
-         * The x coordinate.
-         */
-        public double x;
-
-        /**
-         * The y coordinate.
-         */
-        public double y;
-
-        /**
-         * Instantiates a new double-valued Point2D with its data set to zero.
-         */
-        public Double() {
-        }
-
-        /**
-         * Instantiates a new double-valued Point2D with the specified
-         * coordinates.
-         * 
-         * @param x
-         *            the x coordinate.
-         * @param y
-         *            the y coordinate.
-         */
-        public Double(double x, double y) {
-            this.x = x;
-            this.y = y;
-        }
-
-        @Override
-        public double getX() {
-            return x;
-        }
-
-        @Override
-        public double getY() {
-            return y;
-        }
-
-        @Override
-        public void setLocation(double x, double y) {
-            this.x = x;
-            this.y = y;
-        }
-
-        @Override
-        public String toString() {
-            return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-    }
-
-    /**
-     * Instantiates a new Point2D.
-     */
-    protected Point2D() {
-    }
-
-    /**
-     * Gets the x coordinate.
-     * 
-     * @return the x coordinate.
-     */
-    public abstract double getX();
-
-    /**
-     * Gets the y coordinate.
-     * 
-     * @return the y coordinate.
-     */
-    public abstract double getY();
-
-    /**
-     * Sets the point's coordinates.
-     * 
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     */
-    public abstract void setLocation(double x, double y);
-
-    /**
-     * Sets the point's coordinates by copying them from another point.
-     * 
-     * @param p
-     *            the point to copy the data from.
-     */
-    public void setLocation(Point2D p) {
-        setLocation(p.getX(), p.getY());
-    }
-
-    /**
-     * Finds the square of the distance between the two specified points.
-     * 
-     * @param x1
-     *            the x coordinate of the first point.
-     * @param y1
-     *            the y coordinate of the first point.
-     * @param x2
-     *            the x coordinate of the second point.
-     * @param y2
-     *            the y coordinate of the second point.
-     * @return the square of the distance between the two specified points.
-     */
-    public static double distanceSq(double x1, double y1, double x2, double y2) {
-        x2 -= x1;
-        y2 -= y1;
-        return x2 * x2 + y2 * y2;
-    }
-
-    /**
-     * Finds the square of the distance between this point and the specified
-     * point.
-     * 
-     * @param px
-     *            the x coordinate of the point.
-     * @param py
-     *            the y coordinate of the point.
-     * @return the square of the distance between this point and the specified
-     *         point.
-     */
-    public double distanceSq(double px, double py) {
-        return Point2D.distanceSq(getX(), getY(), px, py);
-    }
-
-    /**
-     * Finds the square of the distance between this point and the specified
-     * point.
-     * 
-     * @param p
-     *            the other point.
-     * @return the square of the distance between this point and the specified
-     *         point.
-     */
-    public double distanceSq(Point2D p) {
-        return Point2D.distanceSq(getX(), getY(), p.getX(), p.getY());
-    }
-
-    /**
-     * Finds the distance between the two specified points.
-     * 
-     * @param x1
-     *            the x coordinate of the first point.
-     * @param y1
-     *            the y coordinate of the first point.
-     * @param x2
-     *            the x coordinate of the second point.
-     * @param y2
-     *            the y coordinate of the second point.
-     * @return the distance between the two specified points.
-     */
-    public static double distance(double x1, double y1, double x2, double y2) {
-        return Math.sqrt(distanceSq(x1, y1, x2, y2));
-    }
-
-    /**
-     * Finds the distance between this point and the specified point.
-     * 
-     * @param px
-     *            the x coordinate of the point.
-     * @param py
-     *            the y coordinate of the point.
-     * @return the distance between this point and the specified point.
-     */
-    public double distance(double px, double py) {
-        return Math.sqrt(distanceSq(px, py));
-    }
-
-    /**
-     * Finds the distance between this point and the specified point.
-     * 
-     * @param p
-     *            the other point.
-     * @return the distance between this point and the specified point.
-     */
-    public double distance(Point2D p) {
-        return Math.sqrt(distanceSq(p));
-    }
-
-    @Override
-    public Object clone() {
-        try {
-            return super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new InternalError();
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        HashCode hash = new HashCode();
-        hash.append(getX());
-        hash.append(getY());
-        return hash.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (obj instanceof Point2D) {
-            Point2D p = (Point2D)obj;
-            return getX() == p.getX() && getY() == p.getY();
-        }
-        return false;
-    }
-}
diff --git a/awt/java/awt/geom/QuadCurve2D.java b/awt/java/awt/geom/QuadCurve2D.java
deleted file mode 100644
index 7a86a48..0000000
--- a/awt/java/awt/geom/QuadCurve2D.java
+++ /dev/null
@@ -1,918 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.gl.Crossing;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class QuadCurve2D is a Shape that represents a segment of a quadratic
- * (Bezier) curve. The curved segment is determined by three points: a start
- * point, an end point, and a control point. The line from the control point to
- * the starting point gives the tangent to the curve at the starting point, and
- * the line from the control point to the end point gives the tangent to the
- * curve at the end point.
- * 
- * @since Android 1.0
- */
-public abstract class QuadCurve2D implements Shape, Cloneable {
-
-    /**
-     * The Class Float is the subclass of QuadCurve2D that has all of its data
-     * values stored with float-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Float extends QuadCurve2D {
-
-        /**
-         * The x coordinate of the starting point of the curved segment.
-         */
-        public float x1;
-
-        /**
-         * The y coordinate of the starting point of the curved segment.
-         */
-        public float y1;
-
-        /**
-         * The x coordinate of the control point.
-         */
-        public float ctrlx;
-
-        /**
-         * The y coordinate of the control point.
-         */
-        public float ctrly;
-
-        /**
-         * The x coordinate of the end point of the curved segment.
-         */
-        public float x2;
-
-        /**
-         * The y coordinate of the end point of the curved segment.
-         */
-        public float y2;
-
-        /**
-         * Instantiates a new float-valued QuadCurve2D with all coordinate
-         * values set to zero.
-         */
-        public Float() {
-        }
-
-        /**
-         * Instantiates a new float-valued QuadCurve2D with the specified
-         * coordinate values.
-         * 
-         * @param x1
-         *            the x coordinate of the starting point of the curved
-         *            segment.
-         * @param y1
-         *            the y coordinate of the starting point of the curved
-         *            segment.
-         * @param ctrlx
-         *            the x coordinate of the control point.
-         * @param ctrly
-         *            the y coordinate of the control point.
-         * @param x2
-         *            the x coordinate of the end point of the curved segment.
-         * @param y2
-         *            the y coordinate of the end point of the curved segment.
-         */
-        public Float(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
-            setCurve(x1, y1, ctrlx, ctrly, x2, y2);
-        }
-
-        @Override
-        public double getX1() {
-            return x1;
-        }
-
-        @Override
-        public double getY1() {
-            return y1;
-        }
-
-        @Override
-        public double getCtrlX() {
-            return ctrlx;
-        }
-
-        @Override
-        public double getCtrlY() {
-            return ctrly;
-        }
-
-        @Override
-        public double getX2() {
-            return x2;
-        }
-
-        @Override
-        public double getY2() {
-            return y2;
-        }
-
-        @Override
-        public Point2D getP1() {
-            return new Point2D.Float(x1, y1);
-        }
-
-        @Override
-        public Point2D getCtrlPt() {
-            return new Point2D.Float(ctrlx, ctrly);
-        }
-
-        @Override
-        public Point2D getP2() {
-            return new Point2D.Float(x2, y2);
-        }
-
-        @Override
-        public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
-            this.x1 = (float)x1;
-            this.y1 = (float)y1;
-            this.ctrlx = (float)ctrlx;
-            this.ctrly = (float)ctrly;
-            this.x2 = (float)x2;
-            this.y2 = (float)y2;
-        }
-
-        /**
-         * Sets the data values of the curve.
-         * 
-         * @param x1
-         *            the x coordinate of the starting point of the curved
-         *            segment.
-         * @param y1
-         *            the y coordinate of the starting point of the curved
-         *            segment.
-         * @param ctrlx
-         *            the x coordinate of the control point.
-         * @param ctrly
-         *            the y coordinate of the control point.
-         * @param x2
-         *            the x coordinate of the end point of the curved segment.
-         * @param y2
-         *            the y coordinate of the end point of the curved segment.
-         */
-        public void setCurve(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
-            this.x1 = x1;
-            this.y1 = y1;
-            this.ctrlx = ctrlx;
-            this.ctrly = ctrly;
-            this.x2 = x2;
-            this.y2 = y2;
-        }
-
-        public Rectangle2D getBounds2D() {
-            float rx0 = Math.min(Math.min(x1, x2), ctrlx);
-            float ry0 = Math.min(Math.min(y1, y2), ctrly);
-            float rx1 = Math.max(Math.max(x1, x2), ctrlx);
-            float ry1 = Math.max(Math.max(y1, y2), ctrly);
-            return new Rectangle2D.Float(rx0, ry0, rx1 - rx0, ry1 - ry0);
-        }
-    }
-
-    /**
-     * The Class Double is the subclass of QuadCurve2D that has all of its data
-     * values stored with double-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Double extends QuadCurve2D {
-
-        /**
-         * The x coordinate of the starting point of the curved segment.
-         */
-        public double x1;
-
-        /**
-         * The y coordinate of the starting point of the curved segment.
-         */
-        public double y1;
-
-        /**
-         * The x coordinate of the control point.
-         */
-        public double ctrlx;
-
-        /**
-         * The y coordinate of the control point.
-         */
-        public double ctrly;
-
-        /**
-         * The x coordinate of the end point of the curved segment.
-         */
-        public double x2;
-
-        /**
-         * The y coordinate of the end point of the curved segment.
-         */
-        public double y2;
-
-        /**
-         * Instantiates a new double-valued QuadCurve2D with all coordinate
-         * values set to zero.
-         */
-        public Double() {
-        }
-
-        /**
-         * Instantiates a new double-valued QuadCurve2D with the specified
-         * coordinate values.
-         * 
-         * @param x1
-         *            the x coordinate of the starting point of the curved
-         *            segment.
-         * @param y1
-         *            the y coordinate of the starting point of the curved
-         *            segment.
-         * @param ctrlx
-         *            the x coordinate of the control point.
-         * @param ctrly
-         *            the y coordinate of the control point.
-         * @param x2
-         *            the x coordinate of the end point of the curved segment.
-         * @param y2
-         *            the y coordinate of the end point of the curved segment.
-         */
-        public Double(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
-            setCurve(x1, y1, ctrlx, ctrly, x2, y2);
-        }
-
-        @Override
-        public double getX1() {
-            return x1;
-        }
-
-        @Override
-        public double getY1() {
-            return y1;
-        }
-
-        @Override
-        public double getCtrlX() {
-            return ctrlx;
-        }
-
-        @Override
-        public double getCtrlY() {
-            return ctrly;
-        }
-
-        @Override
-        public double getX2() {
-            return x2;
-        }
-
-        @Override
-        public double getY2() {
-            return y2;
-        }
-
-        @Override
-        public Point2D getP1() {
-            return new Point2D.Double(x1, y1);
-        }
-
-        @Override
-        public Point2D getCtrlPt() {
-            return new Point2D.Double(ctrlx, ctrly);
-        }
-
-        @Override
-        public Point2D getP2() {
-            return new Point2D.Double(x2, y2);
-        }
-
-        @Override
-        public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
-            this.x1 = x1;
-            this.y1 = y1;
-            this.ctrlx = ctrlx;
-            this.ctrly = ctrly;
-            this.x2 = x2;
-            this.y2 = y2;
-        }
-
-        public Rectangle2D getBounds2D() {
-            double rx0 = Math.min(Math.min(x1, x2), ctrlx);
-            double ry0 = Math.min(Math.min(y1, y2), ctrly);
-            double rx1 = Math.max(Math.max(x1, x2), ctrlx);
-            double ry1 = Math.max(Math.max(y1, y2), ctrly);
-            return new Rectangle2D.Double(rx0, ry0, rx1 - rx0, ry1 - ry0);
-        }
-    }
-
-    /*
-     * QuadCurve2D path iterator
-     */
-    /**
-     * The PathIterator for a Quad2D curve.
-     */
-    class Iterator implements PathIterator {
-
-        /**
-         * The source QuadCurve2D object.
-         */
-        QuadCurve2D c;
-
-        /**
-         * The path iterator transformation.
-         */
-        AffineTransform t;
-
-        /**
-         * The current segment index.
-         */
-        int index;
-
-        /**
-         * Constructs a new QuadCurve2D.Iterator for given curve and
-         * transformation
-         * 
-         * @param q
-         *            the source QuadCurve2D object.
-         * @param t
-         *            the AffineTransform that acts on the coordinates before
-         *            returning them (or null).
-         */
-        Iterator(QuadCurve2D q, AffineTransform t) {
-            this.c = q;
-            this.t = t;
-        }
-
-        public int getWindingRule() {
-            return WIND_NON_ZERO;
-        }
-
-        public boolean isDone() {
-            return (index > 1);
-        }
-
-        public void next() {
-            index++;
-        }
-
-        public int currentSegment(double[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type;
-            int count;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                coords[0] = c.getX1();
-                coords[1] = c.getY1();
-                count = 1;
-            } else {
-                type = SEG_QUADTO;
-                coords[0] = c.getCtrlX();
-                coords[1] = c.getCtrlY();
-                coords[2] = c.getX2();
-                coords[3] = c.getY2();
-                count = 2;
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, count);
-            }
-            return type;
-        }
-
-        public int currentSegment(float[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type;
-            int count;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                coords[0] = (float)c.getX1();
-                coords[1] = (float)c.getY1();
-                count = 1;
-            } else {
-                type = SEG_QUADTO;
-                coords[0] = (float)c.getCtrlX();
-                coords[1] = (float)c.getCtrlY();
-                coords[2] = (float)c.getX2();
-                coords[3] = (float)c.getY2();
-                count = 2;
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, count);
-            }
-            return type;
-        }
-
-    }
-
-    /**
-     * Instantiates a new quadratic curve.
-     */
-    protected QuadCurve2D() {
-    }
-
-    /**
-     * Gets the x coordinate of the starting point.
-     * 
-     * @return the x coordinate of the starting point.
-     */
-    public abstract double getX1();
-
-    /**
-     * Gets the y coordinate of the starting point.
-     * 
-     * @return the y coordinate of the starting point.
-     */
-    public abstract double getY1();
-
-    /**
-     * Gets the starting point.
-     * 
-     * @return the starting point.
-     */
-    public abstract Point2D getP1();
-
-    /**
-     * Gets the x coordinate of the control point.
-     * 
-     * @return the x coordinate of the control point.
-     */
-    public abstract double getCtrlX();
-
-    /**
-     * Gets the y coordinate of the control point.
-     * 
-     * @return y coordinate of the control point.
-     */
-    public abstract double getCtrlY();
-
-    /**
-     * Gets the control point.
-     * 
-     * @return the control point.
-     */
-    public abstract Point2D getCtrlPt();
-
-    /**
-     * Gets the x coordinate of the end point.
-     * 
-     * @return the x coordinate of the end point.
-     */
-    public abstract double getX2();
-
-    /**
-     * Gets the y coordinate of the end point.
-     * 
-     * @return the y coordinate of the end point.
-     */
-    public abstract double getY2();
-
-    /**
-     * Gets the end point.
-     * 
-     * @return the end point.
-     */
-    public abstract Point2D getP2();
-
-    /**
-     * Sets the data of the curve.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point of the curved segment.
-     * @param y1
-     *            the y coordinate of the starting point of the curved segment.
-     * @param ctrlx
-     *            the x coordinate of the control point.
-     * @param ctrly
-     *            the y coordinate of the control point.
-     * @param x2
-     *            the x coordinate of the end point of the curved segment.
-     * @param y2
-     *            the y coordinate of the end point of the curved segment.
-     */
-    public abstract void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2,
-            double y2);
-
-    /**
-     * Sets the data of the curve.
-     * 
-     * @param p1
-     *            the starting point of the curved segment.
-     * @param cp
-     *            the control point.
-     * @param p2
-     *            the end point of the curved segment.
-     * @throws NullPointerException
-     *             if any of the three points is null.
-     */
-    public void setCurve(Point2D p1, Point2D cp, Point2D p2) {
-        setCurve(p1.getX(), p1.getY(), cp.getX(), cp.getY(), p2.getX(), p2.getY());
-    }
-
-    /**
-     * Sets the data of the curve by reading the data from an array of values.
-     * The values are read in the same order as the arguments of the method
-     * {@link QuadCurve2D#setCurve(double, double, double, double, double, double)}
-     * .
-     * 
-     * @param coords
-     *            the array of values containing the new coordinates.
-     * @param offset
-     *            the offset of the data to read within the array.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {@code coords.length} < offset + 6.
-     * @throws NullPointerException
-     *             if the coordinate array is null.
-     */
-    public void setCurve(double[] coords, int offset) {
-        setCurve(coords[offset + 0], coords[offset + 1], coords[offset + 2], coords[offset + 3],
-                coords[offset + 4], coords[offset + 5]);
-    }
-
-    /**
-     * Sets the data of the curve by reading the data from an array of points.
-     * The values are read in the same order as the arguments of the method
-     * {@link QuadCurve2D#setCurve(Point2D, Point2D, Point2D)}.
-     * 
-     * @param points
-     *            the array of points containing the new coordinates.
-     * @param offset
-     *            the offset of the data to read within the array.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if points.length < offset + 3.
-     * @throws NullPointerException
-     *             if the point array is null.
-     */
-    public void setCurve(Point2D[] points, int offset) {
-        setCurve(points[offset + 0].getX(), points[offset + 0].getY(), points[offset + 1].getX(),
-                points[offset + 1].getY(), points[offset + 2].getX(), points[offset + 2].getY());
-    }
-
-    /**
-     * Sets the data of the curve by copying it from another QuadCurve2D.
-     * 
-     * @param curve
-     *            the curve to copy the data points from.
-     * @throws NullPointerException
-     *             if the curve is null.
-     */
-    public void setCurve(QuadCurve2D curve) {
-        setCurve(curve.getX1(), curve.getY1(), curve.getCtrlX(), curve.getCtrlY(), curve.getX2(),
-                curve.getY2());
-    }
-
-    /**
-     * Gets the square of the distance from the control point to the straight
-     * line segment connecting the start point and the end point for this curve.
-     * 
-     * @return the square of the distance from the control point to the straight
-     *         line segment connecting the start point and the end point.
-     */
-    public double getFlatnessSq() {
-        return Line2D.ptSegDistSq(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY());
-    }
-
-    /**
-     * Gets the square of the distance from the control point to the straight
-     * line segment connecting the start point and the end point.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point of the curved segment.
-     * @param y1
-     *            the y coordinate of the starting point of the curved segment.
-     * @param ctrlx
-     *            the x coordinate of the control point.
-     * @param ctrly
-     *            the y coordinate of the control point.
-     * @param x2
-     *            the x coordinate of the end point of the curved segment.
-     * @param y2
-     *            the y coordinate of the end point of the curved segment.
-     * @return the square of the distance from the control point to the straight
-     *         line segment connecting the start point and the end point.
-     */
-    public static double getFlatnessSq(double x1, double y1, double ctrlx, double ctrly, double x2,
-            double y2) {
-        return Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx, ctrly);
-    }
-
-    /**
-     * Gets the square of the distance from the control point to the straight
-     * line segment connecting the start point and the end point by reading the
-     * coordinates of the points from an array of values. The values are read in
-     * the same order as the arguments of the method
-     * {@link QuadCurve2D#getFlatnessSq(double, double, double, double, double, double)}
-     * .
-     * 
-     * @param coords
-     *            the array of points containing the coordinates to use for the
-     *            calculation
-     * @param offset
-     *            the offset of the data to read within the array
-     * @return the square of the distance from the control point to the straight
-     *         line segment connecting the start point and the end point.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {@code coords.length} < offset + 6.
-     * @throws NullPointerException
-     *             if the coordinate array is null.
-     */
-    public static double getFlatnessSq(double coords[], int offset) {
-        return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1], coords[offset + 4],
-                coords[offset + 5], coords[offset + 2], coords[offset + 3]);
-    }
-
-    /**
-     * Gets the distance from the control point to the straight line segment
-     * connecting the start point and the end point of this QuadCurve2D.
-     * 
-     * @return the the distance from the control point to the straight line
-     *         segment connecting the start point and the end point of this
-     *         QuadCurve2D.
-     */
-    public double getFlatness() {
-        return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY());
-    }
-
-    /**
-     * Gets the distance from the control point to the straight line segment
-     * connecting the start point and the end point.
-     * 
-     * @param x1
-     *            the x coordinate of the starting point of the curved segment.
-     * @param y1
-     *            the y coordinate of the starting point of the curved segment.
-     * @param ctrlx
-     *            the x coordinate of the control point.
-     * @param ctrly
-     *            the y coordinate of the control point.
-     * @param x2
-     *            the x coordinate of the end point of the curved segment.
-     * @param y2
-     *            the y coordinate of the end point of the curved segment.
-     * @return the the distance from the control point to the straight line
-     *         segment connecting the start point and the end point.
-     */
-    public static double getFlatness(double x1, double y1, double ctrlx, double ctrly, double x2,
-            double y2) {
-        return Line2D.ptSegDist(x1, y1, x2, y2, ctrlx, ctrly);
-    }
-
-    /**
-     * Gets the the distance from the control point to the straight line segment
-     * connecting the start point and the end point. The values are read in the
-     * same order as the arguments of the method
-     * {@link QuadCurve2D#getFlatness(double, double, double, double, double, double)}
-     * .
-     * 
-     * @param coords
-     *            the array of points containing the coordinates to use for the
-     *            calculation.
-     * @param offset
-     *            the offset of the data to read within the array.
-     * @return the the distance from the control point to the straight line
-     *         segment connecting the start point and the end point.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {code coords.length} < offset + 6.
-     * @throws NullPointerException
-     *             if the coordinate array is null.
-     */
-    public static double getFlatness(double coords[], int offset) {
-        return Line2D.ptSegDist(coords[offset + 0], coords[offset + 1], coords[offset + 4],
-                coords[offset + 5], coords[offset + 2], coords[offset + 3]);
-    }
-
-    /**
-     * Creates the data for two quadratic curves by dividing this curve in two.
-     * The division point is the point on the curve that is closest to this
-     * curve's control point. The data of this curve is left unchanged.
-     * 
-     * @param left
-     *            the QuadCurve2D where the left (start) segment's data is
-     *            written.
-     * @param right
-     *            the QuadCurve2D where the right (end) segment's data is
-     *            written.
-     * @throws NullPointerException
-     *             if either curve is null.
-     */
-    public void subdivide(QuadCurve2D left, QuadCurve2D right) {
-        subdivide(this, left, right);
-    }
-
-    /**
-     * Creates the data for two quadratic curves by dividing a source curve in
-     * two. The division point is the point on the curve that is closest to the
-     * source curve's control point. The data of the source curve is left
-     * unchanged.
-     * 
-     * @param src
-     *            the curve that provides the initial data.
-     * @param left
-     *            the QuadCurve2D where the left (start) segment's data is
-     *            written.
-     * @param right
-     *            the QuadCurve2D where the right (end) segment's data is
-     *            written.
-     * @throws NullPointerException
-     *             if one of the curves is null.
-     */
-    public static void subdivide(QuadCurve2D src, QuadCurve2D left, QuadCurve2D right) {
-        double x1 = src.getX1();
-        double y1 = src.getY1();
-        double cx = src.getCtrlX();
-        double cy = src.getCtrlY();
-        double x2 = src.getX2();
-        double y2 = src.getY2();
-        double cx1 = (x1 + cx) / 2.0;
-        double cy1 = (y1 + cy) / 2.0;
-        double cx2 = (x2 + cx) / 2.0;
-        double cy2 = (y2 + cy) / 2.0;
-        cx = (cx1 + cx2) / 2.0;
-        cy = (cy1 + cy2) / 2.0;
-        if (left != null) {
-            left.setCurve(x1, y1, cx1, cy1, cx, cy);
-        }
-        if (right != null) {
-            right.setCurve(cx, cy, cx2, cy2, x2, y2);
-        }
-    }
-
-    /**
-     * Creates the data for two quadratic curves by dividing a source curve in
-     * two. The division point is the point on the curve that is closest to the
-     * source curve's control point. The data for the three curves is read and
-     * written from arrays of values in the usual order: x1, y1, cx, cy, x2, y2.
-     * 
-     * @param src
-     *            the array that gives the data values for the source curve.
-     * @param srcoff
-     *            the offset in the src array to read the values from.
-     * @param left
-     *            the array where the coordinates of the start curve should be
-     *            written.
-     * @param leftOff
-     *            the offset in the left array to start writing the values.
-     * @param right
-     *            the array where the coordinates of the end curve should be
-     *            written.
-     * @param rightOff
-     *            the offset in the right array to start writing the values.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {@code src.length} < srcoff + 6 or if {@code left.length}
-     *             < leftOff + 6 or if {@code right.length} < rightOff + 6.
-     * @throws NullPointerException
-     *             if one of the arrays is null.
-     */
-    public static void subdivide(double src[], int srcoff, double left[], int leftOff,
-            double right[], int rightOff) {
-        double x1 = src[srcoff + 0];
-        double y1 = src[srcoff + 1];
-        double cx = src[srcoff + 2];
-        double cy = src[srcoff + 3];
-        double x2 = src[srcoff + 4];
-        double y2 = src[srcoff + 5];
-        double cx1 = (x1 + cx) / 2.0;
-        double cy1 = (y1 + cy) / 2.0;
-        double cx2 = (x2 + cx) / 2.0;
-        double cy2 = (y2 + cy) / 2.0;
-        cx = (cx1 + cx2) / 2.0;
-        cy = (cy1 + cy2) / 2.0;
-        if (left != null) {
-            left[leftOff + 0] = x1;
-            left[leftOff + 1] = y1;
-            left[leftOff + 2] = cx1;
-            left[leftOff + 3] = cy1;
-            left[leftOff + 4] = cx;
-            left[leftOff + 5] = cy;
-        }
-        if (right != null) {
-            right[rightOff + 0] = cx;
-            right[rightOff + 1] = cy;
-            right[rightOff + 2] = cx2;
-            right[rightOff + 3] = cy2;
-            right[rightOff + 4] = x2;
-            right[rightOff + 5] = y2;
-        }
-    }
-
-    /**
-     * Finds the roots of the quadratic polynomial. This is accomplished by
-     * finding the (real) values of x that solve the following equation:
-     * eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written back into
-     * the array eqn starting from the index 0 in the array. The return value
-     * tells how many array elements have been changed by this method call.
-     * 
-     * @param eqn
-     *            an array containing the coefficients of the quadratic
-     *            polynomial to solve.
-     * @return the number of roots of the quadratic polynomial.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {@code eqn.length} < 3.
-     * @throws NullPointerException
-     *             if the array is null.
-     */
-    public static int solveQuadratic(double eqn[]) {
-        return solveQuadratic(eqn, eqn);
-    }
-
-    /**
-     * Finds the roots of the quadratic polynomial. This is accomplished by
-     * finding the (real) values of x that solve the following equation:
-     * eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written into the
-     * array res starting from the index 0 in the array. The return value tells
-     * how many array elements have been written by this method call.
-     * 
-     * @param eqn
-     *            an array containing the coefficients of the quadratic
-     *            polynomial to solve.
-     * @param res
-     *            the array that this method writes the results into.
-     * @return the number of roots of the quadratic polynomial.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {@code eqn.length} < 3 or if {@code res.length} is less
-     *             than the number of roots.
-     * @throws NullPointerException
-     *             if either array is null.
-     */
-    public static int solveQuadratic(double eqn[], double res[]) {
-        return Crossing.solveQuad(eqn, res);
-    }
-
-    public boolean contains(double px, double py) {
-        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
-    }
-
-    public boolean contains(double rx, double ry, double rw, double rh) {
-        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
-        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
-    }
-
-    public boolean intersects(double rx, double ry, double rw, double rh) {
-        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
-        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
-    }
-
-    public boolean contains(Point2D p) {
-        return contains(p.getX(), p.getY());
-    }
-
-    public boolean intersects(Rectangle2D r) {
-        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
-    }
-
-    public boolean contains(Rectangle2D r) {
-        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
-    }
-
-    public Rectangle getBounds() {
-        return getBounds2D().getBounds();
-    }
-
-    public PathIterator getPathIterator(AffineTransform t) {
-        return new Iterator(this, t);
-    }
-
-    public PathIterator getPathIterator(AffineTransform t, double flatness) {
-        return new FlatteningPathIterator(getPathIterator(t), flatness);
-    }
-
-    @Override
-    public Object clone() {
-        try {
-            return super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new InternalError();
-        }
-    }
-
-}
diff --git a/awt/java/awt/geom/Rectangle2D.java b/awt/java/awt/geom/Rectangle2D.java
deleted file mode 100644
index 8166134..0000000
--- a/awt/java/awt/geom/Rectangle2D.java
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.misc.HashCode;
-
-/**
- * The Class Rectangle2D represents a rectangle whose coordinates are given with
- * the correct precision to be used with the Graphics2D classes.
- * 
- * @since Android 1.0
- */
-public abstract class Rectangle2D extends RectangularShape {
-
-    /**
-     * The Constant OUT_LEFT is a mask that is used to indicate that a given
-     * point is outside the rectangle and to its left.
-     */
-    public static final int OUT_LEFT = 1;
-
-    /**
-     * The Constant OUT_TOP is a mask that is used to indicate that a given
-     * point is outside the rectangle and above it.
-     */
-    public static final int OUT_TOP = 2;
-
-    /**
-     * The Constant OUT_RIGHT is a mask that is used to indicate that a given
-     * point is outside the rectangle and to its right.
-     */
-    public static final int OUT_RIGHT = 4;
-
-    /**
-     * The Constant OUT_BOTTOM is a mask that is used to indicate that a given
-     * point is outside the rectangle and above it.
-     */
-    public static final int OUT_BOTTOM = 8;
-
-    /**
-     * The Class Float is the subclass of Rectangle2D that represents a
-     * rectangle whose data values are given as floats (with float-level
-     * precision).
-     * 
-     * @since Android 1.0
-     */
-    public static class Float extends Rectangle2D {
-
-        /**
-         * The x coordinate of the rectangle's upper left corner.
-         */
-        public float x;
-
-        /**
-         * The y coordinate of the rectangle's upper left corner.
-         */
-        public float y;
-
-        /**
-         * The width of the rectangle.
-         */
-        public float width;
-
-        /**
-         * The height of the rectangle.
-         */
-        public float height;
-
-        /**
-         * Instantiates a new empty rectangle with float-precision data fields.
-         */
-        public Float() {
-        }
-
-        /**
-         * Instantiates a new rectangle with the specified float-precision data.
-         * 
-         * @param x
-         *            the x coordinate of the rectangle's upper left corner.
-         * @param y
-         *            the y coordinate of the rectangle's upper left corner.
-         * @param width
-         *            the width of the rectangle.
-         * @param height
-         *            the height of the rectangle.
-         */
-        public Float(float x, float y, float width, float height) {
-            setRect(x, y, width, height);
-        }
-
-        @Override
-        public double getX() {
-            return x;
-        }
-
-        @Override
-        public double getY() {
-            return y;
-        }
-
-        @Override
-        public double getWidth() {
-            return width;
-        }
-
-        @Override
-        public double getHeight() {
-            return height;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return width <= 0.0f || height <= 0.0f;
-        }
-
-        /**
-         * Sets the rectangle's data to the given values.
-         * 
-         * @param x
-         *            the x coordinate of the rectangle's upper left corner.
-         * @param y
-         *            the y coordinate of the rectangle's upper left corner.
-         * @param width
-         *            the width of the rectangle.
-         * @param height
-         *            the height of the rectangle.
-         */
-        public void setRect(float x, float y, float width, float height) {
-            this.x = x;
-            this.y = y;
-            this.width = width;
-            this.height = height;
-        }
-
-        @Override
-        public void setRect(double x, double y, double width, double height) {
-            this.x = (float)x;
-            this.y = (float)y;
-            this.width = (float)width;
-            this.height = (float)height;
-        }
-
-        @Override
-        public void setRect(Rectangle2D r) {
-            this.x = (float)r.getX();
-            this.y = (float)r.getY();
-            this.width = (float)r.getWidth();
-            this.height = (float)r.getHeight();
-        }
-
-        @Override
-        public int outcode(double px, double py) {
-            int code = 0;
-
-            if (width <= 0.0f) {
-                code |= OUT_LEFT | OUT_RIGHT;
-            } else if (px < x) {
-                code |= OUT_LEFT;
-            } else if (px > x + width) {
-                code |= OUT_RIGHT;
-            }
-
-            if (height <= 0.0f) {
-                code |= OUT_TOP | OUT_BOTTOM;
-            } else if (py < y) {
-                code |= OUT_TOP;
-            } else if (py > y + height) {
-                code |= OUT_BOTTOM;
-            }
-
-            return code;
-        }
-
-        @Override
-        public Rectangle2D getBounds2D() {
-            return new Float(x, y, width, height);
-        }
-
-        @Override
-        public Rectangle2D createIntersection(Rectangle2D r) {
-            Rectangle2D dst;
-            if (r instanceof Double) {
-                dst = new Rectangle2D.Double();
-            } else {
-                dst = new Rectangle2D.Float();
-            }
-            Rectangle2D.intersect(this, r, dst);
-            return dst;
-        }
-
-        @Override
-        public Rectangle2D createUnion(Rectangle2D r) {
-            Rectangle2D dst;
-            if (r instanceof Double) {
-                dst = new Rectangle2D.Double();
-            } else {
-                dst = new Rectangle2D.Float();
-            }
-            Rectangle2D.union(this, r, dst);
-            return dst;
-        }
-
-        @Override
-        public String toString() {
-            // The output format based on 1.5 release behaviour. It could be
-            // obtained in the following way
-            // System.out.println(new Rectangle2D.Float().toString())
-            return getClass().getName()
-                    + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-        }
-    }
-
-    /**
-     * The Class Double is the subclass of Rectangle2D that represents a
-     * rectangle whose data values are given as doubles (with
-     * double-precision-level precision).
-     * 
-     * @since Android 1.0
-     */
-    public static class Double extends Rectangle2D {
-
-        /**
-         * The x coordinate of the rectangle's upper left corner.
-         */
-        public double x;
-
-        /**
-         * The y coordinate of the rectangle's upper left corner.
-         */
-        public double y;
-
-        /**
-         * The width of the rectangle.
-         */
-        public double width;
-
-        /**
-         * The height of the rectangle.
-         */
-        public double height;
-
-        /**
-         * Instantiates a new empty rectangle with double-precision data fields.
-         */
-        public Double() {
-        }
-
-        /**
-         * Instantiates a new rectangle with the given double values.
-         * 
-         * @param x
-         *            the x coordinate of the rectangle's upper left corner.
-         * @param y
-         *            the y coordinate of the rectangle's upper left corner.
-         * @param width
-         *            the width of the rectangle.
-         * @param height
-         *            the height of the rectangle.
-         */
-        public Double(double x, double y, double width, double height) {
-            setRect(x, y, width, height);
-        }
-
-        @Override
-        public double getX() {
-            return x;
-        }
-
-        @Override
-        public double getY() {
-            return y;
-        }
-
-        @Override
-        public double getWidth() {
-            return width;
-        }
-
-        @Override
-        public double getHeight() {
-            return height;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return width <= 0.0 || height <= 0.0;
-        }
-
-        @Override
-        public void setRect(double x, double y, double width, double height) {
-            this.x = x;
-            this.y = y;
-            this.width = width;
-            this.height = height;
-        }
-
-        @Override
-        public void setRect(Rectangle2D r) {
-            this.x = r.getX();
-            this.y = r.getY();
-            this.width = r.getWidth();
-            this.height = r.getHeight();
-        }
-
-        @Override
-        public int outcode(double px, double py) {
-            int code = 0;
-
-            if (width <= 0.0) {
-                code |= OUT_LEFT | OUT_RIGHT;
-            } else if (px < x) {
-                code |= OUT_LEFT;
-            } else if (px > x + width) {
-                code |= OUT_RIGHT;
-            }
-
-            if (height <= 0.0) {
-                code |= OUT_TOP | OUT_BOTTOM;
-            } else if (py < y) {
-                code |= OUT_TOP;
-            } else if (py > y + height) {
-                code |= OUT_BOTTOM;
-            }
-
-            return code;
-        }
-
-        @Override
-        public Rectangle2D getBounds2D() {
-            return new Double(x, y, width, height);
-        }
-
-        @Override
-        public Rectangle2D createIntersection(Rectangle2D r) {
-            Rectangle2D dst = new Rectangle2D.Double();
-            Rectangle2D.intersect(this, r, dst);
-            return dst;
-        }
-
-        @Override
-        public Rectangle2D createUnion(Rectangle2D r) {
-            Rectangle2D dest = new Rectangle2D.Double();
-            Rectangle2D.union(this, r, dest);
-            return dest;
-        }
-
-        @Override
-        public String toString() {
-            // The output format based on 1.5 release behaviour. It could be
-            // obtained in the following way
-            // System.out.println(new Rectangle2D.Double().toString())
-            return getClass().getName()
-                    + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-        }
-    }
-
-    /**
-     * The Class Iterator provides access to the coordinates of the
-     * Rectangle2D's boundary modified by an AffineTransform.
-     */
-    class Iterator implements PathIterator {
-
-        /**
-         * The x coordinate of the rectangle's upper left corner.
-         */
-        double x;
-
-        /**
-         * The y coordinate of the rectangle's upper left corner.
-         */
-        double y;
-
-        /**
-         * The width of the rectangle.
-         */
-        double width;
-
-        /**
-         * The height of the rectangle.
-         */
-        double height;
-
-        /**
-         * The AffineTransform that is used to modify the coordinates that are
-         * returned by the path iterator.
-         */
-        AffineTransform t;
-
-        /**
-         * The current segment index.
-         */
-        int index;
-
-        /**
-         * Constructs a new Rectangle2D.Iterator for given rectangle and
-         * transformation.
-         * 
-         * @param r
-         *            the source Rectangle2D object.
-         * @param at
-         *            the AffineTransform object to apply to the coordinates
-         *            before returning them.
-         */
-        Iterator(Rectangle2D r, AffineTransform at) {
-            this.x = r.getX();
-            this.y = r.getY();
-            this.width = r.getWidth();
-            this.height = r.getHeight();
-            this.t = at;
-            if (width < 0.0 || height < 0.0) {
-                index = 6;
-            }
-        }
-
-        public int getWindingRule() {
-            return WIND_NON_ZERO;
-        }
-
-        public boolean isDone() {
-            return index > 5;
-        }
-
-        public void next() {
-            index++;
-        }
-
-        public int currentSegment(double[] coords) {
-            if (isDone()) {
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            if (index == 5) {
-                return SEG_CLOSE;
-            }
-            int type;
-            if (index == 0) {
-                type = SEG_MOVETO;
-                coords[0] = x;
-                coords[1] = y;
-            } else {
-                type = SEG_LINETO;
-                switch (index) {
-                    case 1:
-                        coords[0] = x + width;
-                        coords[1] = y;
-                        break;
-                    case 2:
-                        coords[0] = x + width;
-                        coords[1] = y + height;
-                        break;
-                    case 3:
-                        coords[0] = x;
-                        coords[1] = y + height;
-                        break;
-                    case 4:
-                        coords[0] = x;
-                        coords[1] = y;
-                        break;
-                }
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, 1);
-            }
-            return type;
-        }
-
-        public int currentSegment(float[] coords) {
-            if (isDone()) {
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            if (index == 5) {
-                return SEG_CLOSE;
-            }
-            int type;
-            if (index == 0) {
-                coords[0] = (float)x;
-                coords[1] = (float)y;
-                type = SEG_MOVETO;
-            } else {
-                type = SEG_LINETO;
-                switch (index) {
-                    case 1:
-                        coords[0] = (float)(x + width);
-                        coords[1] = (float)y;
-                        break;
-                    case 2:
-                        coords[0] = (float)(x + width);
-                        coords[1] = (float)(y + height);
-                        break;
-                    case 3:
-                        coords[0] = (float)x;
-                        coords[1] = (float)(y + height);
-                        break;
-                    case 4:
-                        coords[0] = (float)x;
-                        coords[1] = (float)y;
-                        break;
-                }
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, 1);
-            }
-            return type;
-        }
-
-    }
-
-    /**
-     * Instantiates a new Rectangle2D.
-     */
-    protected Rectangle2D() {
-    }
-
-    /**
-     * Sets the rectangle's location and dimension.
-     * 
-     * @param x
-     *            the x coordinate of the rectangle's upper left corner.
-     * @param y
-     *            the y coordinate of the rectangle's upper left corner.
-     * @param width
-     *            the width of the rectangle.
-     * @param height
-     *            the height of the rectangle.
-     */
-    public abstract void setRect(double x, double y, double width, double height);
-
-    /**
-     * Gets the location of the point with respect to the rectangle and packs
-     * the information into a single integer using the bitmasks
-     * {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT},
-     * {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}. If the
-     * rectangle has zero or negative width, then every point is regarded as
-     * being both to the left and to the right of the rectangle. Similarly, if
-     * the height is zero or negative then all points are considered to be both
-     * both above and below it.
-     * 
-     * @param x
-     *            the x coordinate of the point to check.
-     * @param y
-     *            the y coordinate of the point to check.
-     * @return the point's location with respect to the rectangle.
-     */
-    public abstract int outcode(double x, double y);
-
-    /**
-     * Creates an new rectangle that is the intersection of this rectangle with
-     * the given rectangle. The resulting rectangle may be empty. The data of
-     * this rectangle is left unchanged.
-     * 
-     * @param r
-     *            the rectangle to intersect with this rectangle.
-     * @return the new rectangle given by intersection.
-     */
-    public abstract Rectangle2D createIntersection(Rectangle2D r);
-
-    /**
-     * Creates an new rectangle that is the union of this rectangle with the
-     * given rectangle. The new rectangle is the smallest rectangle which
-     * contains both this rectangle and the rectangle specified as a parameter.
-     * The data of this rectangle is left unchanged.
-     * 
-     * @param r
-     *            the rectangle to combine with this rectangle.
-     * @return the new rectangle given by union.
-     */
-    public abstract Rectangle2D createUnion(Rectangle2D r);
-
-    /**
-     * Sets the data of this rectangle to match the data of the given rectangle.
-     * 
-     * @param r
-     *            the rectangle whose data is to be copied into this rectangle's
-     *            fields.
-     */
-    public void setRect(Rectangle2D r) {
-        setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
-    }
-
-    @Override
-    public void setFrame(double x, double y, double width, double height) {
-        setRect(x, y, width, height);
-    }
-
-    public Rectangle2D getBounds2D() {
-        return (Rectangle2D)clone();
-    }
-
-    /**
-     * Determines whether any part of the line segment between (and including)
-     * the two given points touches any part of the rectangle, including its
-     * boundary.
-     * 
-     * @param x1
-     *            the x coordinate of one of the points that determines the line
-     *            segment to test.
-     * @param y1
-     *            the y coordinate of one of the points that determines the line
-     *            segment to test.
-     * @param x2
-     *            the x coordinate of one of the points that determines the line
-     *            segment to test.
-     * @param y2
-     *            the y coordinate of one of the points that determines the line
-     *            segment to test.
-     * @return true, if at least one point of the line segment between the two
-     *         points matches any point of the interior of the rectangle or the
-     *         rectangle's boundary.
-     */
-    public boolean intersectsLine(double x1, double y1, double x2, double y2) {
-        double rx1 = getX();
-        double ry1 = getY();
-        double rx2 = rx1 + getWidth();
-        double ry2 = ry1 + getHeight();
-        return (rx1 <= x1 && x1 <= rx2 && ry1 <= y1 && y1 <= ry2)
-                || (rx1 <= x2 && x2 <= rx2 && ry1 <= y2 && y2 <= ry2)
-                || Line2D.linesIntersect(rx1, ry1, rx2, ry2, x1, y1, x2, y2)
-                || Line2D.linesIntersect(rx2, ry1, rx1, ry2, x1, y1, x2, y2);
-    }
-
-    /**
-     * Determines whether any part of the specified line segment touches any
-     * part of the rectangle, including its boundary.
-     * 
-     * @param l
-     *            the line segment to test.
-     * @return true, if at least one point of the given line segment matches any
-     *         point of the interior of the rectangle or the rectangle's
-     *         boundary.
-     */
-    public boolean intersectsLine(Line2D l) {
-        return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
-    }
-
-    /**
-     * Gets the location of the point with respect to the rectangle and packs
-     * the information into a single integer using the bitmasks
-     * {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT},
-     * {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}. If the
-     * rectangle has zero or negative width, then every point is regarded as
-     * being both to the left and to the right of the rectangle. Similarly, if
-     * the height is zero or negative then all points are considered to be both
-     * both above and below it.
-     * 
-     * @param p
-     *            the point to check.
-     * @return the point's location with respect to the rectangle.
-     */
-    public int outcode(Point2D p) {
-        return outcode(p.getX(), p.getY());
-    }
-
-    public boolean contains(double x, double y) {
-        if (isEmpty()) {
-            return false;
-        }
-
-        double x1 = getX();
-        double y1 = getY();
-        double x2 = x1 + getWidth();
-        double y2 = y1 + getHeight();
-
-        return x1 <= x && x < x2 && y1 <= y && y < y2;
-    }
-
-    public boolean intersects(double x, double y, double width, double height) {
-        if (isEmpty() || width <= 0.0 || height <= 0.0) {
-            return false;
-        }
-
-        double x1 = getX();
-        double y1 = getY();
-        double x2 = x1 + getWidth();
-        double y2 = y1 + getHeight();
-
-        return x + width > x1 && x < x2 && y + height > y1 && y < y2;
-    }
-
-    public boolean contains(double x, double y, double width, double height) {
-        if (isEmpty() || width <= 0.0 || height <= 0.0) {
-            return false;
-        }
-
-        double x1 = getX();
-        double y1 = getY();
-        double x2 = x1 + getWidth();
-        double y2 = y1 + getHeight();
-
-        return x1 <= x && x + width <= x2 && y1 <= y && y + height <= y2;
-    }
-
-    /**
-     * Changes the data values of the destination rectangle to match the
-     * intersection of the two source rectangles, leaving the two source
-     * rectangles unchanged. The resulting rectangle may be empty.
-     * 
-     * @param src1
-     *            one of the two source rectangles giving the data to intersect.
-     * @param src2
-     *            one of the two source rectangles giving the data to intersect.
-     * @param dst
-     *            the destination object where the data of the intersection is
-     *            written.
-     */
-    public static void intersect(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
-        double x1 = Math.max(src1.getMinX(), src2.getMinX());
-        double y1 = Math.max(src1.getMinY(), src2.getMinY());
-        double x2 = Math.min(src1.getMaxX(), src2.getMaxX());
-        double y2 = Math.min(src1.getMaxY(), src2.getMaxY());
-        dst.setFrame(x1, y1, x2 - x1, y2 - y1);
-    }
-
-    /**
-     * Changes the data values of the destination rectangle to match the union
-     * of the two source rectangles, leaving the two source rectangles
-     * unchanged. The union is the smallest rectangle that completely covers the
-     * two source rectangles.
-     * 
-     * @param src1
-     *            one of the two source rectangles giving the data.
-     * @param src2
-     *            one of the two source rectangles giving the data.
-     * @param dst
-     *            the destination object where the data of the union is written.
-     */
-    public static void union(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
-        double x1 = Math.min(src1.getMinX(), src2.getMinX());
-        double y1 = Math.min(src1.getMinY(), src2.getMinY());
-        double x2 = Math.max(src1.getMaxX(), src2.getMaxX());
-        double y2 = Math.max(src1.getMaxY(), src2.getMaxY());
-        dst.setFrame(x1, y1, x2 - x1, y2 - y1);
-    }
-
-    /**
-     * Enlarges the rectangle so that it includes the given point.
-     * 
-     * @param x
-     *            the x coordinate of the new point to be covered by the
-     *            rectangle.
-     * @param y
-     *            the y coordinate of the new point to be covered by the
-     *            rectangle.
-     */
-    public void add(double x, double y) {
-        double x1 = Math.min(getMinX(), x);
-        double y1 = Math.min(getMinY(), y);
-        double x2 = Math.max(getMaxX(), x);
-        double y2 = Math.max(getMaxY(), y);
-        setRect(x1, y1, x2 - x1, y2 - y1);
-    }
-
-    /**
-     * Enlarges the rectangle so that it includes the given point.
-     * 
-     * @param p
-     *            the new point to be covered by the rectangle.
-     */
-    public void add(Point2D p) {
-        add(p.getX(), p.getY());
-    }
-
-    /**
-     * Enlarges the rectangle so that it covers the given rectangle.
-     * 
-     * @param r
-     *            the new rectangle to be covered by this rectangle.
-     */
-    public void add(Rectangle2D r) {
-        union(this, r, this);
-    }
-
-    public PathIterator getPathIterator(AffineTransform t) {
-        return new Iterator(this, t);
-    }
-
-    @Override
-    public PathIterator getPathIterator(AffineTransform t, double flatness) {
-        return new Iterator(this, t);
-    }
-
-    @Override
-    public int hashCode() {
-        HashCode hash = new HashCode();
-        hash.append(getX());
-        hash.append(getY());
-        hash.append(getWidth());
-        hash.append(getHeight());
-        return hash.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (obj instanceof Rectangle2D) {
-            Rectangle2D r = (Rectangle2D)obj;
-            return getX() == r.getX() && getY() == r.getY() && getWidth() == r.getWidth()
-                    && getHeight() == r.getHeight();
-        }
-        return false;
-    }
-
-}
diff --git a/awt/java/awt/geom/RectangularShape.java b/awt/java/awt/geom/RectangularShape.java
deleted file mode 100644
index 0b0d05c..0000000
--- a/awt/java/awt/geom/RectangularShape.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-
-/**
- * The Class RectangularShape represents a Shape whose data is (at least
- * partially) described by a rectangular frame. This includes shapes which are
- * obviously rectangular (such as Rectangle2D) as well as shapes like Arc2D
- * which are largely determined by the rectangle they fit inside.
- * 
- * @since Android 1.0
- */
-public abstract class RectangularShape implements Shape, Cloneable {
-
-    /**
-     * Instantiates a new rectangular shape.
-     */
-    protected RectangularShape() {
-    }
-
-    /**
-     * Gets the x coordinate of the upper left corner of the rectangle.
-     * 
-     * @return the x coordinate of the upper left corner of the rectangle.
-     */
-    public abstract double getX();
-
-    /**
-     * Gets the y coordinate of the upper left corner of the rectangle.
-     * 
-     * @return the y coordinate of the upper left corner of the rectangle.
-     */
-    public abstract double getY();
-
-    /**
-     * Gets the width of the rectangle.
-     * 
-     * @return the width of the rectangle.
-     */
-    public abstract double getWidth();
-
-    /**
-     * Gets the height of the rectangle.
-     * 
-     * @return the height of the rectangle.
-     */
-    public abstract double getHeight();
-
-    /**
-     * Checks if this is an empty rectangle: one with zero as its width or
-     * height.
-     * 
-     * @return true, if the width or height is empty.
-     */
-    public abstract boolean isEmpty();
-
-    /**
-     * Sets the data for the bounding rectangle in terms of double values.
-     * 
-     * @param x
-     *            the x coordinate of the upper left corner of the rectangle.
-     * @param y
-     *            the y coordinate of the upper left corner of the rectangle.
-     * @param w
-     *            the width of the rectangle.
-     * @param h
-     *            the height of the rectangle.
-     */
-    public abstract void setFrame(double x, double y, double w, double h);
-
-    /**
-     * Gets the minimum x value of the bounding rectangle (the x coordinate of
-     * the upper left corner of the rectangle).
-     * 
-     * @return the minimum x value of the bounding rectangle.
-     */
-    public double getMinX() {
-        return getX();
-    }
-
-    /**
-     * Gets the minimum y value of the bounding rectangle (the y coordinate of
-     * the upper left corner of the rectangle).
-     * 
-     * @return the minimum y value of the bounding rectangle.
-     */
-    public double getMinY() {
-        return getY();
-    }
-
-    /**
-     * Gets the maximum x value of the bounding rectangle (the x coordinate of
-     * the upper left corner of the rectangle plus the rectangle's width).
-     * 
-     * @return the maximum x value of the bounding rectangle.
-     */
-    public double getMaxX() {
-        return getX() + getWidth();
-    }
-
-    /**
-     * Gets the maximum y value of the bounding rectangle (the y coordinate of
-     * the upper left corner of the rectangle plus the rectangle's height).
-     * 
-     * @return the maximum y value of the bounding rectangle.
-     */
-    public double getMaxY() {
-        return getY() + getHeight();
-    }
-
-    /**
-     * Gets the x coordinate of the center of the rectangle.
-     * 
-     * @return the x coordinate of the center of the rectangle.
-     */
-    public double getCenterX() {
-        return getX() + getWidth() / 2.0;
-    }
-
-    /**
-     * Gets the y coordinate of the center of the rectangle.
-     * 
-     * @return the y coordinate of the center of the rectangle.
-     */
-    public double getCenterY() {
-        return getY() + getHeight() / 2.0;
-    }
-
-    /**
-     * Places the rectangle's size and location data in a new Rectangle2D object
-     * and returns it.
-     * 
-     * @return the bounding rectangle as a new Rectangle2D object.
-     */
-    public Rectangle2D getFrame() {
-        return new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
-    }
-
-    /**
-     * Sets the bounding rectangle in terms of a Point2D which gives its upper
-     * left corner and a Dimension2D object giving its width and height.
-     * 
-     * @param loc
-     *            the new upper left corner coordinate.
-     * @param size
-     *            the new size dimensions.
-     */
-    public void setFrame(Point2D loc, Dimension2D size) {
-        setFrame(loc.getX(), loc.getY(), size.getWidth(), size.getHeight());
-    }
-
-    /**
-     * Sets the bounding rectangle to match the data contained in the specified
-     * Rectangle2D.
-     * 
-     * @param r
-     *            the rectangle that gives the new frame data.
-     */
-    public void setFrame(Rectangle2D r) {
-        setFrame(r.getX(), r.getY(), r.getWidth(), r.getHeight());
-    }
-
-    /**
-     * Sets the framing rectangle given two opposite corners. Any two corners
-     * may be used in any order as long as they are diagonally opposite one
-     * another.
-     * 
-     * @param x1
-     *            the x coordinate of one of the corner points.
-     * @param y1
-     *            the y coordinate of one of the corner points.
-     * @param x2
-     *            the x coordinate of the other corner point.
-     * @param y2
-     *            the y coordinate of the other corner point.
-     */
-    public void setFrameFromDiagonal(double x1, double y1, double x2, double y2) {
-        double rx, ry, rw, rh;
-        if (x1 < x2) {
-            rx = x1;
-            rw = x2 - x1;
-        } else {
-            rx = x2;
-            rw = x1 - x2;
-        }
-        if (y1 < y2) {
-            ry = y1;
-            rh = y2 - y1;
-        } else {
-            ry = y2;
-            rh = y1 - y2;
-        }
-        setFrame(rx, ry, rw, rh);
-    }
-
-    /**
-     * Sets the framing rectangle given two opposite corners. Any two corners
-     * may be used in any order as long as they are diagonally opposite one
-     * another.
-     * 
-     * @param p1
-     *            one of the corner points.
-     * @param p2
-     *            the other corner point.
-     */
-    public void setFrameFromDiagonal(Point2D p1, Point2D p2) {
-        setFrameFromDiagonal(p1.getX(), p1.getY(), p2.getX(), p2.getY());
-    }
-
-    /**
-     * Sets the framing rectangle given the center point and one corner. Any
-     * corner may be used.
-     * 
-     * @param centerX
-     *            the x coordinate of the center point.
-     * @param centerY
-     *            the y coordinate of the center point.
-     * @param cornerX
-     *            the x coordinate of one of the corner points.
-     * @param cornerY
-     *            the y coordinate of one of the corner points.
-     */
-    public void setFrameFromCenter(double centerX, double centerY, double cornerX, double cornerY) {
-        double width = Math.abs(cornerX - centerX);
-        double height = Math.abs(cornerY - centerY);
-        setFrame(centerX - width, centerY - height, width * 2.0, height * 2.0);
-    }
-
-    /**
-     * Sets the framing rectangle given the center point and one corner. Any
-     * corner may be used.
-     * 
-     * @param center
-     *            the center point.
-     * @param corner
-     *            a corner point.
-     */
-    public void setFrameFromCenter(Point2D center, Point2D corner) {
-        setFrameFromCenter(center.getX(), center.getY(), corner.getX(), corner.getY());
-    }
-
-    public boolean contains(Point2D point) {
-        return contains(point.getX(), point.getY());
-    }
-
-    public boolean intersects(Rectangle2D rect) {
-        return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
-    }
-
-    public boolean contains(Rectangle2D rect) {
-        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
-    }
-
-    public Rectangle getBounds() {
-        int x1 = (int)Math.floor(getMinX());
-        int y1 = (int)Math.floor(getMinY());
-        int x2 = (int)Math.ceil(getMaxX());
-        int y2 = (int)Math.ceil(getMaxY());
-        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
-    }
-
-    public PathIterator getPathIterator(AffineTransform t, double flatness) {
-        return new FlatteningPathIterator(getPathIterator(t), flatness);
-    }
-
-    @Override
-    public Object clone() {
-        try {
-            return super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new InternalError();
-        }
-    }
-
-}
diff --git a/awt/java/awt/geom/RoundRectangle2D.java b/awt/java/awt/geom/RoundRectangle2D.java
deleted file mode 100644
index 8fbddd6..0000000
--- a/awt/java/awt/geom/RoundRectangle2D.java
+++ /dev/null
@@ -1,635 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.geom;
-
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class RoundRectangle2D describes a rectangle with rounded corners with
- * high-precision data that is appropriate for geometric operations.
- * 
- * @since Android 1.0
- */
-public abstract class RoundRectangle2D extends RectangularShape {
-
-    /**
-     * The Class Float is the subclass of RoundRectangle2D that has all of its
-     * data values stored with float-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Float extends RoundRectangle2D {
-
-        /**
-         * The x coordinate of the rectangle's upper left corner.
-         */
-        public float x;
-
-        /**
-         * The y coordinate of the rectangle's upper left corner.
-         */
-        public float y;
-
-        /**
-         * The width of the rectangle.
-         */
-        public float width;
-
-        /**
-         * The height of the rectangle.
-         */
-        public float height;
-
-        /**
-         * The arc width of the rounded corners.
-         */
-        public float arcwidth;
-
-        /**
-         * The arc height of the rounded corners.
-         */
-        public float archeight;
-
-        /**
-         * Instantiates a new float-valued RoundRectangle2D with its data-values
-         * set to zero.
-         */
-        public Float() {
-        }
-
-        /**
-         * Instantiates a new float-valued RoundRectangle2D with the specified
-         * data values.
-         * 
-         * @param x
-         *            the x coordinate of the rectangle's upper left corner.
-         * @param y
-         *            the y coordinate of the rectangle's upper left corner.
-         * @param width
-         *            the width of the rectangle.
-         * @param height
-         *            the height of the rectangle.
-         * @param arcwidth
-         *            the arc width of the rounded corners.
-         * @param archeight
-         *            the arc height of the rounded corners.
-         */
-        public Float(float x, float y, float width, float height, float arcwidth, float archeight) {
-            setRoundRect(x, y, width, height, arcwidth, archeight);
-        }
-
-        @Override
-        public double getX() {
-            return x;
-        }
-
-        @Override
-        public double getY() {
-            return y;
-        }
-
-        @Override
-        public double getWidth() {
-            return width;
-        }
-
-        @Override
-        public double getHeight() {
-            return height;
-        }
-
-        @Override
-        public double getArcWidth() {
-            return arcwidth;
-        }
-
-        @Override
-        public double getArcHeight() {
-            return archeight;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return width <= 0.0f || height <= 0.0f;
-        }
-
-        /**
-         * Sets the data of the round rectangle.
-         * 
-         * @param x
-         *            the x coordinate of the rectangle's upper left corner.
-         * @param y
-         *            the y coordinate of the rectangle's upper left corner.
-         * @param width
-         *            the width of the rectangle.
-         * @param height
-         *            the height of the rectangle.
-         * @param arcwidth
-         *            the arc width of the rounded corners.
-         * @param archeight
-         *            the arc height of the rounded corners.
-         */
-        public void setRoundRect(float x, float y, float width, float height, float arcwidth,
-                float archeight) {
-            this.x = x;
-            this.y = y;
-            this.width = width;
-            this.height = height;
-            this.arcwidth = arcwidth;
-            this.archeight = archeight;
-        }
-
-        @Override
-        public void setRoundRect(double x, double y, double width, double height, double arcwidth,
-                double archeight) {
-            this.x = (float)x;
-            this.y = (float)y;
-            this.width = (float)width;
-            this.height = (float)height;
-            this.arcwidth = (float)arcwidth;
-            this.archeight = (float)archeight;
-        }
-
-        @Override
-        public void setRoundRect(RoundRectangle2D rr) {
-            this.x = (float)rr.getX();
-            this.y = (float)rr.getY();
-            this.width = (float)rr.getWidth();
-            this.height = (float)rr.getHeight();
-            this.arcwidth = (float)rr.getArcWidth();
-            this.archeight = (float)rr.getArcHeight();
-        }
-
-        public Rectangle2D getBounds2D() {
-            return new Rectangle2D.Float(x, y, width, height);
-        }
-    }
-
-    /**
-     * The Class Double is the subclass of RoundRectangle2D that has all of its
-     * data values stored with double-level precision.
-     * 
-     * @since Android 1.0
-     */
-    public static class Double extends RoundRectangle2D {
-
-        /**
-         * The x coordinate of the rectangle's upper left corner.
-         */
-        public double x;
-
-        /**
-         * The y coordinate of the rectangle's upper left corner.
-         */
-        public double y;
-
-        /**
-         * The width of the rectangle.
-         */
-        public double width;
-
-        /**
-         * The height of the rectangle.
-         */
-        public double height;
-
-        /**
-         * The arc width of the rounded corners.
-         */
-        public double arcwidth;
-
-        /**
-         * The arc height of the rounded corners.
-         */
-        public double archeight;
-
-        /**
-         * Instantiates a new double-valued RoundRectangle2D with its
-         * data-values set to zero.
-         */
-        public Double() {
-        }
-
-        /**
-         * Instantiates a new double-valued RoundRectangle2D with the specified
-         * data values.
-         * 
-         * @param x
-         *            the x coordinate of the rectangle's upper left corner.
-         * @param y
-         *            the y coordinate of the rectangle's upper left corner.
-         * @param width
-         *            the width of the rectangle.
-         * @param height
-         *            the height of the rectangle.
-         * @param arcwidth
-         *            the arc width of the rounded corners.
-         * @param archeight
-         *            the arc height of the rounded corners.
-         */
-        public Double(double x, double y, double width, double height, double arcwidth,
-                double archeight) {
-            setRoundRect(x, y, width, height, arcwidth, archeight);
-        }
-
-        @Override
-        public double getX() {
-            return x;
-        }
-
-        @Override
-        public double getY() {
-            return y;
-        }
-
-        @Override
-        public double getWidth() {
-            return width;
-        }
-
-        @Override
-        public double getHeight() {
-            return height;
-        }
-
-        @Override
-        public double getArcWidth() {
-            return arcwidth;
-        }
-
-        @Override
-        public double getArcHeight() {
-            return archeight;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return width <= 0.0 || height <= 0.0;
-        }
-
-        @Override
-        public void setRoundRect(double x, double y, double width, double height, double arcwidth,
-                double archeight) {
-            this.x = x;
-            this.y = y;
-            this.width = width;
-            this.height = height;
-            this.arcwidth = arcwidth;
-            this.archeight = archeight;
-        }
-
-        @Override
-        public void setRoundRect(RoundRectangle2D rr) {
-            this.x = rr.getX();
-            this.y = rr.getY();
-            this.width = rr.getWidth();
-            this.height = rr.getHeight();
-            this.arcwidth = rr.getArcWidth();
-            this.archeight = rr.getArcHeight();
-        }
-
-        public Rectangle2D getBounds2D() {
-            return new Rectangle2D.Double(x, y, width, height);
-        }
-    }
-
-    /*
-     * RoundRectangle2D path iterator
-     */
-    /**
-     * The subclass of PathIterator to traverse a RoundRectangle2D.
-     */
-    class Iterator implements PathIterator {
-
-        /*
-         * Path for round corners generated the same way as Ellipse2D
-         */
-
-        /**
-         * The coefficient to calculate control points of Bezier curves.
-         */
-        double u = 0.5 - 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
-
-        /**
-         * The points coordinates calculation table.
-         */
-        double points[][] = {
-                {
-                        0.0, 0.5, 0.0, 0.0
-                }, // MOVETO
-                {
-                        1.0, -0.5, 0.0, 0.0
-                }, // LINETO
-                {
-                        1.0, -u, 0.0, 0.0, // CUBICTO
-                        1.0, 0.0, 0.0, u, 1.0, 0.0, 0.0, 0.5
-                }, {
-                        1.0, 0.0, 1.0, -0.5
-                }, // LINETO
-                {
-                        1.0, 0.0, 1.0, -u, // CUBICTO
-                        1.0, -u, 1.0, 0.0, 1.0, -0.5, 1.0, 0.0
-                }, {
-                        0.0, 0.5, 1.0, 0.0
-                }, // LINETO
-                {
-                        0.0, u, 1.0, 0.0, // CUBICTO
-                        0.0, 0.0, 1.0, -u, 0.0, 0.0, 1.0, -0.5
-                }, {
-                        0.0, 0.0, 0.0, 0.5
-                }, // LINETO
-                {
-                        0.0, 0.0, 0.0, u, // CUBICTO
-                        0.0, u, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0
-                }
-        };
-
-        /**
-         * The segment types correspond to points array.
-         */
-        int types[] = {
-                SEG_MOVETO, SEG_LINETO, SEG_CUBICTO, SEG_LINETO, SEG_CUBICTO, SEG_LINETO,
-                SEG_CUBICTO, SEG_LINETO, SEG_CUBICTO
-        };
-
-        /**
-         * The x coordinate of left-upper corner of the round rectangle bounds.
-         */
-        double x;
-
-        /**
-         * The y coordinate of left-upper corner of the round rectangle bounds.
-         */
-        double y;
-
-        /**
-         * The width of the round rectangle bounds.
-         */
-        double width;
-
-        /**
-         * The height of the round rectangle bounds.
-         */
-        double height;
-
-        /**
-         * The width of arc corners of the round rectangle.
-         */
-        double aw;
-
-        /**
-         * The height of arc corners of the round rectangle.
-         */
-        double ah;
-
-        /**
-         * The path iterator transformation.
-         */
-        AffineTransform t;
-
-        /**
-         * The current segment index.
-         */
-        int index;
-
-        /**
-         * Constructs a new RoundRectangle2D.Iterator for given round rectangle
-         * and transformation.
-         * 
-         * @param rr
-         *            - the source RoundRectangle2D object
-         * @param at
-         *            - the AffineTransform object to apply rectangle path
-         */
-        Iterator(RoundRectangle2D rr, AffineTransform at) {
-            this.x = rr.getX();
-            this.y = rr.getY();
-            this.width = rr.getWidth();
-            this.height = rr.getHeight();
-            this.aw = Math.min(width, rr.getArcWidth());
-            this.ah = Math.min(height, rr.getArcHeight());
-            this.t = at;
-            if (width < 0.0 || height < 0.0 || aw < 0.0 || ah < 0.0) {
-                index = points.length;
-            }
-        }
-
-        public int getWindingRule() {
-            return WIND_NON_ZERO;
-        }
-
-        public boolean isDone() {
-            return index > points.length;
-        }
-
-        public void next() {
-            index++;
-        }
-
-        public int currentSegment(double[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            if (index == points.length) {
-                return SEG_CLOSE;
-            }
-            int j = 0;
-            double p[] = points[index];
-            for (int i = 0; i < p.length; i += 4) {
-                coords[j++] = x + p[i + 0] * width + p[i + 1] * aw;
-                coords[j++] = y + p[i + 2] * height + p[i + 3] * ah;
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, j / 2);
-            }
-            return types[index];
-        }
-
-        public int currentSegment(float[] coords) {
-            if (isDone()) {
-                // awt.4B=Iterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            if (index == points.length) {
-                return SEG_CLOSE;
-            }
-            int j = 0;
-            double p[] = points[index];
-            for (int i = 0; i < p.length; i += 4) {
-                coords[j++] = (float)(x + p[i + 0] * width + p[i + 1] * aw);
-                coords[j++] = (float)(y + p[i + 2] * height + p[i + 3] * ah);
-            }
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, j / 2);
-            }
-            return types[index];
-        }
-
-    }
-
-    /**
-     * Instantiates a new RoundRectangle2D.
-     */
-    protected RoundRectangle2D() {
-    }
-
-    /**
-     * Gets the arc width.
-     * 
-     * @return the arc width.
-     */
-    public abstract double getArcWidth();
-
-    /**
-     * Gets the arc height.
-     * 
-     * @return the arc height.
-     */
-    public abstract double getArcHeight();
-
-    /**
-     * Sets the data of the RoundRectangle2D.
-     * 
-     * @param x
-     *            the x coordinate of the rectangle's upper left corner.
-     * @param y
-     *            the y coordinate of the rectangle's upper left corner.
-     * @param width
-     *            the width of the rectangle.
-     * @param height
-     *            the height of the rectangle.
-     * @param arcWidth
-     *            the arc width of the rounded corners.
-     * @param arcHeight
-     *            the arc height of the rounded corners.
-     */
-    public abstract void setRoundRect(double x, double y, double width, double height,
-            double arcWidth, double arcHeight);
-
-    /**
-     * Sets the data of the RoundRectangle2D by copying the values from an
-     * existing RoundRectangle2D.
-     * 
-     * @param rr
-     *            the round rectangle to copy the data from.
-     * @throws NullPointerException
-     *             if rr is null.
-     */
-    public void setRoundRect(RoundRectangle2D rr) {
-        setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(), rr.getArcWidth(), rr
-                .getArcHeight());
-    }
-
-    @Override
-    public void setFrame(double x, double y, double width, double height) {
-        setRoundRect(x, y, width, height, getArcWidth(), getArcHeight());
-    }
-
-    public boolean contains(double px, double py) {
-        if (isEmpty()) {
-            return false;
-        }
-
-        double rx1 = getX();
-        double ry1 = getY();
-        double rx2 = rx1 + getWidth();
-        double ry2 = ry1 + getHeight();
-
-        if (px < rx1 || px >= rx2 || py < ry1 || py >= ry2) {
-            return false;
-        }
-
-        double aw = getArcWidth() / 2.0;
-        double ah = getArcHeight() / 2.0;
-
-        double cx, cy;
-
-        if (px < rx1 + aw) {
-            cx = rx1 + aw;
-        } else if (px > rx2 - aw) {
-            cx = rx2 - aw;
-        } else {
-            return true;
-        }
-
-        if (py < ry1 + ah) {
-            cy = ry1 + ah;
-        } else if (py > ry2 - ah) {
-            cy = ry2 - ah;
-        } else {
-            return true;
-        }
-
-        px = (px - cx) / aw;
-        py = (py - cy) / ah;
-        return px * px + py * py <= 1.0;
-    }
-
-    public boolean intersects(double rx, double ry, double rw, double rh) {
-        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
-            return false;
-        }
-
-        double x1 = getX();
-        double y1 = getY();
-        double x2 = x1 + getWidth();
-        double y2 = y1 + getHeight();
-
-        double rx1 = rx;
-        double ry1 = ry;
-        double rx2 = rx + rw;
-        double ry2 = ry + rh;
-
-        if (rx2 < x1 || x2 < rx1 || ry2 < y1 || y2 < ry1) {
-            return false;
-        }
-
-        double cx = (x1 + x2) / 2.0;
-        double cy = (y1 + y2) / 2.0;
-
-        double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
-        double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
-
-        return contains(nx, ny);
-    }
-
-    public boolean contains(double rx, double ry, double rw, double rh) {
-        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
-            return false;
-        }
-
-        double rx1 = rx;
-        double ry1 = ry;
-        double rx2 = rx + rw;
-        double ry2 = ry + rh;
-
-        return contains(rx1, ry1) && contains(rx2, ry1) && contains(rx2, ry2) && contains(rx1, ry2);
-    }
-
-    public PathIterator getPathIterator(AffineTransform at) {
-        return new Iterator(this, at);
-    }
-
-}
diff --git a/awt/java/awt/geom/package.html b/awt/java/awt/geom/package.html
deleted file mode 100644
index e3a236e..0000000
--- a/awt/java/awt/geom/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes and interfaces related to Java2D shapes and geometry.
-    </p>
-    @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/im/InputContext.java b/awt/java/awt/im/InputContext.java
deleted file mode 100644
index cce5148..0000000
--- a/awt/java/awt/im/InputContext.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.im;
-
-import java.awt.AWTEvent;
-//???AWT: import java.awt.Component;
-import java.util.Locale;
-
-import org.apache.harmony.awt.im.InputMethodContext;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class InputContext {
-    protected InputContext() {
-    }
-
-    public static InputContext getInstance() {
-        return new InputMethodContext();
-    }
-
-    public void dispatchEvent(AWTEvent event) {
-    }
-
-    public void dispose() {
-    }
-
-    public void endComposition() {
-    }
-
-    public Object getInputMethodControlObject() {
-        return null;
-    }
-
-    public Locale getLocale() {
-        return null;
-    }
-
-    public boolean isCompositionEnabled() {
-        return false;
-    }
-
-    public void reconvert() {
-    }
-
-    //???AWT
-    /*
-    public void removeNotify(Component client) {
-    }
-    */
-
-    public boolean selectInputMethod(Locale locale) {
-        return false;
-    }
-
-    public void setCharacterSubsets(Character.Subset[] subsets) {
-    }
-    
-    public void setCompositionEnabled(boolean enable) {
-    }
-}
-
diff --git a/awt/java/awt/im/InputMethodHighlight.java b/awt/java/awt/im/InputMethodHighlight.java
deleted file mode 100644
index 865d47c..0000000
--- a/awt/java/awt/im/InputMethodHighlight.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package java.awt.im;
-
-import java.util.Map;
-import java.awt.font.TextAttribute;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public class InputMethodHighlight {
-
-    public static final int RAW_TEXT = 0;
-
-    public static final int CONVERTED_TEXT = 1;
-
-    public static final InputMethodHighlight
-        UNSELECTED_RAW_TEXT_HIGHLIGHT = new InputMethodHighlight(false, RAW_TEXT);
-
-    public static final InputMethodHighlight
-        SELECTED_RAW_TEXT_HIGHLIGHT = new InputMethodHighlight(true, RAW_TEXT);
-
-    public static final InputMethodHighlight
-        UNSELECTED_CONVERTED_TEXT_HIGHLIGHT = 
-            new InputMethodHighlight(false, CONVERTED_TEXT);
-
-    public static final InputMethodHighlight
-        SELECTED_CONVERTED_TEXT_HIGHLIGHT = 
-            new InputMethodHighlight(true, CONVERTED_TEXT);
-    
-    private boolean selected;
-    private int state;
-    private int variation;
-    private Map<TextAttribute,?> style;
-
-    public InputMethodHighlight(boolean selected, int state, int variation) {
-        this(selected, state, variation, null);
-    }
-
-    public InputMethodHighlight(boolean selected, int state,
-                                int variation, Map<java.awt.font.TextAttribute, ?> style) {
-        if ((state != RAW_TEXT) && (state != CONVERTED_TEXT)) {
-            // awt.20B=unknown input method highlight state
-            throw new IllegalArgumentException(Messages.getString("awt.20B")); //$NON-NLS-1$
-        }
-        this.selected = selected;
-        this.state = state;
-        this.variation = variation;
-        this.style = style;
-    }
-
-    public InputMethodHighlight(boolean selected, int state) {
-        this(selected, state, 0, null);
-    }
-
-    public int getState() {
-        return state;
-    }
-
-    public Map<java.awt.font.TextAttribute, ?> getStyle() {
-        return style;
-    }
-
-    public int getVariation() {
-        return variation;
-    }
-
-    public boolean isSelected() {
-        return selected;
-    }
-}
-
diff --git a/awt/java/awt/im/InputMethodRequests.java b/awt/java/awt/im/InputMethodRequests.java
deleted file mode 100644
index b12d397..0000000
--- a/awt/java/awt/im/InputMethodRequests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.im;
-
-import java.awt.Rectangle;
-import java.awt.font.TextHitInfo;
-import java.text.AttributedCharacterIterator;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface InputMethodRequests {
-
-    public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes);
-
-    public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, AttributedCharacterIterator.Attribute[] attributes);
-
-    public int getCommittedTextLength();
-
-    public int getInsertPositionOffset();
-
-    public TextHitInfo getLocationOffset(int x, int y);
-
-    public AttributedCharacterIterator getSelectedText(AttributedCharacterIterator.Attribute[] attributes);
-
-    public Rectangle getTextLocation(TextHitInfo offset);
-}
-
diff --git a/awt/java/awt/im/InputSubset.java b/awt/java/awt/im/InputSubset.java
deleted file mode 100644
index 708881e..0000000
--- a/awt/java/awt/im/InputSubset.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package java.awt.im;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public final class InputSubset extends Character.Subset {
-
-    public static final InputSubset LATIN = new InputSubset("LATIN"); //$NON-NLS-1$
-
-    public static final InputSubset 
-        LATIN_DIGITS = new InputSubset("LATIN_DIGITS"); //$NON-NLS-1$
-
-    public static final InputSubset 
-        TRADITIONAL_HANZI = new InputSubset("TRADITIONAL_HANZI"); //$NON-NLS-1$
-
-    public static final InputSubset 
-        SIMPLIFIED_HANZI = new InputSubset("SIMPLIFIED_HANZI"); //$NON-NLS-1$
-
-    public static final InputSubset KANJI = new InputSubset("KANJI"); //$NON-NLS-1$
-
-    public static final InputSubset HANJA = new InputSubset("HANJA"); //$NON-NLS-1$
-
-    public static final InputSubset 
-        HALFWIDTH_KATAKANA = new InputSubset("HALFWIDTH_KATAKANA"); //$NON-NLS-1$
-
-    public static final InputSubset 
-        FULLWIDTH_LATIN = new InputSubset("FULLWIDTH_LATIN"); //$NON-NLS-1$
-
-    public static final InputSubset 
-        FULLWIDTH_DIGITS = new InputSubset("FULLWIDTH_DIGITS"); //$NON-NLS-1$
-
-    private InputSubset(String name) {
-        super(name);
-    }
-}
-
diff --git a/awt/java/awt/im/spi/InputMethod.java b/awt/java/awt/im/spi/InputMethod.java
deleted file mode 100644
index 67a8834..0000000
--- a/awt/java/awt/im/spi/InputMethod.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.im.spi;
-
-import java.awt.AWTEvent;
-import java.awt.Rectangle;
-import java.util.Locale;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface InputMethod {
-
-    public void activate();
-
-    public void deactivate(boolean isTemporary);
-
-    public void dispatchEvent(AWTEvent event);
-
-    public void dispose();
-
-    public void endComposition();
-
-    public Object getControlObject();
-
-    public Locale getLocale();
-
-    public void hideWindows();
-
-    public boolean isCompositionEnabled();
-
-    public void notifyClientWindowChange(Rectangle bounds);
-
-    public void reconvert();
-
-    public void removeNotify();
-
-    public void setCharacterSubsets(Character.Subset[] subsets);
-
-    public void setCompositionEnabled(boolean enable);
-
-    public void setInputMethodContext(InputMethodContext context);
-
-    public boolean setLocale(Locale locale);
-}
-
diff --git a/awt/java/awt/im/spi/InputMethodContext.java b/awt/java/awt/im/spi/InputMethodContext.java
deleted file mode 100644
index bfc773c..0000000
--- a/awt/java/awt/im/spi/InputMethodContext.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.im.spi;
-
-//???AWT: import java.awt.Window;
-import java.awt.font.TextHitInfo;
-import java.awt.im.InputMethodRequests;
-import java.text.AttributedCharacterIterator;
-//???AWT: import javax.swing.JFrame;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface InputMethodContext extends InputMethodRequests {
-
-//    ???AWT: public JFrame createInputMethodJFrame(String title, boolean attachToInputContext);
-
-//    ???AWT: public Window createInputMethodWindow(String title, boolean attachToInputContext);
-
-    public void dispatchInputMethodEvent(int id, AttributedCharacterIterator text, int committedCharacterCount, TextHitInfo caret, TextHitInfo visiblePosition);
-
-    public void enableClientWindowNotification(InputMethod inputMethod, boolean enable);
-
-}
-
diff --git a/awt/java/awt/im/spi/InputMethodDescriptor.java b/awt/java/awt/im/spi/InputMethodDescriptor.java
deleted file mode 100644
index c800bc1..0000000
--- a/awt/java/awt/im/spi/InputMethodDescriptor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.im.spi;
-
-import java.awt.AWTException;
-import java.awt.Image;
-import java.util.Locale;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-public interface InputMethodDescriptor {
-
-    public Locale[] getAvailableLocales() throws AWTException;
-
-    public InputMethod createInputMethod() throws Exception;
-
-    public String getInputMethodDisplayName(Locale inputLocale, Locale displayLanguage);
-
-    public Image getInputMethodIcon(Locale inputLocale);
-
-    public boolean hasDynamicLocaleList();
-
-}
-
diff --git a/awt/java/awt/image/AffineTransformOp.java b/awt/java/awt/image/AffineTransformOp.java
deleted file mode 100644
index db25e1a..0000000
--- a/awt/java/awt/image/AffineTransformOp.java
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky, Denis M. Kishenko
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.Point2D;
-import java.awt.geom.NoninvertibleTransformException;
-import java.awt.*;
-import java.util.Arrays;
-
-import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The AffineTransform class translates coordinates from 2D coordinates in the
- * source image or Raster to 2D coordinates in the destination image or Raster
- * using affine transformation. The number of bands in the source Raster should
- * equal to the number of bands in the destination Raster.
- * 
- * @since Android 1.0
- */
-public class AffineTransformOp implements BufferedImageOp, RasterOp {
-
-    /**
-     * The Constant TYPE_NEAREST_NEIGHBOR indicates nearest-neighbor
-     * interpolation type.
-     */
-    public static final int TYPE_NEAREST_NEIGHBOR = 1;
-
-    /**
-     * The Constant TYPE_BILINEAR indicates bilinear interpolation type.
-     */
-    public static final int TYPE_BILINEAR = 2;
-
-    /**
-     * The Constant TYPE_BICUBIC indicates bi-cubic interpolation type.
-     */
-    public static final int TYPE_BICUBIC = 3;
-
-    /**
-     * The i type.
-     */
-    private int iType; // interpolation type
-
-    /**
-     * The at.
-     */
-    private AffineTransform at;
-
-    /**
-     * The hints.
-     */
-    private RenderingHints hints;
-
-    static {
-        // TODO - uncomment
-        // System.loadLibrary("imageops");
-    }
-
-    /**
-     * Instantiates a new AffineTransformOp with the specified AffineTransform
-     * and RenderingHints object which defines the interpolation type.
-     * 
-     * @param xform
-     *            the AffineTransform.
-     * @param hints
-     *            the RenderingHints object which defines the interpolation
-     *            type.
-     */
-    public AffineTransformOp(AffineTransform xform, RenderingHints hints) {
-        this(xform, TYPE_NEAREST_NEIGHBOR);
-        this.hints = hints;
-
-        if (hints != null) {
-            Object hint = hints.get(RenderingHints.KEY_INTERPOLATION);
-            if (hint != null) {
-                // Nearest neighbor is default
-                if (hint == RenderingHints.VALUE_INTERPOLATION_BILINEAR) {
-                    this.iType = TYPE_BILINEAR;
-                } else if (hint == RenderingHints.VALUE_INTERPOLATION_BICUBIC) {
-                    this.iType = TYPE_BICUBIC;
-                }
-            } else {
-                hint = hints.get(RenderingHints.KEY_RENDERING);
-                // Determine from rendering quality
-                if (hint == RenderingHints.VALUE_RENDER_QUALITY) {
-                    this.iType = TYPE_BILINEAR;
-                    // For speed use nearest neighbor
-                }
-            }
-        }
-    }
-
-    /**
-     * Instantiates a new AffineTransformOp with the specified AffineTransform
-     * and a specified interpolation type from the list of predefined
-     * interpolation types.
-     * 
-     * @param xform
-     *            the AffineTransform.
-     * @param interp
-     *            the one of predefined interpolation types:
-     *            TYPE_NEAREST_NEIGHBOR, TYPE_BILINEAR, or TYPE_BICUBIC.
-     */
-    public AffineTransformOp(AffineTransform xform, int interp) {
-        if (Math.abs(xform.getDeterminant()) <= Double.MIN_VALUE) {
-            // awt.24F=Unable to invert transform {0}
-            throw new ImagingOpException(Messages.getString("awt.24F", xform)); //$NON-NLS-1$
-        }
-
-        this.at = (AffineTransform)xform.clone();
-
-        if (interp != TYPE_NEAREST_NEIGHBOR && interp != TYPE_BILINEAR && interp != TYPE_BICUBIC) {
-            // awt.250=Unknown interpolation type: {0}
-            throw new IllegalArgumentException(Messages.getString("awt.250", interp)); //$NON-NLS-1$
-        }
-
-        this.iType = interp;
-    }
-
-    /**
-     * Gets the interpolation type.
-     * 
-     * @return the interpolation type.
-     */
-    public final int getInterpolationType() {
-        return iType;
-    }
-
-    public final RenderingHints getRenderingHints() {
-        if (hints == null) {
-            Object value = null;
-
-            switch (iType) {
-                case TYPE_NEAREST_NEIGHBOR:
-                    value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
-                    break;
-                case TYPE_BILINEAR:
-                    value = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
-                    break;
-                case TYPE_BICUBIC:
-                    value = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
-                    break;
-                default:
-                    value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
-            }
-
-            hints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, value);
-        }
-
-        return hints;
-    }
-
-    /**
-     * Gets the affine transform associated with this AffineTransformOp.
-     * 
-     * @return the AffineTransform.
-     */
-    public final AffineTransform getTransform() {
-        return (AffineTransform)at.clone();
-    }
-
-    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
-        return at.transform(srcPt, dstPt);
-    }
-
-    public final Rectangle2D getBounds2D(BufferedImage src) {
-        return getBounds2D(src.getRaster());
-    }
-
-    public final Rectangle2D getBounds2D(Raster src) {
-        // We position source raster to (0,0) even if it is translated child
-        // raster.
-        // This means that we need only width and height of the src
-        int width = src.getWidth();
-        int height = src.getHeight();
-
-        float[] corners = {
-                0, 0, width, 0, width, height, 0, height
-        };
-
-        at.transform(corners, 0, corners, 0, 4);
-
-        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0, 0);
-        bounds.add(corners[2], corners[3]);
-        bounds.add(corners[4], corners[5]);
-        bounds.add(corners[6], corners[7]);
-
-        return bounds;
-    }
-
-    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
-        Rectangle2D newBounds = getBounds2D(src);
-
-        // Destination image should include (0,0) + positive part
-        // of the area bounded by newBounds (in source coordinate system).
-        double dstWidth = newBounds.getX() + newBounds.getWidth();
-        double dstHeight = newBounds.getY() + newBounds.getHeight();
-
-        if (dstWidth <= 0 || dstHeight <= 0) {
-            // awt.251=Transformed width ({0}) and height ({1}) should be
-            // greater than 0
-            throw new RasterFormatException(Messages.getString("awt.251", dstWidth, dstHeight)); //$NON-NLS-1$
-        }
-
-        if (destCM != null) {
-            return new BufferedImage(destCM, destCM.createCompatibleWritableRaster((int)dstWidth,
-                    (int)dstHeight), destCM.isAlphaPremultiplied(), null);
-        }
-
-        ColorModel cm = src.getColorModel();
-
-        // Interpolation other than NN doesn't make any sense for index color
-        if (iType != TYPE_NEAREST_NEIGHBOR && cm instanceof IndexColorModel) {
-            return new BufferedImage((int)dstWidth, (int)dstHeight, BufferedImage.TYPE_INT_ARGB);
-        }
-
-        // OK, we can get source color model
-        return new BufferedImage(cm, src.getRaster().createCompatibleWritableRaster((int)dstWidth,
-                (int)dstHeight), cm.isAlphaPremultiplied(), null);
-    }
-
-    public WritableRaster createCompatibleDestRaster(Raster src) {
-        // Here approach is other then in createCompatibleDestImage -
-        // destination should include only
-        // transformed image, but not (0,0) in source coordinate system
-
-        Rectangle2D newBounds = getBounds2D(src);
-        return src.createCompatibleWritableRaster((int)newBounds.getX(), (int)newBounds.getY(),
-                (int)newBounds.getWidth(), (int)newBounds.getHeight());
-    }
-
-    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
-        if (src == dst) {
-            // awt.252=Source can't be same as the destination
-            throw new IllegalArgumentException(Messages.getString("awt.252")); //$NON-NLS-1$
-        }
-
-        ColorModel srcCM = src.getColorModel();
-        BufferedImage finalDst = null;
-
-        if (srcCM instanceof IndexColorModel
-                && (iType != TYPE_NEAREST_NEIGHBOR || srcCM.getPixelSize() % 8 != 0)) {
-            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), true);
-            srcCM = src.getColorModel();
-        }
-
-        if (dst == null) {
-            dst = createCompatibleDestImage(src, srcCM);
-        } else {
-            if (!srcCM.equals(dst.getColorModel())) {
-                // Treat BufferedImage.TYPE_INT_RGB and
-                // BufferedImage.TYPE_INT_ARGB as same
-                if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src.getType() == BufferedImage.TYPE_INT_ARGB) && (dst
-                        .getType() == BufferedImage.TYPE_INT_RGB || dst.getType() == BufferedImage.TYPE_INT_ARGB))) {
-                    finalDst = dst;
-                    dst = createCompatibleDestImage(src, srcCM);
-                }
-            }
-        }
-
-        // Skip alpha channel for TYPE_INT_RGB images
-        if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
-            // awt.21F=Unable to transform source
-            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
-            // TODO - uncomment
-            // if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) !=
-            // 0)
-            // throw new ImagingOpException ("Unable to transform source");
-        }
-
-        if (finalDst != null) {
-            Graphics2D g = finalDst.createGraphics();
-            g.setComposite(AlphaComposite.Src);
-            g.drawImage(dst, 0, 0, null);
-        } else {
-            finalDst = dst;
-        }
-
-        return finalDst;
-    }
-
-    public final WritableRaster filter(Raster src, WritableRaster dst) {
-        if (src == dst) {
-            // awt.252=Source can't be same as the destination
-            throw new IllegalArgumentException(Messages.getString("awt.252")); //$NON-NLS-1$
-        }
-
-        if (dst == null) {
-            dst = createCompatibleDestRaster(src);
-        } else if (src.getNumBands() != dst.getNumBands()) {
-            // awt.253=Different number of bands in source and destination
-            throw new IllegalArgumentException(Messages.getString("awt.253")); //$NON-NLS-1$
-        }
-
-        if (slowFilter(src, dst) != 0) {
-            // awt.21F=Unable to transform source
-            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
-            // TODO - uncomment
-            // if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM) != 0)
-            // throw new ImagingOpException("Unable to transform source");
-        }
-
-        return dst;
-    }
-
-    // TODO remove when method is used
-    /**
-     * Ipp filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @param imageType
-     *            the image type.
-     * @return the int.
-     */
-    @SuppressWarnings("unused")
-    private int ippFilter(Raster src, WritableRaster dst, int imageType) {
-        int srcStride, dstStride;
-        boolean skipChannel = false;
-        int channels;
-        int offsets[] = null;
-
-        switch (imageType) {
-            case BufferedImage.TYPE_INT_RGB:
-            case BufferedImage.TYPE_INT_BGR: {
-                channels = 4;
-                srcStride = src.getWidth() * 4;
-                dstStride = dst.getWidth() * 4;
-                skipChannel = true;
-                break;
-            }
-
-            case BufferedImage.TYPE_INT_ARGB:
-            case BufferedImage.TYPE_INT_ARGB_PRE:
-            case BufferedImage.TYPE_4BYTE_ABGR:
-            case BufferedImage.TYPE_4BYTE_ABGR_PRE: {
-                channels = 4;
-                srcStride = src.getWidth() * 4;
-                dstStride = dst.getWidth() * 4;
-                break;
-            }
-
-            case BufferedImage.TYPE_BYTE_GRAY:
-            case BufferedImage.TYPE_BYTE_INDEXED: {
-                channels = 1;
-                srcStride = src.getWidth();
-                dstStride = dst.getWidth();
-                break;
-            }
-
-            case BufferedImage.TYPE_3BYTE_BGR: {
-                channels = 3;
-                srcStride = src.getWidth() * 3;
-                dstStride = dst.getWidth() * 3;
-                break;
-            }
-
-            case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in
-                // native code?
-            case BufferedImage.TYPE_USHORT_565_RGB:
-            case BufferedImage.TYPE_USHORT_555_RGB:
-            case BufferedImage.TYPE_BYTE_BINARY: {
-                return slowFilter(src, dst);
-            }
-
-            default: {
-                SampleModel srcSM = src.getSampleModel();
-                SampleModel dstSM = dst.getSampleModel();
-
-                if (srcSM instanceof PixelInterleavedSampleModel
-                        && dstSM instanceof PixelInterleavedSampleModel) {
-                    // Check PixelInterleavedSampleModel
-                    if (srcSM.getDataType() != DataBuffer.TYPE_BYTE
-                            || dstSM.getDataType() != DataBuffer.TYPE_BYTE) {
-                        return slowFilter(src, dst);
-                    }
-
-                    channels = srcSM.getNumBands(); // Have IPP functions for 1,
-                    // 3 and 4 channels
-                    if (channels != 1 && channels != 3 && channels != 4) {
-                        return slowFilter(src, dst);
-                    }
-
-                    int dataTypeSize = DataBuffer.getDataTypeSize(srcSM.getDataType()) / 8;
-
-                    srcStride = ((ComponentSampleModel)srcSM).getScanlineStride() * dataTypeSize;
-                    dstStride = ((ComponentSampleModel)dstSM).getScanlineStride() * dataTypeSize;
-                } else if (srcSM instanceof SinglePixelPackedSampleModel
-                        && dstSM instanceof SinglePixelPackedSampleModel) {
-                    // Check SinglePixelPackedSampleModel
-                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)srcSM;
-                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel)dstSM;
-
-                    // No IPP function for this type
-                    if (sppsm1.getDataType() == DataBuffer.TYPE_USHORT) {
-                        return slowFilter(src, dst);
-                    }
-
-                    channels = sppsm1.getNumBands();
-                    // Have IPP functions for 1, 3 and 4 channels
-                    if (channels != 1 && channels != 3 && channels != 4) {
-                        return slowFilter(src, dst);
-                    }
-
-                    // Check compatibility of sample models
-                    if (sppsm1.getDataType() != sppsm2.getDataType()
-                            || !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets())
-                            || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) {
-                        return slowFilter(src, dst);
-                    }
-
-                    for (int i = 0; i < channels; i++) {
-                        if (sppsm1.getSampleSize(i) != 8) {
-                            return slowFilter(src, dst);
-                        }
-                    }
-
-                    if (channels == 3) {
-                        channels = 4;
-                    }
-
-                    int dataTypeSize = DataBuffer.getDataTypeSize(sppsm1.getDataType()) / 8;
-
-                    srcStride = sppsm1.getScanlineStride() * dataTypeSize;
-                    dstStride = sppsm2.getScanlineStride() * dataTypeSize;
-                } else {
-                    return slowFilter(src, dst);
-                }
-
-                // Fill offsets if there's a child raster
-                if (src.getParent() != null || dst.getParent() != null) {
-                    if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
-                            || dst.getSampleModelTranslateX() != 0
-                            || dst.getSampleModelTranslateY() != 0) {
-                        offsets = new int[4];
-                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
-                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
-                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
-                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
-                    }
-                }
-            }
-        }
-
-        double m00 = at.getScaleX();
-        double m01 = at.getShearX();
-        double m02 = at.getTranslateX();
-        double m10 = at.getShearY();
-        double m11 = at.getScaleY();
-        double m12 = at.getTranslateY();
-
-        Object srcData, dstData;
-        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
-        try {
-            srcData = dbAccess.getData(src.getDataBuffer());
-            dstData = dbAccess.getData(dst.getDataBuffer());
-        } catch (IllegalArgumentException e) {
-            return -1; // Unknown data buffer type
-        }
-
-        return ippAffineTransform(m00, m01, m02, m10, m11, m12, srcData, src.getWidth(), src
-                .getHeight(), srcStride, dstData, dst.getWidth(), dst.getHeight(), dstStride,
-                iType, channels, skipChannel, offsets);
-    }
-
-    /**
-     * Slow filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @return the int.
-     */
-    private int slowFilter(Raster src, WritableRaster dst) {
-        // TODO: make correct interpolation
-        // TODO: what if there are different data types?
-
-        Rectangle srcBounds = src.getBounds();
-        Rectangle dstBounds = dst.getBounds();
-        Rectangle normDstBounds = new Rectangle(0, 0, dstBounds.width, dstBounds.height);
-        Rectangle bounds = getBounds2D(src).getBounds().intersection(normDstBounds);
-
-        AffineTransform inv = null;
-        try {
-            inv = at.createInverse();
-        } catch (NoninvertibleTransformException e) {
-            return -1;
-        }
-
-        double[] m = new double[6];
-        inv.getMatrix(m);
-
-        int minSrcX = srcBounds.x;
-        int minSrcY = srcBounds.y;
-        int maxSrcX = srcBounds.x + srcBounds.width;
-        int maxSrcY = srcBounds.y + srcBounds.height;
-
-        int minX = bounds.x + dstBounds.x;
-        int minY = bounds.y + dstBounds.y;
-        int maxX = minX + bounds.width;
-        int maxY = minY + bounds.height;
-
-        int hx = (int)(m[0] * 256);
-        int hy = (int)(m[1] * 256);
-        int vx = (int)(m[2] * 256);
-        int vy = (int)(m[3] * 256);
-        int sx = (int)(m[4] * 256) + hx * bounds.x + vx * bounds.y + (srcBounds.x) * 256;
-        int sy = (int)(m[5] * 256) + hy * bounds.x + vy * bounds.y + (srcBounds.y) * 256;
-
-        vx -= hx * bounds.width;
-        vy -= hy * bounds.width;
-
-        if (src.getTransferType() == dst.getTransferType()) {
-            for (int y = minY; y < maxY; y++) {
-                for (int x = minX; x < maxX; x++) {
-                    int px = sx >> 8;
-                    int py = sy >> 8;
-                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
-                        Object val = src.getDataElements(px, py, null);
-                        dst.setDataElements(x, y, val);
-                    }
-                    sx += hx;
-                    sy += hy;
-                }
-                sx += vx;
-                sy += vy;
-            }
-        } else {
-            float pixel[] = null;
-            for (int y = minY; y < maxY; y++) {
-                for (int x = minX; x < maxX; x++) {
-                    int px = sx >> 8;
-                    int py = sy >> 8;
-                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
-                        pixel = src.getPixel(px, py, pixel);
-                        dst.setPixel(x, y, pixel);
-                    }
-                    sx += hx;
-                    sy += hy;
-                }
-                sx += vx;
-                sy += vy;
-            }
-        }
-
-        return 0;
-    }
-
-    /**
-     * Ipp affine transform.
-     * 
-     * @param m00
-     *            the m00.
-     * @param m01
-     *            the m01.
-     * @param m02
-     *            the m02.
-     * @param m10
-     *            the m10.
-     * @param m11
-     *            the m11.
-     * @param m12
-     *            the m12.
-     * @param src
-     *            the src.
-     * @param srcWidth
-     *            the src width.
-     * @param srcHeight
-     *            the src height.
-     * @param srcStride
-     *            the src stride.
-     * @param dst
-     *            the dst.
-     * @param dstWidth
-     *            the dst width.
-     * @param dstHeight
-     *            the dst height.
-     * @param dstStride
-     *            the dst stride.
-     * @param iType
-     *            the i type.
-     * @param channels
-     *            the channels.
-     * @param skipChannel
-     *            the skip channel.
-     * @param offsets
-     *            the offsets.
-     * @return the int.
-     */
-    private native int ippAffineTransform(double m00, double m01, double m02, double m10,
-            double m11, double m12, Object src, int srcWidth, int srcHeight, int srcStride,
-            Object dst, int dstWidth, int dstHeight, int dstStride, int iType, int channels,
-            boolean skipChannel, int offsets[]);
-}
\ No newline at end of file
diff --git a/awt/java/awt/image/AreaAveragingScaleFilter.java b/awt/java/awt/image/AreaAveragingScaleFilter.java
deleted file mode 100644
index 7fb138e..0000000
--- a/awt/java/awt/image/AreaAveragingScaleFilter.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.util.Arrays;
-
-/**
- * The AreaAveragingScaleFilter class scales the source image using area
- * averaging algorithm. This algorithm provides a source image with a new image
- * containing the resampled image.
- * 
- * @since Android 1.0
- */
-public class AreaAveragingScaleFilter extends ReplicateScaleFilter {
-
-    /**
-     * The Constant rgbCM.
-     */
-    private static final ColorModel rgbCM = ColorModel.getRGBdefault();
-
-    /**
-     * The Constant averagingFlags.
-     */
-    private static final int averagingFlags = (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES);
-
-    /**
-     * The reset.
-     */
-    private boolean reset = true; // Flag for used superclass filter
-
-    /**
-     * The inited.
-     */
-    private boolean inited = false; // All data inited
-
-    /**
-     * The sum_r.
-     */
-    private int sum_r[]; // Array for average Red samples
-
-    /**
-     * The sum_g.
-     */
-    private int sum_g[]; // Array for average Green samples
-
-    /**
-     * The sum_b.
-     */
-    private int sum_b[]; // Array for average Blue samples
-
-    /**
-     * The sum_a.
-     */
-    private int sum_a[]; // Array for average Alpha samples
-
-    /**
-     * The buff.
-     */
-    private int buff[]; // Stride buffer
-
-    /**
-     * The avg factor.
-     */
-    private int avgFactor; // Global averaging factor
-
-    /**
-     * The cached dy.
-     */
-    private int cachedDY; // Cached number of the destination scanline
-
-    /**
-     * The cached dv rest.
-     */
-    private int cachedDVRest; // Cached value of rest src scanlines for sum
-
-    // pixel samples
-    // Because data if transferring by whole scanlines
-    // we are caching only Y coordinate values
-
-    /**
-     * Instantiates a new AreaAveragingScaleFilter object which scales a source
-     * image with the specified width and height.
-     * 
-     * @param width
-     *            the scaled width of the image.
-     * @param height
-     *            the scaled height of the image.
-     */
-    public AreaAveragingScaleFilter(int width, int height) {
-        super(width, height);
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
-            int scansize) {
-        if (reset) {
-            super.setPixels(x, y, w, h, model, pixels, off, scansize);
-        } else {
-            setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
-        }
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
-            int scansize) {
-        if (reset) {
-            super.setPixels(x, y, w, h, model, pixels, off, scansize);
-        } else {
-            setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
-        }
-    }
-
-    @Override
-    public void setHints(int hints) {
-        super.setHints(hints);
-        reset = ((hints & averagingFlags) != averagingFlags);
-    }
-
-    /**
-     * This method implements the Area Averaging Scale filter. The description
-     * of algorithm is presented in Java API Specification. Arrays sum_r, sum_g,
-     * sum_b, sum_a have length equals width of destination image. In each
-     * array's element is accumulating pixel's component values, proportional to
-     * the area which source pixels will occupy in destination image. Then that
-     * values will divide by Global averaging factor (area of the destination
-     * image) for receiving average values of destination pixels.
-     * 
-     * @param x
-     *            the source pixels X coordinate.
-     * @param y
-     *            the source pixels Y coordinate.
-     * @param w
-     *            the width of the area of the source pixels.
-     * @param h
-     *            the height of the area of the source pixels.
-     * @param model
-     *            the color model of the source pixels.
-     * @param pixels
-     *            the array of source pixels.
-     * @param off
-     *            the offset into the source pixels array.
-     * @param scansize
-     *            the length of scanline in the pixels array.
-     */
-    private void setFilteredPixels(int x, int y, int w, int h, ColorModel model, Object pixels,
-            int off, int scansize) {
-        if (!inited) {
-            initialize();
-        }
-
-        int srcX, srcY, dx, dy;
-        int svRest, dvRest, shRest, dhRest, vDif, hDif;
-
-        if (y == 0) {
-            dy = 0;
-            dvRest = srcHeight;
-        } else {
-            dy = cachedDY;
-            dvRest = cachedDVRest;
-        }
-
-        srcY = y;
-        svRest = destHeight;
-
-        int srcOff = off;
-        while (srcY < y + h) {
-            if (svRest < dvRest) {
-                vDif = svRest;
-            } else {
-                vDif = dvRest;
-            }
-
-            srcX = 0;
-            dx = 0;
-            shRest = destWidth;
-            dhRest = srcWidth;
-            while (srcX < w) {
-                if (shRest < dhRest) {
-                    hDif = shRest;
-                } else {
-                    hDif = dhRest;
-                }
-                int avg = hDif * vDif; // calculation of contribution factor
-
-                int rgb, pix;
-                if (pixels instanceof int[]) {
-                    pix = ((int[])pixels)[srcOff + srcX];
-                } else {
-                    pix = ((byte[])pixels)[srcOff + srcX] & 0xff;
-                }
-
-                rgb = model.getRGB(pix);
-                int a = rgb >>> 24;
-                int r = (rgb >> 16) & 0xff;
-                int g = (rgb >> 8) & 0xff;
-                int b = rgb & 0xff;
-
-                // accumulating pixel's component values
-                sum_a[dx] += a * avg;
-                sum_r[dx] += r * avg;
-                sum_g[dx] += g * avg;
-                sum_b[dx] += b * avg;
-
-                shRest -= hDif;
-                dhRest -= hDif;
-
-                if (shRest == 0) {
-                    srcX++;
-                    shRest = destWidth;
-                }
-
-                if (dhRest == 0) {
-                    dx++;
-                    dhRest = srcWidth;
-                }
-            }
-
-            svRest -= vDif;
-            dvRest -= vDif;
-
-            if (svRest == 0) {
-                svRest = destHeight;
-                srcY++;
-                srcOff += scansize;
-            }
-
-            if (dvRest == 0) {
-                // averaging destination pixel's values
-                for (int i = 0; i < destWidth; i++) {
-                    int a = (sum_a[i] / avgFactor) & 0xff;
-                    int r = (sum_r[i] / avgFactor) & 0xff;
-                    int g = (sum_g[i] / avgFactor) & 0xff;
-                    int b = (sum_b[i] / avgFactor) & 0xff;
-                    int frgb = (a << 24) | (r << 16) | (g << 8) | b;
-                    buff[i] = frgb;
-                }
-                consumer.setPixels(0, dy, destWidth, 1, rgbCM, buff, 0, destWidth);
-                dy++;
-                dvRest = srcHeight;
-                Arrays.fill(sum_a, 0);
-                Arrays.fill(sum_r, 0);
-                Arrays.fill(sum_g, 0);
-                Arrays.fill(sum_b, 0);
-            }
-
-        }
-
-        cachedDY = dy;
-        cachedDVRest = dvRest;
-
-    }
-
-    /**
-     * Initialization of the auxiliary data.
-     */
-    private void initialize() {
-
-        sum_a = new int[destWidth];
-        sum_r = new int[destWidth];
-        sum_g = new int[destWidth];
-        sum_b = new int[destWidth];
-
-        buff = new int[destWidth];
-        outpixbuf = buff;
-        avgFactor = srcWidth * srcHeight;
-
-        inited = true;
-    }
-}
diff --git a/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java b/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java
deleted file mode 100644
index 6dffee8..0000000
--- a/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- * Created on 23.11.2005
- *
- */
-
-package java.awt.image;
-
-import java.awt.Image;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.DataBufferDouble;
-import java.awt.image.DataBufferFloat;
-import java.awt.image.DataBufferInt;
-import java.awt.image.DataBufferShort;
-import java.awt.image.DataBufferUShort;
-
-import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
-import org.apache.harmony.awt.gl.GLVolatileImage;
-import org.apache.harmony.awt.gl.Surface;
-import org.apache.harmony.awt.gl.image.DataBufferListener;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * This class not part of public API. It useful for receiving package private
- * data from other packages.
- * 
- * @since Android 1.0
- */
-class AwtImageBackdoorAccessorImpl extends AwtImageBackdoorAccessor {
-
-    static void init() {
-        inst = new AwtImageBackdoorAccessorImpl();
-    }
-
-    @Override
-    public Surface getImageSurface(Image image) {
-        if (image instanceof BufferedImage) {
-            return ((BufferedImage)image).getImageSurface();
-        } else if (image instanceof GLVolatileImage) {
-            return ((GLVolatileImage)image).getImageSurface();
-        }
-        return null;
-    }
-
-    @Override
-    public boolean isGrayPallete(IndexColorModel icm) {
-        return icm.isGrayPallete();
-    }
-
-    @Override
-    public Object getData(DataBuffer db) {
-        if (db instanceof DataBufferByte) {
-            return ((DataBufferByte)db).getData();
-        } else if (db instanceof DataBufferUShort) {
-            return ((DataBufferUShort)db).getData();
-        } else if (db instanceof DataBufferShort) {
-            return ((DataBufferShort)db).getData();
-        } else if (db instanceof DataBufferInt) {
-            return ((DataBufferInt)db).getData();
-        } else if (db instanceof DataBufferFloat) {
-            return ((DataBufferFloat)db).getData();
-        } else if (db instanceof DataBufferDouble) {
-            return ((DataBufferDouble)db).getData();
-        } else {
-            // awt.235=Wrong Data Buffer type : {0}
-            throw new IllegalArgumentException(Messages.getString("awt.235", //$NON-NLS-1$
-                    db.getClass()));
-        }
-    }
-
-    @Override
-    public int[] getDataInt(DataBuffer db) {
-        if (db instanceof DataBufferInt) {
-            return ((DataBufferInt)db).getData();
-        }
-        return null;
-    }
-
-    @Override
-    public byte[] getDataByte(DataBuffer db) {
-        if (db instanceof DataBufferByte) {
-            return ((DataBufferByte)db).getData();
-        }
-        return null;
-    }
-
-    @Override
-    public short[] getDataShort(DataBuffer db) {
-        if (db instanceof DataBufferShort) {
-            return ((DataBufferShort)db).getData();
-        }
-        return null;
-    }
-
-    @Override
-    public short[] getDataUShort(DataBuffer db) {
-        if (db instanceof DataBufferUShort) {
-            return ((DataBufferUShort)db).getData();
-        }
-        return null;
-    }
-
-    @Override
-    public double[] getDataDouble(DataBuffer db) {
-        if (db instanceof DataBufferDouble) {
-            return ((DataBufferDouble)db).getData();
-        }
-        return null;
-    }
-
-    @Override
-    public float[] getDataFloat(DataBuffer db) {
-        if (db instanceof DataBufferFloat) {
-            return ((DataBufferFloat)db).getData();
-        }
-        return null;
-    }
-
-    @Override
-    public void addDataBufferListener(DataBuffer db, DataBufferListener listener) {
-        db.addDataBufferListener(listener);
-    }
-
-    @Override
-    public void removeDataBufferListener(DataBuffer db) {
-        db.removeDataBufferListener();
-    }
-
-    @Override
-    public void validate(DataBuffer db) {
-        db.validate();
-    }
-
-    @Override
-    public void releaseData(DataBuffer db) {
-        db.releaseData();
-    }
-}
diff --git a/awt/java/awt/image/BandCombineOp.java b/awt/java/awt/image/BandCombineOp.java
deleted file mode 100644
index da2cc894..0000000
--- a/awt/java/awt/image/BandCombineOp.java
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Sep 20, 2005
- */
-
-package java.awt.image;
-
-import java.awt.*;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.util.Arrays;
-
-import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The BandCombineOp class translates coordinates from coordinates in the source
- * Raster to coordinates in the destination Raster by an arbitrary linear
- * combination of the bands in a source Raster, using a specified matrix. The
- * number of bands in the matrix should equal to the number of bands in the
- * source Raster plus 1.
- * 
- * @since Android 1.0
- */
-public class BandCombineOp implements RasterOp {
-
-    /**
-     * The Constant offsets3c.
-     */
-    static final int offsets3c[] = {
-            16, 8, 0
-    };
-
-    /**
-     * The Constant offsets4ac.
-     */
-    static final int offsets4ac[] = {
-            16, 8, 0, 24
-    };
-
-    /**
-     * The Constant masks3c.
-     */
-    static final int masks3c[] = {
-            0xFF0000, 0xFF00, 0xFF
-    };
-
-    /**
-     * The Constant masks4ac.
-     */
-    static final int masks4ac[] = {
-            0xFF0000, 0xFF00, 0xFF, 0xFF000000
-    };
-
-    /**
-     * The Constant piOffsets.
-     */
-    private static final int piOffsets[] = {
-            0, 1, 2
-    };
-
-    /**
-     * The Constant piInvOffsets.
-     */
-    private static final int piInvOffsets[] = {
-            2, 1, 0
-    };
-
-    /**
-     * The Constant TYPE_BYTE3C.
-     */
-    private static final int TYPE_BYTE3C = 0;
-
-    /**
-     * The Constant TYPE_BYTE4AC.
-     */
-    private static final int TYPE_BYTE4AC = 1;
-
-    /**
-     * The Constant TYPE_USHORT3C.
-     */
-    private static final int TYPE_USHORT3C = 2;
-
-    /**
-     * The Constant TYPE_SHORT3C.
-     */
-    private static final int TYPE_SHORT3C = 3;
-
-    /**
-     * The mx width.
-     */
-    private int mxWidth;
-
-    /**
-     * The mx height.
-     */
-    private int mxHeight;
-
-    /**
-     * The matrix.
-     */
-    private float matrix[][];
-
-    /**
-     * The r hints.
-     */
-    private RenderingHints rHints;
-
-    static {
-        // XXX - todo
-        // System.loadLibrary("imageops");
-    }
-
-    /**
-     * Instantiates a new BandCombineOp object with the specified matrix.
-     * 
-     * @param matrix
-     *            the specified matrix for band combining.
-     * @param hints
-     *            the RenderingHints.
-     */
-    public BandCombineOp(float matrix[][], RenderingHints hints) {
-        this.mxHeight = matrix.length;
-        this.mxWidth = matrix[0].length;
-        this.matrix = new float[mxHeight][mxWidth];
-
-        for (int i = 0; i < mxHeight; i++) {
-            System.arraycopy(matrix[i], 0, this.matrix[i], 0, mxWidth);
-        }
-
-        this.rHints = hints;
-    }
-
-    public final RenderingHints getRenderingHints() {
-        return this.rHints;
-    }
-
-    /**
-     * Gets the matrix associated with this BandCombineOp object.
-     * 
-     * @return the matrix associated with this BandCombineOp object.
-     */
-    public final float[][] getMatrix() {
-        float res[][] = new float[mxHeight][mxWidth];
-
-        for (int i = 0; i < mxHeight; i++) {
-            System.arraycopy(matrix[i], 0, res[i], 0, mxWidth);
-        }
-
-        return res;
-    }
-
-    public final Point2D getPoint2D(Point2D srcPoint, Point2D dstPoint) {
-        if (dstPoint == null) {
-            dstPoint = new Point2D.Float();
-        }
-
-        dstPoint.setLocation(srcPoint);
-        return dstPoint;
-    }
-
-    public final Rectangle2D getBounds2D(Raster src) {
-        return src.getBounds();
-    }
-
-    public WritableRaster createCompatibleDestRaster(Raster src) {
-        int numBands = src.getNumBands();
-        if (mxWidth != numBands && mxWidth != (numBands + 1) || numBands != mxHeight) {
-            // awt.254=Number of bands in the source raster ({0}) is
-            // incompatible with the matrix [{1}x{2}]
-            throw new IllegalArgumentException(Messages.getString("awt.254", //$NON-NLS-1$
-                    new Object[] {
-                            numBands, mxWidth, mxHeight
-                    }));
-        }
-
-        return src.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
-    }
-
-    public WritableRaster filter(Raster src, WritableRaster dst) {
-        int numBands = src.getNumBands();
-
-        if (mxWidth != numBands && mxWidth != (numBands + 1)) {
-            // awt.254=Number of bands in the source raster ({0}) is
-            // incompatible with the matrix [{1}x{2}]
-            throw new IllegalArgumentException(Messages.getString("awt.254", //$NON-NLS-1$
-                    new Object[] {
-                            numBands, mxWidth, mxHeight
-                    }));
-        }
-
-        if (dst == null) {
-            dst = createCompatibleDestRaster(src);
-        } else if (dst.getNumBands() != mxHeight) {
-            // awt.255=Number of bands in the destination raster ({0}) is
-            // incompatible with the matrix [{1}x{2}]
-            throw new IllegalArgumentException(Messages.getString("awt.255", //$NON-NLS-1$
-                    new Object[] {
-                            dst.getNumBands(), mxWidth, mxHeight
-                    }));
-        }
-
-        // XXX - todo
-        // if (ippFilter(src, dst) != 0)
-        if (verySlowFilter(src, dst) != 0) {
-            // awt.21F=Unable to transform source
-            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
-        }
-
-        return dst;
-    }
-
-    /**
-     * The Class SampleModelInfo.
-     */
-    private static final class SampleModelInfo {
-
-        /**
-         * The channels.
-         */
-        int channels;
-
-        /**
-         * The channels order.
-         */
-        int channelsOrder[];
-
-        /**
-         * The stride.
-         */
-        int stride;
-    }
-
-    /**
-     * Check sample model.
-     * 
-     * @param sm
-     *            the sm.
-     * @return the sample model info.
-     */
-    private final SampleModelInfo checkSampleModel(SampleModel sm) {
-        SampleModelInfo ret = new SampleModelInfo();
-
-        if (sm instanceof PixelInterleavedSampleModel) {
-            // Check PixelInterleavedSampleModel
-            if (sm.getDataType() != DataBuffer.TYPE_BYTE) {
-                return null;
-            }
-
-            ret.channels = sm.getNumBands();
-            ret.stride = ((ComponentSampleModel)sm).getScanlineStride();
-            ret.channelsOrder = ((ComponentSampleModel)sm).getBandOffsets();
-
-        } else if (sm instanceof SinglePixelPackedSampleModel) {
-            // Check SinglePixelPackedSampleModel
-            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)sm;
-
-            ret.channels = sppsm1.getNumBands();
-            if (sppsm1.getDataType() != DataBuffer.TYPE_INT) {
-                return null;
-            }
-
-            // Check sample models
-            for (int i = 0; i < ret.channels; i++) {
-                if (sppsm1.getSampleSize(i) != 8) {
-                    return null;
-                }
-            }
-
-            ret.channelsOrder = new int[ret.channels];
-            int bitOffsets[] = sppsm1.getBitOffsets();
-            for (int i = 0; i < ret.channels; i++) {
-                if (bitOffsets[i] % 8 != 0) {
-                    return null;
-                }
-
-                ret.channelsOrder[i] = bitOffsets[i] / 8;
-            }
-
-            ret.channels = 4;
-            ret.stride = sppsm1.getScanlineStride() * 4;
-        } else {
-            return null;
-        }
-
-        return ret;
-    }
-
-    /**
-     * Slow filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @return the int.
-     */
-    private final int slowFilter(Raster src, WritableRaster dst) {
-        int res = 0;
-
-        SampleModelInfo srcInfo, dstInfo;
-        int offsets[] = null;
-
-        srcInfo = checkSampleModel(src.getSampleModel());
-        dstInfo = checkSampleModel(dst.getSampleModel());
-        if (srcInfo == null || dstInfo == null) {
-            return verySlowFilter(src, dst);
-        }
-
-        // Fill offsets if there's a child raster
-        if (src.getParent() != null || dst.getParent() != null) {
-            if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
-                    || dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) {
-                offsets = new int[4];
-                offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
-                offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
-                offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
-                offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
-            }
-        }
-
-        int rmxWidth = (srcInfo.channels + 1); // width of the reordered matrix
-        float reorderedMatrix[] = new float[rmxWidth * dstInfo.channels];
-        for (int j = 0; j < dstInfo.channels; j++) {
-            if (j >= dstInfo.channelsOrder.length) {
-                continue;
-            }
-
-            for (int i = 0; i < srcInfo.channels; i++) {
-                if (i >= srcInfo.channelsOrder.length) {
-                    break;
-                }
-
-                reorderedMatrix[dstInfo.channelsOrder[j] * rmxWidth + srcInfo.channelsOrder[i]] = matrix[j][i];
-            }
-            if (mxWidth == rmxWidth) {
-                reorderedMatrix[(dstInfo.channelsOrder[j] + 1) * rmxWidth - 1] = matrix[j][mxWidth - 1];
-            }
-        }
-
-        Object srcData, dstData;
-        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
-        try {
-            srcData = dbAccess.getData(src.getDataBuffer());
-            dstData = dbAccess.getData(dst.getDataBuffer());
-        } catch (IllegalArgumentException e) {
-            return -1; // Unknown data buffer type
-        }
-
-        simpleCombineBands(srcData, src.getWidth(), src.getHeight(), srcInfo.stride,
-                srcInfo.channels, dstData, dstInfo.stride, dstInfo.channels, reorderedMatrix,
-                offsets);
-
-        return res;
-    }
-
-    /**
-     * Very slow filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @return the int.
-     */
-    private int verySlowFilter(Raster src, WritableRaster dst) {
-        int numBands = src.getNumBands();
-
-        int srcMinX = src.getMinX();
-        int srcY = src.getMinY();
-
-        int dstMinX = dst.getMinX();
-        int dstY = dst.getMinY();
-
-        int dX = src.getWidth();// < dst.getWidth() ? src.getWidth() :
-        // dst.getWidth();
-        int dY = src.getHeight();// < dst.getHeight() ? src.getHeight() :
-        // dst.getHeight();
-
-        float sample;
-        int srcPixels[] = new int[numBands * dX * dY];
-        int dstPixels[] = new int[mxHeight * dX * dY];
-
-        srcPixels = src.getPixels(srcMinX, srcY, dX, dY, srcPixels);
-
-        if (numBands == mxWidth) {
-            for (int i = 0, j = 0; i < srcPixels.length; i += numBands) {
-                for (int dstB = 0; dstB < mxHeight; dstB++) {
-                    sample = 0f;
-                    for (int srcB = 0; srcB < numBands; srcB++) {
-                        sample += matrix[dstB][srcB] * srcPixels[i + srcB];
-                    }
-                    dstPixels[j++] = (int)sample;
-                }
-            }
-        } else {
-            for (int i = 0, j = 0; i < srcPixels.length; i += numBands) {
-                for (int dstB = 0; dstB < mxHeight; dstB++) {
-                    sample = 0f;
-                    for (int srcB = 0; srcB < numBands; srcB++) {
-                        sample += matrix[dstB][srcB] * srcPixels[i + srcB];
-                    }
-                    dstPixels[j++] = (int)(sample + matrix[dstB][numBands]);
-                }
-            }
-        }
-
-        dst.setPixels(dstMinX, dstY, dX, dY, dstPixels);
-
-        return 0;
-    }
-
-    // TODO remove when method is used
-    /**
-     * Ipp filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @return the int.
-     */
-    @SuppressWarnings("unused")
-    private int ippFilter(Raster src, WritableRaster dst) {
-        boolean invertChannels;
-        boolean inPlace = (src == dst);
-        int type;
-        int srcStride, dstStride;
-        int offsets[] = null;
-
-        int srcBands = src.getNumBands();
-        int dstBands = dst.getNumBands();
-
-        if (dstBands != 3
-                || (srcBands != 3 && !(srcBands == 4 && matrix[0][3] == 0 && matrix[1][3] == 0 && matrix[2][3] == 0))) {
-            return slowFilter(src, dst);
-        }
-
-        SampleModel srcSM = src.getSampleModel();
-        SampleModel dstSM = dst.getSampleModel();
-
-        if (srcSM instanceof SinglePixelPackedSampleModel
-                && dstSM instanceof SinglePixelPackedSampleModel) {
-            // Check SinglePixelPackedSampleModel
-            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)srcSM;
-            SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel)dstSM;
-
-            if (sppsm1.getDataType() != DataBuffer.TYPE_INT
-                    || sppsm2.getDataType() != DataBuffer.TYPE_INT) {
-                return slowFilter(src, dst);
-            }
-
-            // Check sample models
-            if (!Arrays.equals(sppsm2.getBitOffsets(), offsets3c)
-                    || !Arrays.equals(sppsm2.getBitMasks(), masks3c)) {
-                return slowFilter(src, dst);
-            }
-
-            if (srcBands == 3) {
-                if (!Arrays.equals(sppsm1.getBitOffsets(), offsets3c)
-                        || !Arrays.equals(sppsm1.getBitMasks(), masks3c)) {
-                    return slowFilter(src, dst);
-                }
-            } else if (srcBands == 4) {
-                if (!Arrays.equals(sppsm1.getBitOffsets(), offsets4ac)
-                        || !Arrays.equals(sppsm1.getBitMasks(), masks4ac)) {
-                    return slowFilter(src, dst);
-                }
-            }
-
-            type = TYPE_BYTE4AC;
-            invertChannels = true;
-
-            srcStride = sppsm1.getScanlineStride() * 4;
-            dstStride = sppsm2.getScanlineStride() * 4;
-        } else if (srcSM instanceof PixelInterleavedSampleModel
-                && dstSM instanceof PixelInterleavedSampleModel) {
-            if (srcBands != 3) {
-                return slowFilter(src, dst);
-            }
-
-            int srcDataType = srcSM.getDataType();
-
-            switch (srcDataType) {
-                case DataBuffer.TYPE_BYTE:
-                    type = TYPE_BYTE3C;
-                    break;
-                case DataBuffer.TYPE_USHORT:
-                    type = TYPE_USHORT3C;
-                    break;
-                case DataBuffer.TYPE_SHORT:
-                    type = TYPE_SHORT3C;
-                    break;
-                default:
-                    return slowFilter(src, dst);
-            }
-
-            // Check PixelInterleavedSampleModel
-            PixelInterleavedSampleModel pism1 = (PixelInterleavedSampleModel)srcSM;
-            PixelInterleavedSampleModel pism2 = (PixelInterleavedSampleModel)dstSM;
-
-            if (srcDataType != pism2.getDataType() || pism1.getPixelStride() != 3
-                    || pism2.getPixelStride() != 3
-                    || !Arrays.equals(pism1.getBandOffsets(), pism2.getBandOffsets())) {
-                return slowFilter(src, dst);
-            }
-
-            if (Arrays.equals(pism1.getBandOffsets(), piInvOffsets)) {
-                invertChannels = true;
-            } else if (Arrays.equals(pism1.getBandOffsets(), piOffsets)) {
-                invertChannels = false;
-            } else {
-                return slowFilter(src, dst);
-            }
-
-            int dataTypeSize = DataBuffer.getDataTypeSize(srcDataType) / 8;
-
-            srcStride = pism1.getScanlineStride() * dataTypeSize;
-            dstStride = pism2.getScanlineStride() * dataTypeSize;
-        } else { // XXX - todo - IPP allows support for planar data also
-            return slowFilter(src, dst);
-        }
-
-        // Fill offsets if there's a child raster
-        if (src.getParent() != null || dst.getParent() != null) {
-            if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
-                    || dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) {
-                offsets = new int[4];
-                offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
-                offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
-                offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
-                offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
-            }
-        }
-
-        Object srcData, dstData;
-        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
-        try {
-            srcData = dbAccess.getData(src.getDataBuffer());
-            dstData = dbAccess.getData(dst.getDataBuffer());
-        } catch (IllegalArgumentException e) {
-            return -1; // Unknown data buffer type
-        }
-
-        float ippMatrix[] = new float[12];
-
-        if (invertChannels) {
-            // IPP treats big endian integers like BGR, so we have to
-            // swap columns 1 and 3 and rows 1 and 3
-            for (int i = 0; i < mxHeight; i++) {
-                ippMatrix[i * 4] = matrix[2 - i][2];
-                ippMatrix[i * 4 + 1] = matrix[2 - i][1];
-                ippMatrix[i * 4 + 2] = matrix[2 - i][0];
-
-                if (mxWidth == 4) {
-                    ippMatrix[i * 4 + 3] = matrix[2 - i][3];
-                } else if (mxWidth == 5) {
-                    ippMatrix[i * 4 + 3] = matrix[2 - i][4];
-                }
-            }
-        } else {
-            for (int i = 0; i < mxHeight; i++) {
-                ippMatrix[i * 4] = matrix[i][0];
-                ippMatrix[i * 4 + 1] = matrix[i][1];
-                ippMatrix[i * 4 + 2] = matrix[i][2];
-
-                if (mxWidth == 4) {
-                    ippMatrix[i * 4 + 3] = matrix[i][3];
-                } else if (mxWidth == 5) {
-                    ippMatrix[i * 4 + 3] = matrix[i][4];
-                }
-            }
-        }
-
-        return ippColorTwist(srcData, src.getWidth(), src.getHeight(), srcStride, dstData, dst
-                .getWidth(), dst.getHeight(), dstStride, ippMatrix, type, offsets, inPlace);
-    }
-
-    /**
-     * Ipp color twist.
-     * 
-     * @param srcData
-     *            the src data.
-     * @param srcWidth
-     *            the src width.
-     * @param srcHeight
-     *            the src height.
-     * @param srcStride
-     *            the src stride.
-     * @param dstData
-     *            the dst data.
-     * @param dstWidth
-     *            the dst width.
-     * @param dstHeight
-     *            the dst height.
-     * @param dstStride
-     *            the dst stride.
-     * @param ippMatrix
-     *            the ipp matrix.
-     * @param type
-     *            the type.
-     * @param offsets
-     *            the offsets.
-     * @param inPlace
-     *            the in place.
-     * @return the int.
-     */
-    private final native int ippColorTwist(Object srcData, int srcWidth, int srcHeight,
-            int srcStride, Object dstData, int dstWidth, int dstHeight, int dstStride,
-            float ippMatrix[], int type, int offsets[], boolean inPlace);
-
-    /**
-     * Simple combine bands.
-     * 
-     * @param srcData
-     *            the src data.
-     * @param srcWidth
-     *            the src width.
-     * @param srcHeight
-     *            the src height.
-     * @param srcStride
-     *            the src stride.
-     * @param srcChannels
-     *            the src channels.
-     * @param dstData
-     *            the dst data.
-     * @param dstStride
-     *            the dst stride.
-     * @param dstChannels
-     *            the dst channels.
-     * @param m
-     *            the m.
-     * @param offsets
-     *            the offsets.
-     * @return the int.
-     */
-    private final native int simpleCombineBands(Object srcData, int srcWidth, int srcHeight,
-            int srcStride, int srcChannels, Object dstData, int dstStride, int dstChannels,
-            float m[], int offsets[]);
-}
diff --git a/awt/java/awt/image/BandedSampleModel.java b/awt/java/awt/image/BandedSampleModel.java
deleted file mode 100644
index 0aa30d7..0000000
--- a/awt/java/awt/image/BandedSampleModel.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The BandedSampleModel class provides samples of pixels in an image which is
- * stored in a band interleaved method. Each pixel's sample takes one data
- * element of the DataBuffer. The pixel stride for a BandedSampleModel is one.
- * 
- * @since Android 1.0
- */
-public final class BandedSampleModel extends ComponentSampleModel {
-
-    /**
-     * Creates the indices.
-     * 
-     * @param numBands
-     *            the num bands.
-     * @return the int[].
-     */
-    private static int[] createIndices(int numBands) {
-        int indices[] = new int[numBands];
-        for (int i = 0; i < numBands; i++) {
-            indices[i] = i;
-        }
-        return indices;
-    }
-
-    /**
-     * Creates the offsets.
-     * 
-     * @param numBands
-     *            the num bands.
-     * @return the int[].
-     */
-    private static int[] createOffsets(int numBands) {
-        int offsets[] = new int[numBands];
-        for (int i = 0; i < numBands; i++) {
-            offsets[i] = 0;
-        }
-        return offsets;
-    }
-
-    /**
-     * Instantiates a new BandedSampleModel object with the specified data type
-     * of samples, the width, height and bands number of image data.
-     * 
-     * @param dataType
-     *            the data type of samples.
-     * @param w
-     *            the width of image data.
-     * @param h
-     *            the height of image data.
-     * @param numBands
-     *            the number of bands.
-     */
-    public BandedSampleModel(int dataType, int w, int h, int numBands) {
-        this(dataType, w, h, w, BandedSampleModel.createIndices(numBands), BandedSampleModel
-                .createOffsets(numBands));
-    }
-
-    /**
-     * Instantiates a new BandedSampleModel object with the specified data type
-     * of samples, the width, height and bands number of image data.
-     * 
-     * @param dataType
-     *            the data type of samples.
-     * @param w
-     *            the width of image data.
-     * @param h
-     *            the height of image data.
-     * @param scanlineStride
-     *            the scanline stride of the of the image data.
-     * @param bankIndices
-     *            the array of the bank indices.
-     * @param bandOffsets
-     *            the array of the band offsets.
-     */
-    public BandedSampleModel(int dataType, int w, int h, int scanlineStride, int bankIndices[],
-            int bandOffsets[]) {
-        super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
-    }
-
-    @Override
-    public SampleModel createCompatibleSampleModel(int w, int h) {
-        return new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffsets);
-    }
-
-    @Override
-    public DataBuffer createDataBuffer() {
-        DataBuffer data = null;
-        int size = scanlineStride * height;
-
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE:
-                data = new DataBufferByte(size, numBanks);
-                break;
-            case DataBuffer.TYPE_SHORT:
-            case DataBuffer.TYPE_USHORT:
-                data = new DataBufferShort(size, numBanks);
-                break;
-            case DataBuffer.TYPE_INT:
-                data = new DataBufferInt(size, numBanks);
-                break;
-            case DataBuffer.TYPE_FLOAT:
-                data = new DataBufferFloat(size, numBanks);
-                break;
-            case DataBuffer.TYPE_DOUBLE:
-                data = new DataBufferDouble(size, numBanks);
-                break;
-        }
-
-        return data;
-
-    }
-
-    @Override
-    public SampleModel createSubsetSampleModel(int[] bands) {
-        if (bands.length > numBands) {
-            // awt.64=The number of the bands in the subset is greater than the
-            // number of bands in the sample model
-            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
-        }
-
-        int indices[] = new int[bands.length];
-        int offsets[] = new int[bands.length];
-
-        for (int i = 0; i < bands.length; i++) {
-            indices[i] = bankIndices[bands[i]];
-            offsets[i] = bandOffsets[bands[i]];
-        }
-
-        return new BandedSampleModel(dataType, width, height, scanlineStride, indices, offsets);
-    }
-
-    @Override
-    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE: {
-                byte bdata[];
-
-                if (obj == null) {
-                    bdata = new byte[numBands];
-                } else {
-                    bdata = (byte[])obj;
-                }
-
-                for (int i = 0; i < numBands; i++) {
-                    bdata[i] = (byte)getSample(x, y, i, data);
-                }
-
-                obj = bdata;
-                break;
-            }
-            case DataBuffer.TYPE_SHORT:
-            case DataBuffer.TYPE_USHORT: {
-                short sdata[];
-
-                if (obj == null) {
-                    sdata = new short[numBands];
-                } else {
-                    sdata = (short[])obj;
-                }
-
-                for (int i = 0; i < numBands; i++) {
-                    sdata[i] = (short)getSample(x, y, i, data);
-                }
-
-                obj = sdata;
-                break;
-            }
-            case DataBuffer.TYPE_INT: {
-                int idata[];
-
-                if (obj == null) {
-                    idata = new int[numBands];
-                } else {
-                    idata = (int[])obj;
-                }
-
-                for (int i = 0; i < numBands; i++) {
-                    idata[i] = getSample(x, y, i, data);
-                }
-
-                obj = idata;
-                break;
-            }
-            case DataBuffer.TYPE_FLOAT: {
-                float fdata[];
-
-                if (obj == null) {
-                    fdata = new float[numBands];
-                } else {
-                    fdata = (float[])obj;
-                }
-
-                for (int i = 0; i < numBands; i++) {
-                    fdata[i] = getSampleFloat(x, y, i, data);
-                }
-
-                obj = fdata;
-                break;
-            }
-            case DataBuffer.TYPE_DOUBLE: {
-                double ddata[];
-
-                if (obj == null) {
-                    ddata = new double[numBands];
-                } else {
-                    ddata = (double[])obj;
-                }
-
-                for (int i = 0; i < numBands; i++) {
-                    ddata[i] = getSampleDouble(x, y, i, data);
-                }
-
-                obj = ddata;
-                break;
-            }
-        }
-
-        return obj;
-    }
-
-    @Override
-    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
-        int pixel[];
-        if (iArray == null) {
-            pixel = new int[numBands];
-        } else {
-            pixel = iArray;
-        }
-
-        for (int i = 0; i < numBands; i++) {
-            pixel[i] = getSample(x, y, i, data);
-        }
-
-        return pixel;
-    }
-
-    @Override
-    public int getSample(int x, int y, int b, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        return data.getElem(bankIndices[b], y * scanlineStride + x + bandOffsets[b]);
-    }
-
-    @Override
-    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        return data.getElemDouble(bankIndices[b], y * scanlineStride + x + bandOffsets[b]);
-    }
-
-    @Override
-    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        return data.getElemFloat(bankIndices[b], y * scanlineStride + x + bandOffsets[b]);
-    }
-
-    @Override
-    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
-        int samples[];
-        int idx = 0;
-
-        if (iArray == null) {
-            samples = new int[w * h];
-        } else {
-            samples = iArray;
-        }
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                samples[idx++] = getSample(j, i, b, data);
-            }
-        }
-
-        return samples;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = super.hashCode();
-        int tmp = hash >>> 8;
-        hash <<= 8;
-        hash |= tmp;
-
-        return hash ^ 0x55;
-    }
-
-    @Override
-    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE:
-                byte bdata[] = (byte[])obj;
-                for (int i = 0; i < numBands; i++) {
-                    setSample(x, y, i, bdata[i] & 0xff, data);
-                }
-                break;
-
-            case DataBuffer.TYPE_SHORT:
-            case DataBuffer.TYPE_USHORT:
-                short sdata[] = (short[])obj;
-                for (int i = 0; i < numBands; i++) {
-                    setSample(x, y, i, sdata[i] & 0xffff, data);
-                }
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int idata[] = (int[])obj;
-                for (int i = 0; i < numBands; i++) {
-                    setSample(x, y, i, idata[i], data);
-                }
-                break;
-
-            case DataBuffer.TYPE_FLOAT:
-                float fdata[] = (float[])obj;
-                for (int i = 0; i < numBands; i++) {
-                    setSample(x, y, i, fdata[i], data);
-                }
-                break;
-
-            case DataBuffer.TYPE_DOUBLE:
-                double ddata[] = (double[])obj;
-                for (int i = 0; i < numBands; i++) {
-                    setSample(x, y, i, ddata[i], data);
-                }
-                break;
-        }
-    }
-
-    @Override
-    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
-        for (int i = 0; i < numBands; i++) {
-            setSample(x, y, i, iArray[i], data);
-        }
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
-        int idx = 0;
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < numBands; n++) {
-                    setSample(j, i, n, iArray[idx++], data);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, double s, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        data.setElemDouble(bankIndices[b], y * scanlineStride + x + bandOffsets[b], s);
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, float s, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        data.setElemFloat(bankIndices[b], y * scanlineStride + x + bandOffsets[b], s);
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, int s, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        data.setElem(bankIndices[b], y * scanlineStride + x + bandOffsets[b], s);
-    }
-
-    @Override
-    public void setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
-        int idx = 0;
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                setSample(j, i, b, iArray[idx++], data);
-            }
-        }
-
-    }
-
-}
diff --git a/awt/java/awt/image/BufferStrategy.java b/awt/java/awt/image/BufferStrategy.java
deleted file mode 100644
index 3c8779d..0000000
--- a/awt/java/awt/image/BufferStrategy.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.BufferCapabilities;
-import java.awt.Graphics;
-
-/**
- * The BufferStrategy abstract class provides an opportunity to organize the
- * buffers for a Canvas or Window. The BufferStrategy implementation depends on
- * hardware and software limitations. These limitations are detectable through
- * the capabilities object which can be obtained by the GraphicsConfiguration of
- * the Canvas or Window.
- * 
- * @since Android 1.0
- */
-public abstract class BufferStrategy {
-
-    /**
-     * Returns true if the drawing buffer was lost since the last call of
-     * getDrawGraphics.
-     * 
-     * @return true if the drawing buffer was lost since the last call of
-     *         getDrawGraphics, false otherwise.
-     */
-    public abstract boolean contentsLost();
-
-    /**
-     * Returns true if the drawing buffer is restored from a lost state.
-     * 
-     * @return true if the drawing buffer is restored from a lost state, false
-     *         otherwise.
-     */
-    public abstract boolean contentsRestored();
-
-    /**
-     * Gets the BufferCapabilities of BufferStrategy.
-     * 
-     * @return the BufferCapabilities of BufferStrategy.
-     */
-    public abstract BufferCapabilities getCapabilities();
-
-    /**
-     * Gets the Graphics object to use to draw to the buffer.
-     * 
-     * @return the Graphics object to use to draw to the buffer.
-     */
-    public abstract Graphics getDrawGraphics();
-
-    /**
-     * Shows the next available buffer.
-     */
-    public abstract void show();
-
-}
diff --git a/awt/java/awt/image/BufferedImage.java b/awt/java/awt/image/BufferedImage.java
deleted file mode 100644
index c9d58d9..0000000
--- a/awt/java/awt/image/BufferedImage.java
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import com.android.internal.awt.AndroidGraphics2D;
-
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.GraphicsEnvironment;
-import java.awt.Image;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
-
-import org.apache.harmony.awt.gl.ImageSurface;
-import org.apache.harmony.awt.gl.Surface;
-import org.apache.harmony.awt.gl.image.BufferedImageSource;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The BufferedImage class describes an Image which contains a buffer of image
- * data and includes a ColorModel and a Raster for this data. This class
- * provides methods for obtaining and setting the Raster and for manipulating
- * the ColorModel parameters.
- * 
- * @since Android 1.0
- */
-public class BufferedImage extends Image implements WritableRenderedImage, Transparency {
-
-    /**
-     * The Constant TYPE_CUSTOM indicates that Image type is unknown.
-     */
-    public static final int TYPE_CUSTOM = 0;
-
-    /**
-     * The Constant TYPE_INT_RGB indicates an image with 8 bit RGB color
-     * components, it has a DirectColorModel without alpha.
-     */
-    public static final int TYPE_INT_RGB = 1;
-
-    /**
-     * The Constant TYPE_INT_ARGB indicates an image with 8 bit RGBA color
-     * components, it has a DirectColorModel with alpha.
-     */
-    public static final int TYPE_INT_ARGB = 2;
-
-    /**
-     * The Constant TYPE_INT_ARGB_PRE indicates an image with 8 bit RGBA color
-     * components, it has a DirectColorModel with alpha, and image data is
-     * pre-multiplied by alpha.
-     */
-    public static final int TYPE_INT_ARGB_PRE = 3;
-
-    /**
-     * The Constant TYPE_INT_BGR indicates an image with 8 bit RGB color
-     * components, BGR color model (with the colors Blue, Green, and Red). There
-     * is no alpha. The image has a DirectColorModel.
-     */
-    public static final int TYPE_INT_BGR = 4;
-
-    /**
-     * The Constant TYPE_3BYTE_BGR indicates an image with 8 bit RGB color
-     * components, BGR color model (with the colors Blue, Green, and Red stored
-     * in 3 bytes). There is no alpha. The image has a ComponentColorModel.
-     */
-    public static final int TYPE_3BYTE_BGR = 5;
-
-    /**
-     * The Constant TYPE_4BYTE_ABGR indicates an image with 8 bit RGBA color
-     * components stored in 3 bytes and 1 byte of alpha. It has a
-     * ComponentColorModel with alpha.
-     */
-    public static final int TYPE_4BYTE_ABGR = 6;
-
-    /**
-     * The Constant TYPE_4BYTE_ABGR_PRE indicates an image with 8 bit RGBA color
-     * components stored in 3 bytes and 1 byte for alpha. The image has a
-     * ComponentColorModel with alpha. The color data is pre-multiplied with
-     * alpha.
-     */
-    public static final int TYPE_4BYTE_ABGR_PRE = 7;
-
-    /**
-     * The Constant TYPE_USHORT_565_RGB indicates an image with 565 RGB color
-     * components (5-bits red, 6-bits green, 5-bits blue) with no alpha. This
-     * image has a DirectColorModel.
-     */
-    public static final int TYPE_USHORT_565_RGB = 8;
-
-    /**
-     * The Constant TYPE_USHORT_555_RGB indicates an image with 555 RGB color
-     * components (5-bits red, 5-bits green, 5-bits blue) with no alpha. This
-     * image has a DirectColorModel.
-     */
-    public static final int TYPE_USHORT_555_RGB = 9;
-
-    /**
-     * The Constant TYPE_BYTE_GRAY indicates a unsigned byte image. This image
-     * has a ComponentColorModel with a CS_GRAY ColorSpace.
-     */
-    public static final int TYPE_BYTE_GRAY = 10;
-
-    /**
-     * The Constant TYPE_USHORT_GRAY indicates an unsigned short image. This
-     * image has a ComponentColorModel with a CS_GRAY ColorSpace.
-     */
-    public static final int TYPE_USHORT_GRAY = 11;
-
-    /**
-     * The Constant TYPE_BYTE_BINARY indicates an opaque byte-packed 1, 2 or 4
-     * bit image. The image has an IndexColorModel without alpha.
-     */
-    public static final int TYPE_BYTE_BINARY = 12;
-
-    /**
-     * The Constant TYPE_BYTE_INDEXED indicates an indexed byte image.
-     */
-    public static final int TYPE_BYTE_INDEXED = 13;
-
-    /**
-     * The Constant ALPHA_MASK.
-     */
-    private static final int ALPHA_MASK = 0xff000000;
-
-    /**
-     * The Constant RED_MASK.
-     */
-    private static final int RED_MASK = 0x00ff0000;
-
-    /**
-     * The Constant GREEN_MASK.
-     */
-    private static final int GREEN_MASK = 0x0000ff00;
-
-    /**
-     * The Constant BLUE_MASK.
-     */
-    private static final int BLUE_MASK = 0x000000ff;
-
-    /**
-     * The Constant RED_BGR_MASK.
-     */
-    private static final int RED_BGR_MASK = 0x000000ff;
-
-    /**
-     * The Constant GREEN_BGR_MASK.
-     */
-    private static final int GREEN_BGR_MASK = 0x0000ff00;
-
-    /**
-     * The Constant BLUE_BGR_MASK.
-     */
-    private static final int BLUE_BGR_MASK = 0x00ff0000;
-
-    /**
-     * The Constant RED_565_MASK.
-     */
-    private static final int RED_565_MASK = 0xf800;
-
-    /**
-     * The Constant GREEN_565_MASK.
-     */
-    private static final int GREEN_565_MASK = 0x07e0;
-
-    /**
-     * The Constant BLUE_565_MASK.
-     */
-    private static final int BLUE_565_MASK = 0x001f;
-
-    /**
-     * The Constant RED_555_MASK.
-     */
-    private static final int RED_555_MASK = 0x7c00;
-
-    /**
-     * The Constant GREEN_555_MASK.
-     */
-    private static final int GREEN_555_MASK = 0x03e0;
-
-    /**
-     * The Constant BLUE_555_MASK.
-     */
-    private static final int BLUE_555_MASK = 0x001f;
-
-    /**
-     * The cm.
-     */
-    private ColorModel cm;
-
-    /**
-     * The raster.
-     */
-    private final WritableRaster raster;
-
-    /**
-     * The image type.
-     */
-    private final int imageType;
-
-    /**
-     * The properties.
-     */
-    private Hashtable<?, ?> properties;
-
-    // Surface of the Buffered Image - used for blitting one Buffered Image
-    // on the other one or on the Component
-    /**
-     * The image surf.
-     */
-    private final ImageSurface imageSurf;
-
-    /**
-     * Instantiates a new BufferedImage with the specified ColorModel, and
-     * WritableRaster objects. The Raster data can be be divided or multiplied
-     * by alpha. It depends on the alphaPremultiplied state in the ColorModel.
-     * 
-     * @param cm
-     *            the ColorModel of the new image.
-     * @param raster
-     *            the WritableRaster of the new image.
-     * @param isRasterPremultiplied
-     *            if true the data of the specified Raster is pre-multiplied by
-     *            alpha.
-     * @param properties
-     *            the properties of new Image.
-     */
-    public BufferedImage(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied,
-            Hashtable<?, ?> properties) {
-        if (!cm.isCompatibleRaster(raster)) {
-            // awt.4D=The raster is incompatible with this ColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
-        }
-
-        if (raster.getMinX() != 0 || raster.getMinY() != 0) {
-            // awt.228=minX or minY of this raster not equal to zero
-            throw new IllegalArgumentException(Messages.getString("awt.228")); //$NON-NLS-1$
-        }
-
-        this.cm = cm;
-        this.raster = raster;
-        this.properties = properties;
-
-        coerceData(isRasterPremultiplied);
-
-        imageType = Surface.getType(cm, raster);
-
-        imageSurf = createImageSurface(imageType);
-    }
-
-    /**
-     * Instantiates a new BufferedImage with the specified width, height
-     * predefined image type (TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED) and the
-     * specified IndexColorModel.
-     * 
-     * @param width
-     *            the width of new image.
-     * @param height
-     *            the height of new image.
-     * @param imageType
-     *            the predefined image type.
-     * @param cm
-     *            the specified IndexColorModel.
-     */
-    public BufferedImage(int width, int height, int imageType, IndexColorModel cm) {
-        switch (imageType) {
-            case TYPE_BYTE_BINARY:
-                if (cm.hasAlpha()) {
-                    // awt.227=This image type can't have alpha
-                    throw new IllegalArgumentException(Messages.getString("awt.227")); //$NON-NLS-1$
-                }
-                int pixel_bits = 0;
-                int mapSize = cm.getMapSize();
-                if (mapSize <= 2) {
-                    pixel_bits = 1;
-                } else if (mapSize <= 4) {
-                    pixel_bits = 2;
-                } else if (mapSize <= 16) {
-                    pixel_bits = 4;
-                } else {
-                    // awt.221=The imageType is TYPE_BYTE_BINARY and the color
-                    // map has more than 16 entries
-                    throw new IllegalArgumentException(Messages.getString("awt.221")); //$NON-NLS-1$
-                }
-
-                raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width, height, 1,
-                        pixel_bits, null);
-                break;
-
-            case TYPE_BYTE_INDEXED:
-                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, 1,
-                        null);
-                break;
-
-            default:
-                // awt.222=The imageType is not TYPE_BYTE_BINARY or
-                // TYPE_BYTE_INDEXED
-                throw new IllegalArgumentException(Messages.getString("awt.222")); //$NON-NLS-1$
-
-        }
-
-        if (!cm.isCompatibleRaster(raster)) {
-            // awt.223=The imageType is not compatible with ColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.223")); //$NON-NLS-1$
-        }
-
-        this.cm = cm;
-        this.imageType = imageType;
-        imageSurf = createImageSurface(imageType);
-
-    }
-
-    /**
-     * Instantiates a new BufferedImage with the specified width, height and
-     * predefined image type.
-     * 
-     * @param width
-     *            the width of new image.
-     * @param height
-     *            the height of new image.
-     * @param imageType
-     *            the predefined image type.
-     */
-    public BufferedImage(int width, int height, int imageType) {
-
-        switch (imageType) {
-            case TYPE_INT_RGB:
-                cm = new DirectColorModel(24, RED_MASK, GREEN_MASK, BLUE_MASK);
-                raster = cm.createCompatibleWritableRaster(width, height);
-                break;
-
-            case TYPE_INT_ARGB:
-                cm = ColorModel.getRGBdefault();
-                raster = cm.createCompatibleWritableRaster(width, height);
-                break;
-
-            case TYPE_INT_ARGB_PRE:
-                cm = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32, RED_MASK,
-                        GREEN_MASK, BLUE_MASK, ALPHA_MASK, true, DataBuffer.TYPE_INT);
-
-                raster = cm.createCompatibleWritableRaster(width, height);
-                break;
-
-            case TYPE_INT_BGR:
-                cm = new DirectColorModel(24, RED_BGR_MASK, GREEN_BGR_MASK, BLUE_BGR_MASK);
-
-                raster = cm.createCompatibleWritableRaster(width, height);
-                break;
-
-            case TYPE_3BYTE_BGR: {
-                int bits[] = {
-                        8, 8, 8
-                };
-                int bandOffsets[] = {
-                        2, 1, 0
-                };
-                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits,
-                        false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
-
-                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
-                        width * 3, 3, bandOffsets, null);
-            }
-                break;
-
-            case TYPE_4BYTE_ABGR: {
-                int bits[] = {
-                        8, 8, 8, 8
-                };
-                int bandOffsets[] = {
-                        3, 2, 1, 0
-                };
-                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits,
-                        true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
-
-                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
-                        width * 4, 4, bandOffsets, null);
-            }
-                break;
-
-            case TYPE_4BYTE_ABGR_PRE: {
-                int bits[] = {
-                        8, 8, 8, 8
-                };
-                int bandOffsets[] = {
-                        3, 2, 1, 0
-                };
-                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits,
-                        true, true, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
-
-                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
-                        width * 4, 4, bandOffsets, null);
-            }
-                break;
-
-            case TYPE_USHORT_565_RGB:
-                cm = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 16,
-                        RED_565_MASK, GREEN_565_MASK, BLUE_565_MASK, 0, false,
-                        DataBuffer.TYPE_USHORT);
-
-                raster = cm.createCompatibleWritableRaster(width, height);
-                break;
-
-            case TYPE_USHORT_555_RGB:
-                cm = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 15,
-                        RED_555_MASK, GREEN_555_MASK, BLUE_555_MASK, 0, false,
-                        DataBuffer.TYPE_USHORT);
-
-                raster = cm.createCompatibleWritableRaster(width, height);
-                break;
-
-            case TYPE_BYTE_GRAY: {
-                int bits[] = {
-                    8
-                };
-                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), bits,
-                        false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
-
-                raster = cm.createCompatibleWritableRaster(width, height);
-            }
-                break;
-
-            case TYPE_USHORT_GRAY: {
-                int bits[] = {
-                    16
-                };
-                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), bits,
-                        false, false, Transparency.OPAQUE, DataBuffer.TYPE_USHORT);
-                raster = cm.createCompatibleWritableRaster(width, height);
-            }
-                break;
-
-            case TYPE_BYTE_BINARY: {
-                int colorMap[] = {
-                        0, 0xffffff
-                };
-                cm = new IndexColorModel(1, 2, colorMap, 0, false, -1, DataBuffer.TYPE_BYTE);
-
-                raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width, height, 1, 1, null);
-            }
-                break;
-
-            case TYPE_BYTE_INDEXED: {
-                int colorMap[] = new int[256];
-                int i = 0;
-                for (int r = 0; r < 256; r += 51) {
-                    for (int g = 0; g < 256; g += 51) {
-                        for (int b = 0; b < 256; b += 51) {
-                            colorMap[i] = (r << 16) | (g << 8) | b;
-                            i++;
-                        }
-                    }
-                }
-
-                int gray = 0x12;
-                for (; i < 256; i++, gray += 6) {
-                    colorMap[i] = (gray << 16) | (gray << 8) | gray;
-                }
-                cm = new IndexColorModel(8, 256, colorMap, 0, false, -1, DataBuffer.TYPE_BYTE);
-                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, 1,
-                        null);
-
-            }
-                break;
-            default:
-                // awt.224=Unknown image type
-                throw new IllegalArgumentException(Messages.getString("awt.224")); //$NON-NLS-1$
-        }
-        this.imageType = imageType;
-        imageSurf = createImageSurface(imageType);
-    }
-
-    @Override
-    public Object getProperty(String name, ImageObserver observer) {
-        return getProperty(name);
-    }
-
-    public Object getProperty(String name) {
-        if (name == null) {
-            // awt.225=Property name is null
-            throw new NullPointerException(Messages.getString("awt.225")); //$NON-NLS-1$
-        }
-        if (properties == null) {
-            return Image.UndefinedProperty;
-        }
-        Object property = properties.get(name);
-        if (property == null) {
-            property = Image.UndefinedProperty;
-        }
-        return property;
-    }
-
-    public WritableRaster copyData(WritableRaster outRaster) {
-        if (outRaster == null) {
-            outRaster = Raster.createWritableRaster(raster.getSampleModel(), new Point(raster
-                    .getSampleModelTranslateX(), raster.getSampleModelTranslateY()));
-        }
-
-        int w = outRaster.getWidth();
-        int h = outRaster.getHeight();
-        int minX = outRaster.getMinX();
-        int minY = outRaster.getMinY();
-
-        Object data = null;
-
-        data = raster.getDataElements(minX, minY, w, h, data);
-        outRaster.setDataElements(minX, minY, w, h, data);
-
-        return outRaster;
-    }
-
-    public Raster getData(Rectangle rect) {
-        int minX = rect.x;
-        int minY = rect.y;
-        int w = rect.width;
-        int h = rect.height;
-
-        SampleModel sm = raster.getSampleModel();
-        SampleModel nsm = sm.createCompatibleSampleModel(w, h);
-        WritableRaster outr = Raster.createWritableRaster(nsm, rect.getLocation());
-        Object data = null;
-
-        data = raster.getDataElements(minX, minY, w, h, data);
-        outr.setDataElements(minX, minY, w, h, data);
-        return outr;
-    }
-
-    public Vector<RenderedImage> getSources() {
-        return null;
-    }
-
-    public String[] getPropertyNames() {
-        if (properties == null) {
-            return null;
-        }
-        Vector<String> v = new Vector<String>();
-        for (Enumeration<?> e = properties.keys(); e.hasMoreElements();) {
-            try {
-                v.add((String)e.nextElement());
-            } catch (ClassCastException ex) {
-            }
-        }
-        int size = v.size();
-        if (size > 0) {
-            String names[] = new String[size];
-            for (int i = 0; i < size; i++) {
-                names[i] = v.elementAt(i);
-            }
-            return names;
-        }
-        return null;
-    }
-
-    /**
-     * Returns the string representation of this BufferedImage object.
-     * 
-     * @return the string representation of this BufferedImage object.
-     */
-    @Override
-    public String toString() {
-        return "BufferedImage@" + Integer.toHexString(hashCode()) + //$NON-NLS-1$
-                ": type = " + imageType + " " + cm + " " + raster; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    }
-
-    public WritableRaster getWritableTile(int tileX, int tileY) {
-        return raster;
-    }
-
-    /**
-     * Gets the WritableRaster of this BufferedImage.
-     * 
-     * @return the WritableRaster of this BufferedImage.
-     */
-    public WritableRaster getRaster() {
-        return raster;
-    }
-
-    /**
-     * Gets a WritableRaster object which contains the alpha channel of
-     * BufferedImage object with ColorModel objects that supports a separate
-     * alpha channel such as ComponentColorModel or DirectColorModel.
-     * 
-     * @return the WritableRaster object which contains the alpha channel of
-     *         this BufferedImage.
-     */
-    public WritableRaster getAlphaRaster() {
-        return cm.getAlphaRaster(raster);
-    }
-
-    public void removeTileObserver(TileObserver to) {
-    }
-
-    public void addTileObserver(TileObserver to) {
-    }
-
-    public SampleModel getSampleModel() {
-        return raster.getSampleModel();
-    }
-
-    public void setData(Raster r) {
-
-        Rectangle from = r.getBounds();
-        Rectangle to = raster.getBounds();
-        Rectangle intersection = to.intersection(from);
-
-        int minX = intersection.x;
-        int minY = intersection.y;
-        int w = intersection.width;
-        int h = intersection.height;
-
-        Object data = null;
-
-        data = r.getDataElements(minX, minY, w, h, data);
-        raster.setDataElements(minX, minY, w, h, data);
-    }
-
-    public Raster getTile(int tileX, int tileY) {
-        if (tileX == 0 && tileY == 0) {
-            return raster;
-        }
-        // awt.226=Both tileX and tileY are not equal to 0
-        throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.226")); //$NON-NLS-1$
-    }
-
-    public Raster getData() {
-        int w = raster.getWidth();
-        int h = raster.getHeight();
-        int minX = raster.getMinX();
-        int minY = raster.getMinY();
-
-        WritableRaster outr = Raster.createWritableRaster(raster.getSampleModel(), new Point(raster
-                .getSampleModelTranslateX(), raster.getSampleModelTranslateY()));
-
-        Object data = null;
-
-        data = raster.getDataElements(minX, minY, w, h, data);
-        outr.setDataElements(minX, minY, w, h, data);
-
-        return outr;
-    }
-
-    @Override
-    public ImageProducer getSource() {
-        return new BufferedImageSource(this, properties);
-    }
-
-    @Override
-    public int getWidth(ImageObserver observer) {
-        return raster.getWidth();
-    }
-
-    @Override
-    public int getHeight(ImageObserver observer) {
-        return raster.getHeight();
-    }
-
-    public ColorModel getColorModel() {
-        return cm;
-    }
-
-    /**
-     * Gets the rectangular area of this BufferedImage as a subimage.
-     * 
-     * @param x
-     *            the x coordinate.
-     * @param y
-     *            the y coordinate.
-     * @param w
-     *            the width of the subimage.
-     * @param h
-     *            the height of the subimage.
-     * @return the BufferedImage.
-     */
-    public BufferedImage getSubimage(int x, int y, int w, int h) {
-        WritableRaster wr = raster.createWritableChild(x, y, w, h, 0, 0, null);
-        return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), properties);
-    }
-
-    public Point[] getWritableTileIndices() {
-        Point points[] = new Point[1];
-        points[0] = new Point(0, 0);
-        return points;
-    }
-
-    /**
-     * Creates the Graphics2D object which allows to draw into this
-     * BufferedImage.
-     * 
-     * @return the graphics2D object.
-     */
-    public Graphics2D createGraphics() {
-        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
-        // return ge.createGraphics(this);
-        // ???AWT hack, FIXME
-        // return AndroidGraphics2D.getInstance();
-        // throw new RuntimeException("Not implemented!");
-        return null;
-    }
-
-    @Override
-    public Graphics getGraphics() {
-        return createGraphics();
-    }
-
-    /**
-     * Coerces the data to achieve the state which is specified by the
-     * isAlphaPremultiplied variable.
-     * 
-     * @param isAlphaPremultiplied
-     *            the is alpha pre-multiplied state.
-     */
-    public void coerceData(boolean isAlphaPremultiplied) {
-        if (cm.hasAlpha() && cm.isAlphaPremultiplied() != isAlphaPremultiplied) {
-            cm = cm.coerceData(raster, isAlphaPremultiplied);
-        }
-    }
-
-    /**
-     * Gets an array of colors in the TYPE_INT_ARGB color model and default sRGB
-     * color space of the specified area of this BufferedImage. The result array
-     * is composed by the following algorithm:
-     * <p>
-     * pixel = rgbArray[offset + (y-startY)*scansize + (x-startX)]
-     * </p>
-     * 
-     * @param startX
-     *            the start X area coordinate.
-     * @param startY
-     *            the start Y area coordinate.
-     * @param w
-     *            the width of the area.
-     * @param h
-     *            the height of the area.
-     * @param rgbArray
-     *            the result array will be stored to this array.
-     * @param offset
-     *            the offset of the rgbArray array.
-     * @param scansize
-     *            the scanline stride for the rgbArray.
-     * @return an array of colors for the specified area.
-     */
-    public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset,
-            int scansize) {
-        if (rgbArray == null) {
-            rgbArray = new int[offset + h * scansize];
-        }
-
-        int off = offset;
-        for (int y = startY; y < startY + h; y++, off += scansize) {
-            int i = off;
-            for (int x = startX; x < startX + w; x++, i++) {
-                rgbArray[i] = cm.getRGB(raster.getDataElements(x, y, null));
-            }
-        }
-        return rgbArray;
-    }
-
-    /**
-     * Sets RGB values from the specified array to the specified BufferedImage
-     * area. The pixels are in the default RGB color model (TYPE_INT_ARGB) and
-     * default sRGB color space.
-     * 
-     * @param startX
-     *            the start X coordinate.
-     * @param startY
-     *            the start Y coordinate.
-     * @param w
-     *            the width of the BufferedImage area.
-     * @param h
-     *            the height of the BufferedImage area.
-     * @param rgbArray
-     *            the array of RGB values.
-     * @param offset
-     *            the offset of the rgbArray array.
-     * @param scansize
-     *            the scanline stride for the rgbArray.
-     */
-    public void setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset,
-            int scansize) {
-        int off = offset;
-        for (int y = startY; y < startY + h; y++, off += scansize) {
-            int i = off;
-            for (int x = startX; x < startX + w; x++, i++) {
-                raster.setDataElements(x, y, cm.getDataElements(rgbArray[i], null));
-            }
-        }
-    }
-
-    /**
-     * Sets a the specified RGB value to the specified pixel of this
-     * BufferedImage. The pixel should be in the default RGB color model
-     * (TYPE_INT_ARGB) and default sRGB color space.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param rgb
-     *            the RGB value to be set.
-     */
-    public synchronized void setRGB(int x, int y, int rgb) {
-        raster.setDataElements(x, y, cm.getDataElements(rgb, null));
-    }
-
-    public boolean isTileWritable(int tileX, int tileY) {
-        if (tileX == 0 && tileY == 0) {
-            return true;
-        }
-        // awt.226=Both tileX and tileY are not equal to 0
-        throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.226")); //$NON-NLS-1$
-    }
-
-    public void releaseWritableTile(int tileX, int tileY) {
-    }
-
-    /**
-     * Gets a color in the TYPE_INT_ARGB color model and default sRGB color
-     * space of the specified pixel.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @return the color of the specified pixel in the TYPE_INT_ARGB color model
-     *         and default sRGB color space.
-     */
-    public int getRGB(int x, int y) {
-        return cm.getRGB(raster.getDataElements(x, y, null));
-    }
-
-    /**
-     * Returns true if alpha is pre-multiplied, false if alpha is not
-     * pre-multiplied or there is no alpha.
-     * 
-     * @return true if alpha is pre-multiplied, false if alpha is not
-     *         pre-multiplied or there is no alpha.
-     */
-    public boolean isAlphaPremultiplied() {
-        return cm.isAlphaPremultiplied();
-    }
-
-    public boolean hasTileWriters() {
-        return true;
-    }
-
-    @Override
-    public void flush() {
-        imageSurf.dispose();
-    }
-
-    public int getWidth() {
-        return raster.getWidth();
-    }
-
-    /**
-     * Gets the image type.
-     * 
-     * @return the image type.
-     */
-    public int getType() {
-        return imageType;
-    }
-
-    public int getTileWidth() {
-        return raster.getWidth();
-    }
-
-    public int getTileHeight() {
-        return raster.getHeight();
-    }
-
-    public int getTileGridYOffset() {
-        return raster.getSampleModelTranslateY();
-    }
-
-    public int getTileGridXOffset() {
-        return raster.getSampleModelTranslateX();
-    }
-
-    public int getNumYTiles() {
-        return 1;
-    }
-
-    public int getNumXTiles() {
-        return 1;
-    }
-
-    public int getMinY() {
-        return raster.getMinY();
-    }
-
-    public int getMinX() {
-        return raster.getMinX();
-    }
-
-    public int getMinTileY() {
-        return 0;
-    }
-
-    public int getMinTileX() {
-        return 0;
-    }
-
-    public int getHeight() {
-        return raster.getHeight();
-    }
-
-    /**
-     * Creates the image surface.
-     * 
-     * @param type
-     *            the type.
-     * @return the image surface.
-     */
-    private ImageSurface createImageSurface(int type) {
-        return new ImageSurface(getColorModel(), getRaster(), type);
-    }
-
-    /**
-     * Gets the image surface.
-     * 
-     * @return the image surface.
-     */
-    ImageSurface getImageSurface() {
-        return imageSurf;
-    }
-
-    public int getTransparency() {
-        return cm.getTransparency();
-    }
-}
diff --git a/awt/java/awt/image/BufferedImageFilter.java b/awt/java/awt/image/BufferedImageFilter.java
deleted file mode 100644
index 8b6fcf0..0000000
--- a/awt/java/awt/image/BufferedImageFilter.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The BufferedImageFilter class provides filtering operations to the
- * BufferedImage objects using operators which implement BufferedImageOp
- * interface.
- * 
- * @since Android 1.0
- */
-public class BufferedImageFilter extends ImageFilter implements Cloneable {
-
-    /**
-     * The Constant accessor.
-     */
-    private static final AwtImageBackdoorAccessor accessor = AwtImageBackdoorAccessor.getInstance();
-
-    /**
-     * The op.
-     */
-    private BufferedImageOp op;
-
-    /**
-     * The raster.
-     */
-    private WritableRaster raster;
-
-    /**
-     * The i data.
-     */
-    private int iData[];
-
-    /**
-     * The b data.
-     */
-    private byte bData[];
-
-    /**
-     * The width.
-     */
-    private int width;
-
-    /**
-     * The height.
-     */
-    private int height;
-
-    /**
-     * The cm.
-     */
-    private ColorModel cm;
-
-    /**
-     * The forced rgb.
-     */
-    private boolean forcedRGB = false;
-
-    /**
-     * The transfer type.
-     */
-    private int transferType = DataBuffer.TYPE_UNDEFINED;
-
-    /**
-     * Instantiates a new BufferedImageFilter with the specified BufferedImageOp
-     * operator.
-     * 
-     * @param op
-     *            the specified BufferedImageOp operator.
-     * @throws NullPointerException
-     *             if BufferedImageOp is null.
-     */
-    public BufferedImageFilter(BufferedImageOp op) {
-        if (op == null) {
-            throw new NullPointerException(Messages.getString("awt.05")); //$NON-NLS-1$
-        }
-        this.op = op;
-    }
-
-    /**
-     * Gets the BufferedImageOp operator associated with this
-     * BufferedImageFilter object.
-     * 
-     * @return the BufferedImageOp associated with this BufferedImageFilter
-     *         object.
-     */
-    public BufferedImageOp getBufferedImageOp() {
-        return op;
-    }
-
-    @Override
-    public void setDimensions(int width, int height) {
-        this.width = width;
-        this.height = height;
-        // Stop image consuming if no pixels expected.
-        if (width <= 0 || height <= 0) {
-            consumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
-            reset();
-        }
-    }
-
-    @Override
-    public void setColorModel(ColorModel model) {
-        if (this.cm != null && this.cm != model && raster != null) {
-            forceRGB();
-        } else {
-            this.cm = model;
-        }
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
-            int scansize) {
-        setPixels(x, y, w, h, model, pixels, off, scansize, true);
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
-            int scansize) {
-        setPixels(x, y, w, h, model, pixels, off, scansize, false);
-    }
-
-    @Override
-    public void imageComplete(int status) {
-        if (status == STATICIMAGEDONE || status == SINGLEFRAMEDONE) {
-            BufferedImage bim = new BufferedImage(cm, raster, cm.isAlphaPremultiplied, null);
-            bim = op.filter(bim, null);
-            DataBuffer dstDb = bim.getRaster().getDataBuffer();
-            ColorModel dstCm = bim.getColorModel();
-            int dstW = bim.getWidth();
-            int dstH = bim.getHeight();
-
-            consumer.setDimensions(dstW, dstH);
-
-            if (dstDb.getDataType() == DataBuffer.TYPE_INT) {
-                consumer.setColorModel(dstCm);
-                consumer.setPixels(0, 0, dstW, dstH, dstCm, accessor.getDataInt(dstDb), 0, dstW);
-            } else if (dstDb.getDataType() == DataBuffer.TYPE_BYTE) {
-                consumer.setColorModel(dstCm);
-                consumer.setPixels(0, 0, dstW, dstH, dstCm, accessor.getDataByte(dstDb), 0, dstW);
-            } else {
-                int dstData[] = bim.getRGB(0, 0, dstW, dstH, null, 0, dstW);
-                dstCm = ColorModel.getRGBdefault();
-                consumer.setColorModel(dstCm);
-                consumer.setPixels(0, 0, dstW, dstH, dstCm, dstData, 0, dstW);
-            }
-        } else if (status == IMAGEERROR || status == IMAGEABORTED) {
-            reset();
-        }
-
-        consumer.imageComplete(status);
-    }
-
-    /**
-     * Sets the pixels.
-     * 
-     * @param x
-     *            the x.
-     * @param y
-     *            the y.
-     * @param w
-     *            the w.
-     * @param h
-     *            the h.
-     * @param model
-     *            the model.
-     * @param pixels
-     *            the pixels.
-     * @param off
-     *            the off.
-     * @param scansize
-     *            the scansize.
-     * @param isByteData
-     *            the is byte data.
-     */
-    private void setPixels(int x, int y, int w, int h, ColorModel model, Object pixels, int off,
-            int scansize, boolean isByteData) {
-        // Check bounds
-        // Need to copy only the pixels that will fit into the destination area
-        if (x < 0) {
-            w -= x;
-            off += x;
-            x = 0;
-        }
-
-        if (y < 0) {
-            h -= y;
-            off += y * scansize;
-            y = 0;
-        }
-
-        if (x + w > width) {
-            w = width - x;
-        }
-
-        if (y + h > height) {
-            h = height - y;
-        }
-
-        if (w <= 0 || h <= 0) {
-            return;
-        }
-
-        // Check model
-        if (this.cm == null) {
-            setColorModel(model);
-        } else if (model == null) {
-            model = this.cm;
-        } else if (!model.equals(this.cm)) {
-            forceRGB();
-        }
-
-        boolean canArraycopy;
-        // Process pixels
-        switch (transferType) {
-            case DataBuffer.TYPE_UNDEFINED: {
-                if (isByteData) {
-                    transferType = DataBuffer.TYPE_BYTE;
-                    createRaster(transferType);
-                    // bData = new byte[width*height];
-                    canArraycopy = !forcedRGB;
-                    break;
-                }
-                transferType = DataBuffer.TYPE_INT;
-                createRaster(transferType);
-                // iData = new int[width*height];
-                canArraycopy = !forcedRGB || model.equals(ColorModel.getRGBdefault());
-                break;
-            } // And proceed to copy the pixels
-            case DataBuffer.TYPE_INT: {
-                if (isByteData) { // There are int data already but the new data
-                    // are bytes
-                    forceRGB();
-                    canArraycopy = false;
-                    break;
-                } else if (!forcedRGB || model.equals(ColorModel.getRGBdefault())) {
-                    canArraycopy = true;
-                    break;
-                } // Else fallback to the RGB conversion
-            }
-            case DataBuffer.TYPE_BYTE: {
-                if (isByteData && !forcedRGB) {
-                    canArraycopy = true;
-                    break;
-                }
-
-                // RGB conversion
-                canArraycopy = false;
-                break;
-            }
-            default: {
-                throw new IllegalStateException(Messages.getString("awt.06")); //$NON-NLS-1$
-            }
-        }
-
-        off += x;
-        int maxOffset = off + h * scansize;
-        int dstOffset = x + y * width;
-
-        if (canArraycopy) {
-            Object dstArray = isByteData ? (Object)bData : (Object)iData;
-            for (; off < maxOffset; off += scansize, dstOffset += width) {
-                System.arraycopy(pixels, off, dstArray, dstOffset, w);
-            }
-        } else {
-            // RGB conversion
-            for (; off < maxOffset; off += scansize, dstOffset += width) {
-                int srcPos = off;
-                int dstPos = dstOffset;
-                int maxDstPos = dstOffset + w;
-                for (; dstPos < maxDstPos; dstPos++, srcPos++) {
-                    iData[dstPos] = model.getRGB(isByteData ? ((byte[])pixels)[srcPos]
-                            : ((int[])pixels)[srcPos]);
-                }
-            }
-        }
-    }
-
-    /**
-     * Force rgb.
-     */
-    private void forceRGB() {
-        if (!forcedRGB) {
-            forcedRGB = true;
-            int size = width * height;
-            int rgbData[] = new int[size];
-
-            if (bData != null) {
-                for (int i = 0; i < size; i++) {
-                    rgbData[i] = cm.getRGB(bData[i]);
-                }
-            } else if (iData != null) {
-                for (int i = 0; i < size; i++) {
-                    rgbData[i] = cm.getRGB(iData[i]);
-                }
-            }
-
-            cm = ColorModel.getRGBdefault();
-            DataBufferInt db = new DataBufferInt(rgbData, size);
-            int masks[] = new int[] {
-                    0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
-            };
-            raster = Raster.createPackedRaster(db, width, height, width, masks, null);
-            iData = accessor.getDataInt(db);
-            bData = null;
-            transferType = DataBuffer.TYPE_INT;
-        }
-    }
-
-    /**
-     * Reset.
-     */
-    private void reset() {
-        width = 0;
-        height = 0;
-        forcedRGB = false;
-        cm = null;
-        iData = null;
-        bData = null;
-        transferType = DataBuffer.TYPE_UNDEFINED;
-        raster = null;
-    }
-
-    /**
-     * Creates the raster.
-     * 
-     * @param dataType
-     *            the data type.
-     */
-    private void createRaster(int dataType) {
-        boolean createdValidBuffer = false;
-        try {
-            raster = cm.createCompatibleWritableRaster(width, height);
-            int rasterType = raster.getDataBuffer().getDataType();
-            if (rasterType == dataType) {
-                switch (rasterType) {
-                    case DataBuffer.TYPE_INT: {
-                        iData = accessor.getDataInt(raster.getDataBuffer());
-                        if (iData != null) {
-                            createdValidBuffer = true;
-                        }
-                        break;
-                    }
-                    case DataBuffer.TYPE_BYTE: {
-                        bData = accessor.getDataByte(raster.getDataBuffer());
-                        if (bData != null) {
-                            createdValidBuffer = true;
-                        }
-                        break;
-                    }
-                    default:
-                        createdValidBuffer = false;
-                }
-
-                if (cm == ColorModel.getRGBdefault()) {
-                    forcedRGB = true;
-                }
-            } else {
-                createdValidBuffer = false;
-            }
-        } catch (Exception e) {
-            createdValidBuffer = false;
-        }
-
-        if (createdValidBuffer == false) {
-            cm = ColorModel.getRGBdefault();
-            raster = cm.createCompatibleWritableRaster(width, height);
-            iData = accessor.getDataInt(raster.getDataBuffer());
-            bData = null;
-            forcedRGB = true;
-        }
-    }
-}
diff --git a/awt/java/awt/image/BufferedImageOp.java b/awt/java/awt/image/BufferedImageOp.java
deleted file mode 100644
index 883a39d..0000000
--- a/awt/java/awt/image/BufferedImageOp.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.RenderingHints;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-
-/**
- * The BufferedImageOp interface provides methods for performing transformations
- * from source data to destination data for BufferedImage objects. An object
- * implementing this interface can be passed into a BufferedImageFilter to
- * operate on a BufferedImage.
- * 
- * @since Android 1.0
- */
-public interface BufferedImageOp {
-
-    /**
-     * Creates a destination image with the specified BufferedImage and
-     * ColorModel; this destination image is empty and has the correct size and
-     * number of bands.
-     * 
-     * @param src
-     *            the source BufferedImage.
-     * @param destCM
-     *            the destination ColorModel.
-     * @return the BufferedImage.
-     */
-    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM);
-
-    /**
-     * Performs a filter operation on the source BufferedImage and stores the
-     * resulting BufferedImage to the destination BufferedImage. If the
-     * destination BufferedImage is null, a BufferedImage with an appropriate
-     * ColorModel is created.
-     * 
-     * @param src
-     *            the source BufferedImage.
-     * @param dest
-     *            the destination BufferedImage, where the result is stored.
-     * @return the filtered BufferedImage.
-     */
-    public BufferedImage filter(BufferedImage src, BufferedImage dest);
-
-    /**
-     * Gets the bounds of filtered image.
-     * 
-     * @param src
-     *            the source BufferedImage to be filtered.
-     * @return the rectangle bounds of filtered image.
-     */
-    public Rectangle2D getBounds2D(BufferedImage src);
-
-    /**
-     * Gets the point of the destination image which corresponds to the
-     * specified point in the source image.
-     * 
-     * @param srcPt
-     *            the point of the source image.
-     * @param dstPt
-     *            the point where the result will be stored.
-     * @return the destination point.
-     */
-    public Point2D getPoint2D(Point2D srcPt, Point2D dstPt);
-
-    /**
-     * Gets the RenderingHints of the BufferedImageOp.
-     * 
-     * @return the RenderingHints of the BufferedImageOp.
-     */
-    public RenderingHints getRenderingHints();
-}
diff --git a/awt/java/awt/image/ByteLookupTable.java b/awt/java/awt/image/ByteLookupTable.java
deleted file mode 100644
index 27cee30..0000000
--- a/awt/java/awt/image/ByteLookupTable.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Oct 14, 2005
- */
-
-package java.awt.image;
-
-/**
- * The ByteLookupTable class provides functionality for lookup operations, and
- * is defined by an input byte array for bands or components of image and an
- * offset value. The offset value will be subtracted from the input values
- * before indexing the input arrays. The output of a lookup operation is
- * represented as an array of unsigned bytes.
- * 
- * @since Android 1.0
- */
-public class ByteLookupTable extends LookupTable {
-
-    /**
-     * The data.
-     */
-    private byte data[][];
-
-    /**
-     * Instantiates a new ByteLookupTable with the specified offset value and
-     * the specified byte array which represents the lookup table for all bands.
-     * 
-     * @param offset
-     *            the offset value.
-     * @param data
-     *            the data array of bytes.
-     */
-    public ByteLookupTable(int offset, byte[] data) {
-        super(offset, 1);
-        if (data.length < 1)
-            throw new IllegalArgumentException("Length of data should not be less then one");
-        this.data = new byte[1][data.length];
-        // The data array stored as a reference
-        this.data[0] = data;
-    }
-
-    /**
-     * Instantiates a new ByteLookupTable with the specified offset value and
-     * the specified byte array of arrays which represents the lookup table for
-     * each band.
-     * 
-     * @param offset
-     *            the offset value.
-     * @param data
-     *            the data array of bytes array for each band.
-     */
-    public ByteLookupTable(int offset, byte[][] data) {
-        super(offset, data.length);
-        this.data = new byte[data.length][data[0].length];
-        for (int i = 0; i < data.length; i++) {
-            // The data array for each band stored as a reference
-            this.data[i] = data[i];
-        }
-    }
-
-    /**
-     * Gets the lookup table of this ByteLookupTable object. If this
-     * ByteLookupTable object has one byte array for all bands, the returned
-     * array length is one.
-     * 
-     * @return the lookup table of this ByteLookupTable object.
-     */
-    public final byte[][] getTable() {
-        // Returns data by reference
-        return data;
-    }
-
-    @Override
-    public int[] lookupPixel(int[] src, int[] dst) {
-        if (dst == null) {
-            dst = new int[src.length];
-        }
-
-        int offset = getOffset();
-        if (getNumComponents() == 1) {
-            for (int i = 0; i < src.length; i++) {
-                dst[i] = data[0][src[i] - offset];
-            }
-        } else {
-            for (int i = 0; i < getNumComponents(); i++) {
-                dst[i] = data[i][src[i] - offset];
-            }
-        }
-
-        return dst;
-    }
-
-    /**
-     * Returns a byte array which contains samples of the specified pixel which
-     * is translated with the lookup table of this ByteLookupTable object. The
-     * resulted array is stored to the dst array.
-     * 
-     * @param src
-     *            the source array.
-     * @param dst
-     *            the destination array where the result can be stored.
-     * @return the byte array of translated samples of a pixel.
-     */
-    public byte[] lookupPixel(byte[] src, byte[] dst) {
-        if (dst == null) {
-            dst = new byte[src.length];
-        }
-
-        int offset = getOffset();
-        if (getNumComponents() == 1) {
-            for (int i = 0; i < src.length; i++) {
-                dst[i] = data[0][src[i] - offset];
-            }
-        } else {
-            for (int i = 0; i < getNumComponents(); i++) {
-                dst[i] = data[i][src[i] - offset];
-            }
-        }
-
-        return dst;
-    }
-}
diff --git a/awt/java/awt/image/ColorConvertOp.java b/awt/java/awt/image/ColorConvertOp.java
deleted file mode 100644
index 1a1700b..0000000
--- a/awt/java/awt/image/ColorConvertOp.java
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/** 
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.RenderingHints;
-import java.awt.color.ColorSpace;
-import java.awt.color.ICC_ColorSpace;
-import java.awt.color.ICC_Profile;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-
-import org.apache.harmony.awt.gl.color.ColorConverter;
-import org.apache.harmony.awt.gl.color.ColorScaler;
-import org.apache.harmony.awt.gl.color.ICC_Transform;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The ColorConvertOp class converts the pixels of the data in the source image
- * with the specified ColorSpace objects or an array of ICC_Profile objects. The
- * result pixels are scaled to the precision of the destination image.
- * 
- * @since Android 1.0
- */
-public class ColorConvertOp implements BufferedImageOp, RasterOp {
-    // Unused but required by interfaces
-    /**
-     * The rendering hints.
-     */
-    RenderingHints renderingHints;
-
-    // Sequence consisting of ColorSpace and ICC_Profile elements
-    /**
-     * The conversion sequence.
-     */
-    Object conversionSequence[] = new ICC_Profile[0]; // To eliminate checks for
-
-    // null
-
-    // Not null if ColorConvertOp is constructed from the array of ICC profiles
-    /**
-     * The mid profiles.
-     */
-    private ICC_Profile midProfiles[];
-
-    /**
-     * The cc.
-     */
-    private final ColorConverter cc = new ColorConverter();
-
-    /**
-     * The t creator.
-     */
-    private final ICC_TransfomCreator tCreator = new ICC_TransfomCreator();
-
-    /**
-     * The is icc.
-     */
-    private boolean isICC = true;
-
-    // Cached ICC_Transform
-    /**
-     * The Class ICC_TransfomCreator.
-     */
-    private class ICC_TransfomCreator {
-
-        /**
-         * The transform.
-         */
-        private ICC_Transform transform;
-
-        /**
-         * The max components.
-         */
-        private int maxComponents;
-
-        /**
-         * For the full ICC case.
-         * 
-         * @param src
-         *            the src.
-         * @param dst
-         *            the dst.
-         * @param convSeq
-         *            the conv seq.
-         * @return the transform.
-         */
-        public ICC_Transform getTransform(ICC_Profile src, ICC_Profile dst, ICC_Profile convSeq[]) {
-            if (transform != null && src == transform.getSrc() && dst == transform.getDst()) {
-                return transform;
-            }
-
-            int length = convSeq.length;
-            int srcFlg = 0, dstFlg = 0;
-
-            if (length == 0 || src != convSeq[0]) {
-                if (src != null) {
-                    srcFlg = 1; // need src profile
-                }
-            }
-            if (length == 0 || dst != convSeq[length - 1]) {
-                if (dst != null) {
-                    dstFlg = 1; // need dst profile
-                }
-            }
-
-            ICC_Profile profiles[];
-            int nProfiles = length + srcFlg + dstFlg;
-            if (nProfiles == length) {
-                profiles = convSeq;
-            } else {
-                profiles = new ICC_Profile[nProfiles];
-                int pos = 0;
-                if (srcFlg != 0) {
-                    profiles[pos++] = src;
-                }
-                for (int i = 0; i < length; i++) {
-                    profiles[pos++] = convSeq[i];
-                }
-                if (dstFlg != 0) {
-                    profiles[pos++] = dst;
-                }
-            }
-
-            return transform = new ICC_Transform(profiles);
-        }
-
-        /**
-         * Used only when there are non-ICC color spaces. Returns sequence of
-         * non-ICC color spaces and ICC transforms made from src, dst and
-         * conversionSequence.
-         * 
-         * @param src
-         *            the src.
-         * @param dst
-         *            the dst.
-         * @return the sequence.
-         */
-        public Object[] getSequence(Object src, Object dst) {
-            ArrayList<Object> profiles = new ArrayList<Object>(10);
-            ArrayList<Object> sequence = new ArrayList<Object>(10);
-
-            // We need this profile anyway
-            ICC_Profile xyzProfile = ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
-
-            Object conversionFirst = null, conversionLast = null;
-            int conversionLength = conversionSequence.length;
-            if (conversionLength > 0) {
-                conversionFirst = conversionSequence[0];
-                conversionLast = conversionSequence[conversionLength - 1];
-            }
-
-            boolean iccSequenceStarted = false;
-
-            if (src != conversionFirst && src != null) {
-                if (src instanceof ICC_Profile) {
-                    profiles.add(src);
-                    iccSequenceStarted = true;
-                } else {
-                    profiles.add(xyzProfile);
-                    sequence.add(src); // Add non-ICC color space to the
-                    // sequence
-                }
-            } else {
-                profiles.add(xyzProfile);
-            }
-
-            for (int i = 0; i < conversionLength; i++) {
-                if (conversionSequence[i] instanceof ICC_Profile) {
-                    profiles.add(conversionSequence[i]);
-                    iccSequenceStarted = true;
-                } else if (iccSequenceStarted) {
-                    profiles.add(xyzProfile);
-
-                    // Eliminate same profiles if there are any
-                    // (e.g. xyzProfile may occur several times)
-                    Object prev = profiles.get(0);
-                    for (int k = 1; k < profiles.size(); k++) {
-                        if (prev == profiles.get(k)) {
-                            k--;
-                            profiles.remove(k);
-                        }
-                        prev = profiles.get(k);
-                    }
-
-                    // If only one profile left we skip the transform -
-                    // it can be only CIEXYZ
-                    if (profiles.size() > 1) {
-                        sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
-
-                        // Add non-ICC color space to the sequence
-                        sequence.add(conversionSequence[i]);
-                    }
-
-                    profiles.clear();
-                    profiles.add(xyzProfile);
-                    iccSequenceStarted = false; // Sequence of ICC profiles is
-                    // processed
-                } else { // Add non-ICC color space to the sequence
-                    sequence.add(conversionSequence[i]);
-                }
-            }
-
-            if (dst != conversionLast && dst != null) { // Add last profile if
-                // needed
-                if (dst instanceof ICC_Profile) {
-                    profiles.add(dst);
-                    iccSequenceStarted = true;
-                } else if (iccSequenceStarted) {
-                    profiles.add(xyzProfile);
-                } else {
-                    sequence.add(dst); // Add last non-ICC color space to the
-                    // sequence
-                }
-            }
-
-            if (iccSequenceStarted) { // Make last transform if needed
-                sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
-                if (dst != null && !(dst instanceof ICC_Profile)) {
-                    sequence.add(dst); // Add last non-ICC color space to the
-                    // sequence
-                }
-            }
-
-            // Calculate max number of components
-            // This number will be used for memory allocation
-            maxComponents = 0;
-            Object o;
-            for (int i = 0, size = sequence.size(); i < size; i++) {
-                o = sequence.get(i);
-                if (o instanceof ICC_Transform) {
-                    ICC_Transform t = (ICC_Transform)o;
-                    maxComponents = (maxComponents > t.getNumInputChannels() + 1) ? maxComponents
-                            : t.getNumInputChannels() + 1;
-                    maxComponents = (maxComponents > t.getNumOutputChannels() + 1) ? maxComponents
-                            : t.getNumOutputChannels() + 1;
-                } else {
-                    ColorSpace cs = (ColorSpace)o;
-                    maxComponents = (maxComponents > cs.getNumComponents() + 1) ? maxComponents
-                            : cs.getNumComponents() + 1;
-                }
-            }
-
-            return sequence.toArray();
-        }
-    }
-
-    /**
-     * Instantiates a new ColorConvertOp object using two specified ColorSpace
-     * objects.
-     * 
-     * @param srcCS
-     *            the source ColorSpace.
-     * @param dstCS
-     *            the destination ColorSpace.
-     * @param hints
-     *            the RenderingHints object used for the color conversion, or
-     *            null.
-     */
-    public ColorConvertOp(ColorSpace srcCS, ColorSpace dstCS, RenderingHints hints) {
-        if (srcCS == null || dstCS == null) {
-            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
-        }
-
-        renderingHints = hints;
-
-        boolean srcICC = srcCS instanceof ICC_ColorSpace;
-        boolean dstICC = dstCS instanceof ICC_ColorSpace;
-
-        if (srcICC && dstICC) {
-            conversionSequence = new ICC_Profile[2];
-        } else {
-            conversionSequence = new Object[2];
-            isICC = false;
-        }
-
-        if (srcICC) {
-            conversionSequence[0] = ((ICC_ColorSpace)srcCS).getProfile();
-        } else {
-            conversionSequence[0] = srcCS;
-        }
-
-        if (dstICC) {
-            conversionSequence[1] = ((ICC_ColorSpace)dstCS).getProfile();
-        } else {
-            conversionSequence[1] = dstCS;
-        }
-    }
-
-    /**
-     * Instantiates a new ColorConvertOp object from the specified ICC_Profile
-     * objects.
-     * 
-     * @param profiles
-     *            the array of ICC_Profile objects.
-     * @param hints
-     *            the RenderingHints object used for the color conversion, or
-     *            null.
-     */
-    public ColorConvertOp(ICC_Profile profiles[], RenderingHints hints) {
-        if (profiles == null) {
-            throw new NullPointerException(Messages.getString("awt.25C")); //$NON-NLS-1$
-        }
-
-        renderingHints = hints;
-
-        // This array is not used in the program logic, so don't need to copy it
-        // Store it only to return back
-        midProfiles = profiles;
-
-        conversionSequence = new ICC_Profile[midProfiles.length];
-
-        // Add profiles to the conversion sequence
-        for (int i = 0, length = midProfiles.length; i < length; i++) {
-            conversionSequence[i] = midProfiles[i];
-        }
-    }
-
-    /**
-     * Instantiates a new ColorConvertOp object using the specified ColorSpace
-     * object.
-     * 
-     * @param cs
-     *            the destination ColorSpace or an intermediate ColorSpace.
-     * @param hints
-     *            the RenderingHints object used for the color conversion, or
-     *            null.
-     */
-    public ColorConvertOp(ColorSpace cs, RenderingHints hints) {
-        if (cs == null) {
-            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
-        }
-
-        renderingHints = hints;
-
-        if (cs instanceof ICC_ColorSpace) {
-            conversionSequence = new ICC_Profile[1];
-            conversionSequence[0] = ((ICC_ColorSpace)cs).getProfile();
-        } else {
-            conversionSequence = new Object[1];
-            conversionSequence[0] = cs;
-            isICC = false;
-        }
-    }
-
-    /**
-     * Instantiates a new ColorConvertOp object which converts from a source
-     * color space to a destination color space.
-     * 
-     * @param hints
-     *            the RenderingHints object used for the color conversion, or
-     *            null.
-     */
-    public ColorConvertOp(RenderingHints hints) {
-        renderingHints = hints;
-    }
-
-    public final WritableRaster filter(Raster src, WritableRaster dst) {
-        if (conversionSequence.length < 2) {
-            throw new IllegalArgumentException(Messages.getString("awt.25D")); //$NON-NLS-1$
-        }
-
-        ICC_Profile srcPf = null, dstPf = null; // unused if isICC is false
-        int nSrcColorComps, nDstColorComps;
-        Object first = conversionSequence[0];
-        Object last = conversionSequence[conversionSequence.length - 1];
-
-        // Get the number of input/output color components
-        if (isICC) {
-            srcPf = (ICC_Profile)first;
-            dstPf = (ICC_Profile)last;
-            nSrcColorComps = srcPf.getNumComponents();
-            nDstColorComps = dstPf.getNumComponents();
-        } else {
-            if (first instanceof ICC_Profile) {
-                srcPf = (ICC_Profile)first;
-                nSrcColorComps = srcPf.getNumComponents();
-            } else {
-                nSrcColorComps = ((ColorSpace)first).getNumComponents();
-            }
-
-            if (last instanceof ICC_Profile) {
-                dstPf = (ICC_Profile)last;
-                nDstColorComps = dstPf.getNumComponents();
-            } else {
-                nDstColorComps = ((ColorSpace)last).getNumComponents();
-            }
-        }
-
-        // Check that source and destination rasters are compatible with
-        // transforms and with each other
-        if (src.getNumBands() != nSrcColorComps) {
-            // awt.25E=Incorrect number of source raster bands. Should be equal
-            // to the number of color components of source colorspace.
-            throw new IllegalArgumentException(Messages.getString("awt.25E")); //$NON-NLS-1$
-        }
-
-        if (dst != null) { // Check destination raster
-            if (dst.getNumBands() != nDstColorComps) {
-                // awt.25F=Incorrect number of destination raster bands. Should
-                // be equal to the number of color components of destination
-                // colorspace.
-                throw new IllegalArgumentException(Messages.getString("awt.25F")); //$NON-NLS-1$
-            }
-
-            if (src.getWidth() != dst.getWidth() || src.getHeight() != dst.getHeight()) {
-                throw new IllegalArgumentException(Messages.getString("awt.260")); //$NON-NLS-1$
-            }
-
-        } else {
-            dst = createCompatibleDestRaster(src);
-        }
-
-        if (isICC) {
-            // Create transform
-            ICC_Transform t = tCreator
-                    .getTransform(srcPf, dstPf, (ICC_Profile[])conversionSequence);
-            cc.translateColor(t, src, dst);
-        } else {
-            Object[] sequence = tCreator.getSequence(null, null);
-
-            // Get data from the source raster
-            ColorScaler scaler = new ColorScaler();
-            scaler.loadScalingData(src, null);
-            float tmpData[][] = scaler.scaleNormalize(src);
-
-            // Get source and destination color spaces
-            ColorSpace srcCS = (srcPf == null) ? (ColorSpace)first : new ICC_ColorSpace(srcPf);
-            ColorSpace dstCS = (dstPf == null) ? (ColorSpace)last : new ICC_ColorSpace(dstPf);
-
-            applySequence(sequence, tmpData, srcCS, dstCS);
-
-            scaler.loadScalingData(dst, null);
-            scaler.unscaleNormalized(dst, tmpData);
-        }
-
-        return dst;
-    }
-
-    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
-        // If destination color model is passed only one line needed
-        if (destCM != null) {
-            return new BufferedImage(destCM, destCM.createCompatibleWritableRaster(src.getWidth(),
-                    src.getHeight()), destCM.isAlphaPremultiplied(), null);
-        }
-
-        int nSpaces = conversionSequence.length;
-
-        if (nSpaces < 1) {
-            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
-        }
-
-        // Get destination color space
-        Object destination = conversionSequence[nSpaces - 1];
-        ColorSpace dstCS = (destination instanceof ColorSpace) ? (ColorSpace)destination
-                : new ICC_ColorSpace((ICC_Profile)destination);
-
-        ColorModel srcCM = src.getColorModel();
-        ColorModel dstCM = new ComponentColorModel(dstCS, srcCM.hasAlpha(), srcCM
-                .isAlphaPremultiplied(), srcCM.getTransparency(), srcCM.getTransferType());
-
-        return new BufferedImage(dstCM, destCM.createCompatibleWritableRaster(src.getWidth(), src
-                .getHeight()), destCM.isAlphaPremultiplied(), null);
-    }
-
-    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
-        if (dst == null && conversionSequence.length < 1) {
-            throw new IllegalArgumentException(Messages.getString("awt.262")); //$NON-NLS-1$
-        }
-
-        ColorModel srcCM = src.getColorModel();
-        // First handle index color model
-        if (srcCM instanceof IndexColorModel) {
-            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), false);
-        }
-        ColorSpace srcCS = srcCM.getColorSpace();
-
-        BufferedImage res;
-        boolean isDstIndex = false;
-        if (dst != null) {
-
-            if (src.getWidth() != dst.getWidth() || src.getHeight() != dst.getHeight()) {
-                throw new IllegalArgumentException(Messages.getString("awt.263")); //$NON-NLS-1$
-            }
-
-            if (dst.getColorModel() instanceof IndexColorModel) {
-                isDstIndex = true;
-                res = createCompatibleDestImage(src, null);
-            } else {
-                res = dst;
-            }
-        } else {
-            res = createCompatibleDestImage(src, null);
-        }
-        ColorModel dstCM = res.getColorModel();
-        ColorSpace dstCS = dstCM.getColorSpace();
-
-        ICC_Profile srcPf = null, dstPf = null;
-        if (srcCS instanceof ICC_ColorSpace) {
-            srcPf = ((ICC_ColorSpace)srcCS).getProfile();
-        }
-        if (dstCS instanceof ICC_ColorSpace) {
-            dstPf = ((ICC_ColorSpace)dstCS).getProfile();
-        }
-
-        boolean isFullICC = isICC && srcPf != null && dstPf != null;
-
-        if (isFullICC) {
-            ICC_Transform t = tCreator
-                    .getTransform(srcPf, dstPf, (ICC_Profile[])conversionSequence);
-            cc.translateColor(t, src, res);
-        } else { // Perform non-ICC transform
-            Object sequence[] = tCreator.getSequence(srcPf == null ? (Object)srcCS : srcPf,
-                    dstPf == null ? (Object)dstCS : dstPf);
-
-            int srcW = src.getWidth();
-            int srcH = src.getHeight();
-            int numPixels = srcW * srcH;
-
-            // Load all pixel data into array tmpData
-            float tmpData[][] = new float[numPixels][tCreator.maxComponents];
-            for (int row = 0, dataPos = 0; row < srcW; row++) {
-                for (int col = 0; col < srcH; col++) {
-                    tmpData[dataPos] = srcCM.getNormalizedComponents(src.getRaster()
-                            .getDataElements(row, col, null), tmpData[dataPos], 0);
-                    dataPos++;
-                }
-            }
-
-            // Copy alpha channel if needed
-            float alpha[] = null;
-            int alphaIdx = srcCM.numComponents - 1;
-            if (srcCM.hasAlpha() && dstCM.hasAlpha()) {
-                alpha = new float[numPixels];
-                for (int i = 0; i < numPixels; i++) {
-                    alpha[i] = tmpData[i][alphaIdx];
-                }
-            }
-
-            // Translate colors
-            applySequence(sequence, tmpData, srcCS, dstCS);
-
-            // Copy alpha if needed
-            if (dstCM.hasAlpha()) {
-                alphaIdx = dstCM.numComponents - 1;
-                if (alpha != null) {
-                    for (int i = 0; i < numPixels; i++) {
-                        tmpData[i][alphaIdx] = alpha[i];
-                    }
-                } else {
-                    for (int i = 0; i < numPixels; i++) {
-                        tmpData[i][alphaIdx] = 1f;
-                    }
-                }
-            }
-
-            // Store data back to the image
-            for (int row = 0, dataPos = 0; row < srcW; row++) {
-                for (int col = 0; col < srcH; col++) {
-                    res.getRaster().setDataElements(row, col,
-                            dstCM.getDataElements(tmpData[dataPos++], 0, null));
-                }
-            }
-        }
-
-        if (isDstIndex) { // Convert image into indexed color
-            Graphics2D g2d = dst.createGraphics();
-            g2d.drawImage(res, 0, 0, null);
-            g2d.dispose();
-            return dst;
-        }
-
-        return res;
-    }
-
-    /**
-     * Apply sequence.
-     * 
-     * @param sequence
-     *            the sequence.
-     * @param tmpData
-     *            the tmp data.
-     * @param srcCS
-     *            the src cs.
-     * @param dstCS
-     *            the dst cs.
-     */
-    private void applySequence(Object sequence[], float tmpData[][], ColorSpace srcCS,
-            ColorSpace dstCS) {
-        ColorSpace xyzCS = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
-
-        int numPixels = tmpData.length;
-
-        // First transform...
-        if (sequence[0] instanceof ICC_Transform) { // ICC
-            ICC_Transform t = (ICC_Transform)sequence[0];
-            cc.translateColor(t, tmpData, srcCS, xyzCS, numPixels);
-        } else { // non ICC
-            for (int k = 0; k < numPixels; k++) {
-                tmpData[k] = srcCS.toCIEXYZ(tmpData[k]);
-            }
-            cc.loadScalingData(xyzCS); // prepare for scaling XYZ
-        }
-
-        for (Object element : sequence) {
-            if (element instanceof ICC_Transform) {
-                ICC_Transform t = (ICC_Transform)element;
-                cc.translateColor(t, tmpData, null, null, numPixels);
-            } else {
-                ColorSpace cs = (ColorSpace)element;
-                for (int k = 0; k < numPixels; k++) {
-                    tmpData[k] = cs.fromCIEXYZ(tmpData[k]);
-                    tmpData[k] = cs.toCIEXYZ(tmpData[k]);
-                }
-            }
-        }
-
-        // Last transform...
-        if (sequence[sequence.length - 1] instanceof ICC_Transform) { // ICC
-            ICC_Transform t = (ICC_Transform)sequence[sequence.length - 1];
-            cc.translateColor(t, tmpData, xyzCS, dstCS, numPixels);
-        } else { // non ICC
-            for (int k = 0; k < numPixels; k++) {
-                tmpData[k] = dstCS.fromCIEXYZ(tmpData[k]);
-            }
-        }
-    }
-
-    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
-        if (dstPt != null) {
-            dstPt.setLocation(srcPt);
-            return dstPt;
-        }
-        return new Point2D.Float((float)srcPt.getX(), (float)srcPt.getY());
-    }
-
-    public WritableRaster createCompatibleDestRaster(Raster src) {
-        int nComps = 0;
-        int nSpaces = conversionSequence.length;
-
-        if (nSpaces < 2) {
-            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
-        }
-
-        Object lastCS = conversionSequence[nSpaces - 1];
-        if (lastCS instanceof ColorSpace) {
-            nComps = ((ColorSpace)lastCS).getNumComponents();
-        } else {
-            nComps = ((ICC_Profile)lastCS).getNumComponents();
-        }
-
-        // Calculate correct data type
-        int dstDataType = src.getDataBuffer().getDataType();
-        if (dstDataType != DataBuffer.TYPE_BYTE && dstDataType != DataBuffer.TYPE_SHORT) {
-            dstDataType = DataBuffer.TYPE_SHORT;
-        }
-
-        return Raster.createInterleavedRaster(dstDataType, src.getWidth(), src.getHeight(), nComps,
-                new Point(src.getMinX(), src.getMinY()));
-    }
-
-    public final Rectangle2D getBounds2D(Raster src) {
-        return src.getBounds();
-    }
-
-    public final Rectangle2D getBounds2D(BufferedImage src) {
-        return src.getRaster().getBounds();
-    }
-
-    /**
-     * Gets an array of ICC_Profiles objects which constructs this
-     * ColorConvertOp object or returns null if this ColorConvertOp is not
-     * constructed from array of ICC_Profiles.
-     * 
-     * @return an array of ICC_Profiles objects which constructs this
-     *         ColorConvertOp object or returns null if this ColorConvertOp is
-     *         not constructed from array of ICC_Profiles.
-     */
-    public final ICC_Profile[] getICC_Profiles() {
-        if (midProfiles != null) {
-            return midProfiles;
-        }
-        return null;
-    }
-
-    public final RenderingHints getRenderingHints() {
-        return renderingHints;
-    }
-}
diff --git a/awt/java/awt/image/ColorModel.java b/awt/java/awt/image/ColorModel.java
deleted file mode 100644
index 1b084e1..0000000
--- a/awt/java/awt/image/ColorModel.java
+++ /dev/null
@@ -1,964 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
-import java.util.Arrays;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The class ColorModel.
- * 
- * @since Android 1.0
- */
-public abstract class ColorModel implements Transparency {
-
-    /**
-     * The pixel_bits.
-     */
-    protected int pixel_bits; // Pixel length in bits
-
-    /**
-     * The transfer type.
-     */
-    protected int transferType;
-
-    /**
-     * The cs.
-     */
-    ColorSpace cs;
-
-    /**
-     * The has alpha.
-     */
-    boolean hasAlpha;
-
-    /**
-     * The is alpha premultiplied.
-     */
-    boolean isAlphaPremultiplied;
-
-    /**
-     * The transparency.
-     */
-    int transparency;
-
-    /**
-     * The num color components.
-     */
-    int numColorComponents;
-
-    /**
-     * The num components.
-     */
-    int numComponents;
-
-    /**
-     * The bits.
-     */
-    int[] bits; // Array of components masks
-
-    /**
-     * The max values.
-     */
-    int[] maxValues = null; // Max values that may be represent by color
-
-    // components
-
-    /**
-     * The max bit length.
-     */
-    int maxBitLength; // Max length color components in bits
-
-    /**
-     * The RG bdefault.
-     */
-    private static ColorModel RGBdefault;
-
-    /**
-     * Instantiates a new color model with the specified values.
-     * 
-     * @param pixel_bits
-     *            the pixel length in bits.
-     * @param bits
-     *            the array of component masks.
-     * @param cspace
-     *            the color space.
-     * @param hasAlpha
-     *            whether the color model has alpha.
-     * @param isAlphaPremultiplied
-     *            whether the alpha is pre-multiplied.
-     * @param transparency
-     *            the transparency strategy, @see java.awt.Transparency.
-     * @param transferType
-     *            the transfer type (primitive java type to use for the
-     *            components).
-     */
-    protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace, boolean hasAlpha,
-            boolean isAlphaPremultiplied, int transparency, int transferType) {
-
-        if (pixel_bits < 1) {
-            // awt.26B=The number of bits in the pixel values is less than 1
-            throw new IllegalArgumentException(Messages.getString("awt.26B")); //$NON-NLS-1$
-        }
-
-        if (bits == null) {
-            // awt.26C=bits is null
-            throw new NullPointerException(Messages.getString("awt.26C")); //$NON-NLS-1$
-        }
-
-        int sum = 0;
-        for (int element : bits) {
-            if (element < 0) {
-                // awt.26D=The elements in bits is less than 0
-                throw new IllegalArgumentException(Messages.getString("awt.26D")); //$NON-NLS-1$
-            }
-            sum += element;
-        }
-
-        if (sum < 1) {
-            // awt.26E=The sum of the number of bits in bits is less than 1
-            throw new NullPointerException(Messages.getString("awt.26E")); //$NON-NLS-1$
-        }
-
-        if (cspace == null) {
-            // awt.26F=The cspace is null
-            throw new IllegalArgumentException(Messages.getString("awt.26F")); //$NON-NLS-1$
-        }
-
-        if (transparency < Transparency.OPAQUE || transparency > Transparency.TRANSLUCENT) {
-            // awt.270=The transparency is not a valid value
-            throw new IllegalArgumentException(Messages.getString("awt.270")); //$NON-NLS-1$
-        }
-
-        this.pixel_bits = pixel_bits;
-        this.bits = bits.clone();
-
-        maxValues = new int[bits.length];
-        maxBitLength = 0;
-        for (int i = 0; i < maxValues.length; i++) {
-            maxValues[i] = (1 << bits[i]) - 1;
-            if (bits[i] > maxBitLength) {
-                maxBitLength = bits[i];
-            }
-        }
-
-        cs = cspace;
-        this.hasAlpha = hasAlpha;
-        this.isAlphaPremultiplied = isAlphaPremultiplied;
-        numColorComponents = cs.getNumComponents();
-
-        if (hasAlpha) {
-            numComponents = numColorComponents + 1;
-        } else {
-            numComponents = numColorComponents;
-        }
-
-        this.transparency = transparency;
-        this.transferType = transferType;
-
-    }
-
-    /**
-     * Instantiates a new color model with the specified pixel bit depth. The
-     * transferType is chosen based on the pixel bits, and the other data fields
-     * are given default values.
-     * 
-     * @param bits
-     *            the array of component masks.
-     */
-    public ColorModel(int bits) {
-
-        if (bits < 1) {
-            // awt.271=The number of bits in bits is less than 1
-            throw new IllegalArgumentException(Messages.getString("awt.271")); //$NON-NLS-1$
-        }
-
-        pixel_bits = bits;
-        transferType = getTransferType(bits);
-        cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-        hasAlpha = true;
-        isAlphaPremultiplied = false;
-        transparency = Transparency.TRANSLUCENT;
-
-        numColorComponents = 3;
-        numComponents = 4;
-
-        this.bits = null;
-    }
-
-    /**
-     * Gets the data elements from the specified component array, transforming
-     * them according to rules of the color model.
-     * 
-     * @param components
-     *            the components.
-     * @param offset
-     *            the offset in the normComponents array.
-     * @param obj
-     *            the array that the result is written to: an array of values
-     *            whose length must be the number of components used by the
-     *            color model and whose type depends on the transfer type (based
-     *            on the pixel bit depth), or null to have the appropriate array
-     *            created.
-     * @return the array of data elements.
-     */
-    public Object getDataElements(int[] components, int offset, Object obj) {
-        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
-                "supported by this ColorModel"); //$NON-NLS-1$
-    }
-
-    /**
-     * Gets the data elements from the specified array of normalized components.
-     * 
-     * @param normComponents
-     *            the array normalized components.
-     * @param normOffset
-     *            the offset in the normComponents array.
-     * @param obj
-     *            the array that the result is written to: an array of values
-     *            whose length must be the number of components used by the
-     *            color model and whose type depends on the transfer type (based
-     *            on the pixel bit depth), or null to have the appropriate array
-     *            created.
-     * @return the array of data elements.
-     */
-    public Object getDataElements(float[] normComponents, int normOffset, Object obj) {
-        int unnormComponents[] = getUnnormalizedComponents(normComponents, normOffset, null, 0);
-        return getDataElements(unnormComponents, 0, obj);
-    }
-
-    /**
-     * Gets the data elements corresponding to the pixel determined by the RGB
-     * data.
-     * 
-     * @param rgb
-     *            the RGB integer value that defines the pixel.
-     * @param pixel
-     *            the array that the result is written to: an array of values
-     *            whose length must be the number of components used by the
-     *            color model and whose type depends on the transfer type (based
-     *            on the pixel bit depth), or null to have the appropriate array
-     *            created.
-     * @return the array of data elements.
-     */
-    public Object getDataElements(int rgb, Object pixel) {
-        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
-                "supported by this ColorModel"); //$NON-NLS-1$
-    }
-
-    /**
-     * Gets the child raster corresponding to the alpha channel of the specified
-     * writable raster, or null if alpha is not supported.
-     * 
-     * @param raster
-     *            the raster.
-     * @return the alpha raster.
-     */
-    public WritableRaster getAlphaRaster(WritableRaster raster) {
-        return null;
-    }
-
-    /**
-     * Creates a new color model by coercing the data in the writable raster in
-     * accordance with the alpha strategy of this color model.
-     * 
-     * @param raster
-     *            the raster.
-     * @param isAlphaPremultiplied
-     *            whether the alpha is pre-multiplied in this color model
-     * @return the new color model.
-     */
-    public ColorModel coerceData(WritableRaster raster, boolean isAlphaPremultiplied) {
-        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
-                "supported by this ColorModel"); //$NON-NLS-1$
-    }
-
-    @Override
-    public String toString() {
-        // The output format based on 1.5 release behavior.
-        // It could be reveled such way:
-        // ColorModel cm = new
-        // ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB,
-        // false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
-        // System.out.println(cm.toString());
-        return "ColorModel: Color Space = " + cs.toString() + "; has alpha = " //$NON-NLS-1$ //$NON-NLS-2$
-                + hasAlpha + "; is alpha premultipied = " //$NON-NLS-1$
-                + isAlphaPremultiplied + "; transparency = " + transparency //$NON-NLS-1$
-                + "; number color components = " + numColorComponents //$NON-NLS-1$
-                + "; pixel bits = " + pixel_bits + "; transfer type = " //$NON-NLS-1$ //$NON-NLS-2$
-                + transferType;
-    }
-
-    /**
-     * Gets the components of the pixel determined by the data array.
-     * 
-     * @param pixel
-     *            the data array that defines the pixel (whose primitive type
-     *            corresponds to the pixel length in bits.
-     * @see ColorModel#getTransferType()
-     * @param components
-     *            the the array where the resulting components are written (or
-     *            null to prompt the method to create the return array).
-     * @param offset
-     *            the offset that tells where the results should be written in
-     *            the return array.
-     * @return the array of components.
-     */
-    public int[] getComponents(Object pixel, int[] components, int offset) {
-        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
-                "supported by this ColorModel"); //$NON-NLS-1$
-    }
-
-    /**
-     * Gets the normalized components of the pixel determined by the data array.
-     * 
-     * @param pixel
-     *            the data array that defines the pixel (whose primitive type
-     *            corresponds to the pixel length in bits.
-     * @see ColorModel#getTransferType()
-     * @param normComponents
-     *            the array where the resulting normalized components are
-     *            written (or null to prompt the method to create the return
-     *            array).
-     * @param normOffset
-     *            the offset that tells where the results should be written in
-     *            the return array.
-     * @return the array of normalized components.
-     */
-    public float[] getNormalizedComponents(Object pixel, float[] normComponents, int normOffset) {
-
-        if (pixel == null) {
-            // awt.294=pixel is null
-            throw new NullPointerException(Messages.getString("awt.294")); //$NON-NLS-1$
-        }
-
-        int unnormComponents[] = getComponents(pixel, null, 0);
-        return getNormalizedComponents(unnormComponents, 0, normComponents, normOffset);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof ColorModel)) {
-            return false;
-        }
-        ColorModel cm = (ColorModel)obj;
-
-        return (pixel_bits == cm.getPixelSize() && transferType == cm.getTransferType()
-                && cs.getType() == cm.getColorSpace().getType() && hasAlpha == cm.hasAlpha()
-                && isAlphaPremultiplied == cm.isAlphaPremultiplied()
-                && transparency == cm.getTransparency()
-                && numColorComponents == cm.getNumColorComponents()
-                && numComponents == cm.getNumComponents() && Arrays.equals(bits, cm
-                .getComponentSize()));
-    }
-
-    /**
-     * Gets the red component of the pixel determined by the data array.
-     * 
-     * @param inData
-     *            the data array that defines the pixel (whose primitive type
-     *            corresponds to the pixel length in bits.
-     * @see ColorModel#getTransferType()
-     * @return the red.
-     */
-    public int getRed(Object inData) {
-        return getRed(constructPixel(inData));
-    }
-
-    /**
-     * Gets the RGB integer value corresponding to the pixel defined by the data
-     * array.
-     * 
-     * @param inData
-     *            the data array that defines the pixel (whose primitive type
-     *            corresponds to the pixel length in bits.
-     * @see ColorModel#getTransferType()
-     * @return the integer value that gives the pixel's colors in RGB format.
-     */
-    public int getRGB(Object inData) {
-        return (getAlpha(inData) << 24 | getRed(inData) << 16 | getGreen(inData) << 8 | getBlue(inData));
-    }
-
-    /**
-     * Gets the green component of the pixel defined by the data array.
-     * 
-     * @param inData
-     *            the data array that defines the pixel (whose primitive type
-     *            corresponds to the pixel length in bits.
-     * @see ColorModel#getTransferType()
-     * @return the green.
-     */
-    public int getGreen(Object inData) {
-        return getGreen(constructPixel(inData));
-    }
-
-    /**
-     * Gets the blue component of the pixel defined by the data array.
-     * 
-     * @param inData
-     *            the data array that defines the pixel (whose primitive type
-     *            corresponds to the pixel length in bits.
-     * @see ColorModel#getTransferType()
-     * @return the blue.
-     */
-    public int getBlue(Object inData) {
-        return getBlue(constructPixel(inData));
-    }
-
-    /**
-     * Gets the alpha component of the pixel defined by the data array.
-     * 
-     * @param inData
-     *            the data array that defines the pixel (whose primitive type
-     *            corresponds to the pixel length in bits.
-     * @see ColorModel#getTransferType()
-     * @return the alpha.
-     */
-    public int getAlpha(Object inData) {
-        return getAlpha(constructPixel(inData));
-    }
-
-    /**
-     * Creates a compatible writable raster.
-     * 
-     * @param w
-     *            the width of the desired writable raster.
-     * @param h
-     *            the height of the desired writable raster.
-     * @return the writable raster.
-     */
-    public WritableRaster createCompatibleWritableRaster(int w, int h) {
-        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
-                "supported by this ColorModel"); //$NON-NLS-1$
-    }
-
-    /**
-     * Checks if the sample model is compatible with this color model.
-     * 
-     * @param sm
-     *            the sample model.
-     * @return true, if the sample model is compatible with this color model.
-     */
-    public boolean isCompatibleSampleModel(SampleModel sm) {
-        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
-                "supported by this ColorModel"); //$NON-NLS-1$
-    }
-
-    /**
-     * Creates the compatible sample model.
-     * 
-     * @param w
-     *            the width of the desired sample model.
-     * @param h
-     *            the height of the desired sample model.
-     * @return the sample model.
-     */
-    public SampleModel createCompatibleSampleModel(int w, int h) {
-        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
-                "supported by this ColorModel"); //$NON-NLS-1$
-    }
-
-    /**
-     * Checks if the specified raster is compatible with this color model.
-     * 
-     * @param raster
-     *            the raster to inspect.
-     * @return true, if the raster is compatible with this color model.
-     */
-    public boolean isCompatibleRaster(Raster raster) {
-        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
-                "supported by this ColorModel"); //$NON-NLS-1$
-    }
-
-    /**
-     * Gets the color space of this color model.
-     * 
-     * @return the color space.
-     */
-    public final ColorSpace getColorSpace() {
-        return cs;
-    }
-
-    /**
-     * Gets the normalized components corresponding to the specified
-     * unnormalized components.
-     * 
-     * @param components
-     *            the array of unnormalized components.
-     * @param offset
-     *            the offset where the components should be read from the array
-     *            of unnormalized components.
-     * @param normComponents
-     *            the array where the resulting normalized components are
-     *            written (or null to prompt the method to create the return
-     *            array).
-     * @param normOffset
-     *            the offset that tells where the results should be written in
-     *            the return array.
-     * @return the normalized components.
-     */
-    public float[] getNormalizedComponents(int[] components, int offset, float normComponents[],
-            int normOffset) {
-        if (bits == null) {
-            // awt.26C=bits is null
-            throw new UnsupportedOperationException(Messages.getString("awt.26C")); //$NON-NLS-1$
-        }
-
-        if (normComponents == null) {
-            normComponents = new float[numComponents + normOffset];
-        }
-
-        if (hasAlpha && isAlphaPremultiplied) {
-            float normAlpha = (float)components[offset + numColorComponents]
-                    / maxValues[numColorComponents];
-            if (normAlpha != 0.0f) {
-                for (int i = 0; i < numColorComponents; i++) {
-                    normComponents[normOffset + i] = components[offset + i]
-                            / (normAlpha * maxValues[i]);
-                }
-                normComponents[normOffset + numColorComponents] = normAlpha;
-            } else {
-                for (int i = 0; i < numComponents; i++) {
-                    normComponents[normOffset + i] = 0.0f;
-                }
-            }
-        } else {
-            for (int i = 0; i < numComponents; i++) {
-                normComponents[normOffset + i] = (float)components[offset + i] / maxValues[i];
-            }
-        }
-
-        return normComponents;
-    }
-
-    /**
-     * Gets the data element corresponding to the unnormalized components.
-     * 
-     * @param components
-     *            the components.
-     * @param offset
-     *            the offset to start reading the components from the array of
-     *            components.
-     * @return the data element.
-     */
-    public int getDataElement(int[] components, int offset) {
-        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
-                "supported by this ColorModel"); //$NON-NLS-1$
-    }
-
-    /**
-     * Gets the unnormalized components corresponding to the specified
-     * normalized components.
-     * 
-     * @param normComponents
-     *            the array of normalized components.
-     * @param normOffset
-     *            the offset where the components should be read from the array
-     *            of normalized components.
-     * @param components
-     *            the array where the resulting unnormalized components are
-     *            written (or null to prompt the method to create the return
-     *            array).
-     * @param offset
-     *            the offset that tells where the results should be written in
-     *            the return array.
-     * @return the unnormalized components.
-     */
-    public int[] getUnnormalizedComponents(float normComponents[], int normOffset,
-            int components[], int offset) {
-
-        if (bits == null) {
-            // awt.26C=bits is null
-            throw new UnsupportedOperationException(Messages.getString("awt.26C")); //$NON-NLS-1$
-        }
-
-        if (normComponents.length - normOffset < numComponents) {
-            // awt.273=The length of normComponents minus normOffset is less
-            // than numComponents
-            throw new IllegalArgumentException(Messages.getString("awt.273")); //$NON-NLS-1$
-        }
-
-        if (components == null) {
-            components = new int[numComponents + offset];
-        } else {
-            if (components.length - offset < numComponents) {
-                // awt.272=The length of components minus offset is less than
-                // numComponents
-                throw new IllegalArgumentException(Messages.getString("awt.272")); //$NON-NLS-1$
-            }
-        }
-
-        if (hasAlpha && isAlphaPremultiplied) {
-            float alpha = normComponents[normOffset + numColorComponents];
-            for (int i = 0; i < numColorComponents; i++) {
-                components[offset + i] = (int)(normComponents[normOffset + i] * maxValues[i]
-                        * alpha + 0.5f);
-            }
-            components[offset + numColorComponents] = (int)(normComponents[normOffset
-                    + numColorComponents]
-                    * maxValues[numColorComponents] + 0.5f);
-        } else {
-            for (int i = 0; i < numComponents; i++) {
-                components[offset + i] = (int)(normComponents[normOffset + i] * maxValues[i] + 0.5f);
-            }
-        }
-
-        return components;
-    }
-
-    /**
-     * Gets the data element corresponding to the normalized components.
-     * 
-     * @param normComponents
-     *            the normalized components.
-     * @param normOffset
-     *            the offset where the normalized components should be read from
-     *            the normalized component array.
-     * @return the data element.
-     */
-    public int getDataElement(float normComponents[], int normOffset) {
-        int unnormComponents[] = getUnnormalizedComponents(normComponents, normOffset, null, 0);
-        return getDataElement(unnormComponents, 0);
-    }
-
-    /**
-     * Takes a pixel whose data is defined by an integer, and writes the
-     * corresponding components into the components array, starting from the
-     * index offset.
-     * 
-     * @param pixel
-     *            the pixel data.
-     * @param components
-     *            the data array to write the components to (or null to have the
-     *            method create the return array).
-     * @param offset
-     *            the offset that determines where the results are written in
-     *            the components array.
-     * @return the array of components corresponding to the pixel.
-     */
-    public int[] getComponents(int pixel, int components[], int offset) {
-        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
-                "supported by this ColorModel"); //$NON-NLS-1$
-    }
-
-    /**
-     * Gets the red component of the pixel determined by the pixel data.
-     * 
-     * @param pixel
-     *            the pixel.
-     * @return the red component of the given pixel.
-     */
-    public abstract int getRed(int pixel);
-
-    /**
-     * Takes the pixel data and returns the integer value corresponding to the
-     * pixel's color in RGB format.
-     * 
-     * @param pixel
-     *            the pixel data.
-     * @return the corresponding RGB integer value.
-     */
-    public int getRGB(int pixel) {
-        return (getAlpha(pixel) << 24 | getRed(pixel) << 16 | getGreen(pixel) << 8 | getBlue(pixel));
-    }
-
-    /**
-     * Gets the green component of the pixel determined by the pixel data.
-     * 
-     * @param pixel
-     *            the pixel.
-     * @return the green component of the given pixel.
-     */
-    public abstract int getGreen(int pixel);
-
-    /**
-     * Gets the size of the desired component of this color model.
-     * 
-     * @param componentIdx
-     *            the index that determines which component size to get.
-     * @return the component size corresponding to the index.
-     * @throws NullPointerException
-     *             if this color model doesn't support an array of separate
-     *             components.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if the index is negative or greater than or equal to the
-     *             number of components.
-     */
-    public int getComponentSize(int componentIdx) {
-        if (bits == null) {
-            // awt.26C=bits is null
-            throw new NullPointerException(Messages.getString("awt.26C")); //$NON-NLS-1$
-        }
-
-        if (componentIdx < 0 || componentIdx >= bits.length) {
-            // awt.274=componentIdx is greater than the number of components or
-            // less than zero
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.274")); //$NON-NLS-1$
-        }
-
-        return bits[componentIdx];
-    }
-
-    /**
-     * Gets the blue component of the pixel determined by the pixel data.
-     * 
-     * @param pixel
-     *            the pixel.
-     * @return the blue component of the given pixel.
-     */
-    public abstract int getBlue(int pixel);
-
-    /**
-     * Gets the alpha component of the pixel determined by the pixel data.
-     * 
-     * @param pixel
-     *            the pixel.
-     * @return the alpha component of the given pixel.
-     */
-    public abstract int getAlpha(int pixel);
-
-    /**
-     * Gets the array of sizes of the different components.
-     * 
-     * @return the array of sizes of the different components.
-     */
-    public int[] getComponentSize() {
-        if (bits != null) {
-            return bits.clone();
-        }
-        return null;
-    }
-
-    /**
-     * Checks if the alpha component is pre-multiplied.
-     * 
-     * @return true, if the alpha component is pre-multiplied.
-     */
-    public final boolean isAlphaPremultiplied() {
-        return isAlphaPremultiplied;
-    }
-
-    /**
-     * Checks whether this color model supports alpha.
-     * 
-     * @return true, if this color model has alpha.
-     */
-    public final boolean hasAlpha() {
-        return hasAlpha;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 0;
-        int tmp;
-
-        if (hasAlpha) {
-            hash ^= 1;
-            hash <<= 8;
-        }
-        if (isAlphaPremultiplied) {
-            hash ^= 1;
-            hash <<= 8;
-        }
-
-        tmp = hash >>> 24;
-        hash ^= numColorComponents;
-        hash <<= 8;
-        hash |= tmp;
-
-        tmp = hash >>> 24;
-        hash ^= transparency;
-        hash <<= 8;
-        hash |= tmp;
-
-        tmp = hash >>> 24;
-        hash ^= cs.getType();
-        hash <<= 8;
-        hash |= tmp;
-
-        tmp = hash >>> 24;
-        hash ^= pixel_bits;
-        hash <<= 8;
-        hash |= tmp;
-
-        tmp = hash >>> 24;
-        hash ^= transferType;
-        hash <<= 8;
-        hash |= tmp;
-
-        if (bits != null) {
-
-            for (int element : bits) {
-                tmp = hash >>> 24;
-                hash ^= element;
-                hash <<= 8;
-                hash |= tmp;
-            }
-
-        }
-
-        return hash;
-    }
-
-    public int getTransparency() {
-        return transparency;
-    }
-
-    /**
-     * Gets the transfer type, which is the type of Java primitive value that
-     * corresponds to the bit length per pixel: either
-     * {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT},
-     * {@link DataBuffer#TYPE_INT}, or {@link DataBuffer#TYPE_UNDEFINED}.
-     * 
-     * @return the transfer type.
-     */
-    public final int getTransferType() {
-        return transferType;
-    }
-
-    /**
-     * Gets the pixel size in bits.
-     * 
-     * @return the pixel size.
-     */
-    public int getPixelSize() {
-        return pixel_bits;
-    }
-
-    /**
-     * Gets the number of components of this color model.
-     * 
-     * @return the number of components.
-     */
-    public int getNumComponents() {
-        return numComponents;
-    }
-
-    /**
-     * Gets the number of color components of this color model.
-     * 
-     * @return the number color components.
-     */
-    public int getNumColorComponents() {
-        return numColorComponents;
-    }
-
-    /**
-     * Gets the default RGB color model.
-     * 
-     * @return the default RGB color model.
-     */
-    public static ColorModel getRGBdefault() {
-        if (RGBdefault == null) {
-            RGBdefault = new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
-        }
-        return RGBdefault;
-    }
-
-    /*
-     * Construct INT pixel representation from Object
-     * @param obj
-     * @return
-     */
-    /**
-     * Construct pixel.
-     * 
-     * @param obj
-     *            the obj.
-     * @return the int.
-     */
-    private int constructPixel(Object obj) {
-        int pixel = 0;
-
-        switch (getTransferType()) {
-
-            case DataBuffer.TYPE_BYTE:
-                byte[] bPixel = (byte[])obj;
-                if (bPixel.length > 1) {
-                    // awt.275=This pixel representation is not suuported by tis
-                    // Color Model
-                    throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
-                }
-                pixel = bPixel[0] & 0xff;
-                break;
-
-            case DataBuffer.TYPE_USHORT:
-                short[] sPixel = (short[])obj;
-                if (sPixel.length > 1) {
-                    // awt.275=This pixel representation is not suuported by tis
-                    // Color Model
-                    throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
-                }
-                pixel = sPixel[0] & 0xffff;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int[] iPixel = (int[])obj;
-                if (iPixel.length > 1) {
-                    // awt.275=This pixel representation is not suuported by tis
-                    // Color Model
-                    throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
-                }
-                pixel = iPixel[0];
-                break;
-
-            default:
-                // awt.22D=This transferType ( {0} ) is not supported by this
-                // color model
-                throw new UnsupportedOperationException(Messages.getString("awt.22D", //$NON-NLS-1$
-                        transferType));
-
-        }
-        return pixel;
-    }
-
-    /**
-     * Gets the transfer type, which is the type of Java primitive value that
-     * corresponds to the bit length per pixel: either
-     * {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT},
-     * {@link DataBuffer#TYPE_INT}, or {@link DataBuffer#TYPE_UNDEFINED}.
-     * 
-     * @param bits
-     *            the array of component masks.
-     * @return the transfer type.
-     */
-    static int getTransferType(int bits) {
-        if (bits <= 8) {
-            return DataBuffer.TYPE_BYTE;
-        } else if (bits <= 16) {
-            return DataBuffer.TYPE_USHORT;
-        } else if (bits <= 32) {
-            return DataBuffer.TYPE_INT;
-        } else {
-            return DataBuffer.TYPE_UNDEFINED;
-        }
-    }
-
-    @Override
-    public void finalize() {
-        // This method is added for the API compatibility
-        // Don't need to call super since Object's finalize is always empty
-    }
-}
diff --git a/awt/java/awt/image/ComponentColorModel.java b/awt/java/awt/image/ComponentColorModel.java
deleted file mode 100644
index 4328fd3..0000000
--- a/awt/java/awt/image/ComponentColorModel.java
+++ /dev/null
@@ -1,1482 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.color.ColorSpace;
-
-import org.apache.harmony.awt.gl.color.LUTColorConverter;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class ComponentColorModel represents a color model that is defined in
- * terms of its components.
- * 
- * @since Android 1.0
- */
-public class ComponentColorModel extends ColorModel {
-
-    /**
-     * The signed.
-     */
-    private boolean signed; // Pixel samples are signed.
-
-    // Samples with TransferType DataBuffer.TYPE_BYTE,
-    // DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT -
-    // unsigned. Samples with others TransferType -
-    // signed.
-
-    /**
-     * The integral.
-     */
-    private boolean integral; // Pixel samples are integral.
-
-    // Samples with TransferType DataBuffer.TYPE_BYTE,
-    // DataBuffer.TYPE_USHORT, DataBuffer.Short and
-    // DataBuffer.TYPE_INT - integral.
-
-    /**
-     * The scale factors.
-     */
-    private float scaleFactors[]; // Array of factors for reduction components
-
-    // values into the form scaled from 0 to 255
-
-    /**
-     * The donot support unnormalized.
-     */
-    private boolean donotSupportUnnormalized; // This Color Model don't support
-
-    // unnormolized form
-
-    /**
-     * The need alpha divide.
-     */
-    private boolean needAlphaDivide; // hasAlpha && isAlphaPremultiplied
-
-    /**
-     * The calc value.
-     */
-    private boolean calcValue; // Value was culculated
-
-    /**
-     * The need scale.
-     */
-    private boolean needScale; // Normalized value need to scale
-
-    /**
-     * The min vals.
-     */
-    private float minVals[]; // Array of Min normalized values
-
-    /**
-     * The ranges.
-     */
-    private float ranges[]; // Array of range normalized values
-
-    /**
-     * The alpha lut.
-     */
-    private byte alphaLUT[]; // Lookup table for scale alpha value
-
-    /**
-     * The color lu ts.
-     */
-    private byte colorLUTs[][]; // Lookup tables for scale color values
-
-    /**
-     * The from_ linea r_ rg b_ lut.
-     */
-    private byte from_LINEAR_RGB_LUT[]; // Lookup table for conversion from
-
-    // Linear RGB Color Space into sRGB
-
-    /**
-     * The to_ linea r_8 rg b_ lut.
-     */
-    private byte to_LINEAR_8RGB_LUT[]; // Lookup table for conversion from
-
-    // sRGB Color Space into Linear RGB
-    // 8 bit
-
-    /**
-     * The to_ linea r_16 rg b_ lut.
-     */
-    private short to_LINEAR_16RGB_LUT[]; // Lookup table for conversion from
-
-    // sRGB Color Space into Linear RGB
-    // 16 bit
-
-    /**
-     * The LINEA r_ rg b_ length.
-     */
-    private int LINEAR_RGB_Length; // Linear RGB bit length
-
-    /**
-     * The factor.
-     */
-    private float fFactor; // Scale factor
-
-    /**
-     * The is_s rgb.
-     */
-    private boolean is_sRGB; // ColorModel has sRGB ColorSpace
-
-    /**
-     * The is_ linea r_ rgb.
-     */
-    private boolean is_LINEAR_RGB; // Color Model has Linear RGB Color
-
-    // Space
-
-    /**
-     * Instantiates a new component color model.
-     * 
-     * @param colorSpace
-     *            the color space.
-     * @param bits
-     *            the array of component masks.
-     * @param hasAlpha
-     *            whether the color model has alpha.
-     * @param isAlphaPremultiplied
-     *            whether the alpha is pre-multiplied.
-     * @param transparency
-     *            the transparency strategy, @see java.awt.Transparency.
-     * @param transferType
-     *            the transfer type (primitive java type to use for the
-     *            components).
-     */
-    public ComponentColorModel(ColorSpace colorSpace, int bits[], boolean hasAlpha,
-            boolean isAlphaPremultiplied, int transparency, int transferType) {
-        super(createPixelBits(colorSpace, hasAlpha, transferType), validateBits(bits, colorSpace,
-                hasAlpha, transferType), colorSpace, hasAlpha, isAlphaPremultiplied, transparency,
-                transferType);
-
-        needScale = false;
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-            case DataBuffer.TYPE_USHORT:
-            case DataBuffer.TYPE_INT:
-                signed = false;
-                integral = true;
-                donotSupportUnnormalized = false;
-                scaleFactors = new float[numComponents];
-                for (int i = 0; i < numColorComponents; i++) {
-                    scaleFactors[i] = 1.0f / maxValues[i];
-                    if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
-                        donotSupportUnnormalized = true;
-                    }
-                }
-                if (hasAlpha) {
-                    maxValues[numColorComponents] = (1 << bits[numColorComponents]) - 1;
-                    scaleFactors[numColorComponents] = 1.0f / maxValues[numColorComponents];
-                }
-                break;
-            case DataBuffer.TYPE_SHORT:
-                signed = true;
-                integral = true;
-                donotSupportUnnormalized = true;
-                scaleFactors = new float[numComponents];
-                for (int i = 0; i < numComponents; i++) {
-                    maxValues[i] = Short.MAX_VALUE;
-                    scaleFactors[i] = 1.0f / maxValues[i];
-                    if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
-                        needScale = true;
-                    }
-                }
-                if (needScale) {
-                    minVals = new float[numColorComponents];
-                    ranges = new float[numColorComponents];
-                    for (int i = 0; i < numColorComponents; i++) {
-                        minVals[i] = cs.getMinValue(i);
-                        ranges[i] = cs.getMaxValue(i) - minVals[i];
-                    }
-                }
-                break;
-            case DataBuffer.TYPE_FLOAT:
-            case DataBuffer.TYPE_DOUBLE:
-                signed = true;
-                integral = false;
-                donotSupportUnnormalized = true;
-                break;
-            default:
-                // awt.215=transferType is not one of DataBuffer.TYPE_BYTE,
-                // DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
-                // DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
-                // DataBuffer.TYPE_DOUBLE
-                throw new IllegalArgumentException(Messages.getString("awt.215")); //$NON-NLS-1$
-        }
-
-        needAlphaDivide = hasAlpha && isAlphaPremultiplied;
-        initLUTs();
-    }
-
-    /**
-     * Instantiates a new component color model.
-     * 
-     * @param colorSpace
-     *            the color space.
-     * @param hasAlpha
-     *            whether the color model has alpha.
-     * @param isAlphaPremultiplied
-     *            whether the alpha is pre-multiplied.
-     * @param transparency
-     *            the transparency strategy, @see java.awt.Transparency.
-     * @param transferType
-     *            the transfer type (primitive java type to use for the
-     *            components).
-     */
-    public ComponentColorModel(ColorSpace colorSpace, boolean hasAlpha,
-            boolean isAlphaPremultiplied, int transparency, int transferType) {
-
-        this(colorSpace, createPixelBitsArray(colorSpace, hasAlpha, transferType), hasAlpha,
-                isAlphaPremultiplied, transparency, transferType);
-    }
-
-    /**
-     * Validate bits.
-     * 
-     * @param bits
-     *            the bits.
-     * @param colorSpace
-     *            the color space.
-     * @param hasAlpha
-     *            the has alpha.
-     * @param transferType
-     *            the transfer type.
-     * @return the int[].
-     */
-    private static int[] validateBits(int bits[], ColorSpace colorSpace, boolean hasAlpha,
-            int transferType) {
-        if (bits != null) {
-            return bits;
-        }
-
-        int numComponents = colorSpace.getNumComponents();
-        if (hasAlpha) {
-            numComponents++;
-        }
-        bits = new int[numComponents];
-
-        int componentLength = DataBuffer.getDataTypeSize(transferType);
-
-        for (int i = 0; i < numComponents; i++) {
-            bits[i] = componentLength;
-        }
-
-        return bits;
-    }
-
-    /**
-     * Creates the pixel bits.
-     * 
-     * @param colorSpace
-     *            the color space.
-     * @param hasAlpha
-     *            the has alpha.
-     * @param transferType
-     *            the transfer type.
-     * @return the int.
-     */
-    private static int createPixelBits(ColorSpace colorSpace, boolean hasAlpha, int transferType) {
-        int numComponents = colorSpace.getNumComponents();
-        if (hasAlpha) {
-            numComponents++;
-        }
-        int componentLength = DataBuffer.getDataTypeSize(transferType);
-        return numComponents * componentLength;
-    }
-
-    /**
-     * Creates the pixel bits array.
-     * 
-     * @param colorSpace
-     *            the color space.
-     * @param hasAlpha
-     *            the has alpha.
-     * @param transferType
-     *            the transfer type.
-     * @return the int[].
-     */
-    private static int[] createPixelBitsArray(ColorSpace colorSpace, boolean hasAlpha,
-            int transferType) {
-
-        int numComponents = colorSpace.getNumComponents();
-        if (hasAlpha) {
-            numComponents++;
-        }
-
-        int bits[] = new int[numComponents];
-        for (int i = 0; i < numComponents; i++) {
-            bits[i] = DataBuffer.getDataTypeSize(transferType);
-        }
-        return bits;
-    }
-
-    @Override
-    public Object getDataElements(int components[], int offset, Object obj) {
-        if (donotSupportUnnormalized) {
-            // awt.213=This ComponentColorModel does not support the
-            // unnormalized form
-            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
-        }
-
-        if (offset + numComponents > components.length) {
-            // awt.216=The components array is not large enough to hold all the
-            // color and alpha components
-            throw new IllegalArgumentException(Messages.getString("awt.216")); //$NON-NLS-1$
-        }
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[];
-                if (obj == null) {
-                    ba = new byte[numComponents];
-                } else {
-                    ba = (byte[])obj;
-                }
-                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
-                    ba[i] = (byte)components[idx];
-                }
-                return ba;
-            case DataBuffer.TYPE_USHORT:
-                short sa[];
-                if (obj == null) {
-                    sa = new short[numComponents];
-                } else {
-                    sa = (short[])obj;
-                }
-                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
-                    sa[i] = (short)components[idx];
-                }
-                return sa;
-            case DataBuffer.TYPE_INT:
-                int ia[];
-                if (obj == null) {
-                    ia = new int[numComponents];
-                } else {
-                    ia = (int[])obj;
-                }
-                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
-                    ia[i] = components[idx];
-                }
-                return ia;
-            default:
-                // awt.217=The transfer type of this ComponentColorModel is not
-                // one
-                // of the following transfer types: DataBuffer.TYPE_BYTE,
-                // DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
-                throw new UnsupportedOperationException(Messages.getString("awt.217")); //$NON-NLS-1$
-        }
-    }
-
-    @Override
-    public Object getDataElements(float normComponents[], int normOffset, Object obj) {
-        if (needScale) {
-            for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
-                normComponents[idx] = (normComponents[idx] - minVals[i]) / ranges[i];
-            }
-        }
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[];
-                if (obj == null) {
-                    ba = new byte[numComponents];
-                } else {
-                    ba = (byte[])obj;
-                }
-
-                if (needAlphaDivide) {
-                    float alpha = normComponents[normOffset + numColorComponents];
-                    for (int i = 0, idx = normOffset; i < numColorComponents; i++, idx++) {
-                        ba[i] = (byte)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
-                    }
-                    ba[numColorComponents] = (byte)(normComponents[normOffset + numColorComponents]
-                            * maxValues[numColorComponents] + 0.5f);
-                } else {
-                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                        ba[idx] = (byte)(normComponents[idx] * maxValues[i] + 0.5f);
-                    }
-                }
-                return ba;
-
-            case DataBuffer.TYPE_USHORT:
-                short usa[];
-                if (obj == null) {
-                    usa = new short[numComponents];
-                } else {
-                    usa = (short[])obj;
-                }
-
-                if (needAlphaDivide) {
-                    float alpha = normComponents[normOffset + numColorComponents];
-                    for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
-                        usa[i] = (short)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
-                    }
-                    usa[numColorComponents] = (short)(alpha * maxValues[numColorComponents] + 0.5f);
-                } else {
-                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                        usa[i] = (short)(normComponents[idx] * maxValues[i] + 0.5f);
-                    }
-                }
-                return usa;
-
-            case DataBuffer.TYPE_INT:
-                int ia[];
-                if (obj == null) {
-                    ia = new int[numComponents];
-                } else {
-                    ia = (int[])obj;
-                }
-
-                if (needAlphaDivide) {
-                    float alpha = normComponents[normOffset + numColorComponents];
-                    for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
-                        ia[i] = (int)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
-                    }
-                    ia[numColorComponents] = (int)(alpha * maxValues[numColorComponents] + 0.5f);
-                } else {
-                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                        ia[i] = (int)(normComponents[idx] * maxValues[i] + 0.5f);
-                    }
-                }
-                return ia;
-
-            case DataBuffer.TYPE_SHORT:
-                short sa[];
-                if (obj == null) {
-                    sa = new short[numComponents];
-                } else {
-                    sa = (short[])obj;
-                }
-
-                if (needAlphaDivide) {
-                    float alpha = normComponents[normOffset + numColorComponents];
-                    for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
-                        sa[i] = (short)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
-                    }
-                    sa[numColorComponents] = (short)(alpha * maxValues[numColorComponents] + 0.5f);
-                } else {
-                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                        sa[i] = (short)(normComponents[idx] * maxValues[i] + 0.5f);
-                    }
-                }
-                return sa;
-
-            case DataBuffer.TYPE_FLOAT:
-                float fa[];
-                if (obj == null) {
-                    fa = new float[numComponents];
-                } else {
-                    fa = (float[])obj;
-                }
-
-                if (needAlphaDivide) {
-                    float alpha = normComponents[normOffset + numColorComponents];
-                    for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
-                        fa[i] = normComponents[idx] * alpha;
-                    }
-                    fa[numColorComponents] = alpha;
-                } else {
-                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                        fa[i] = normComponents[idx];
-                    }
-                }
-                return fa;
-
-            case DataBuffer.TYPE_DOUBLE:
-                double da[];
-                if (obj == null) {
-                    da = new double[numComponents];
-                } else {
-                    da = (double[])obj;
-                }
-
-                if (needAlphaDivide) {
-                    double alpha = normComponents[normOffset + numColorComponents];
-                    for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
-                        da[i] = normComponents[idx] * alpha;
-                    }
-                    da[numColorComponents] = alpha;
-                } else {
-                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                        da[i] = normComponents[idx];
-                    }
-                }
-                return da;
-
-            default:
-                // awt.213=This ComponentColorModel does not support the
-                // unnormalized form
-                throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
-        }
-    }
-
-    @Override
-    public Object getDataElements(int rgb, Object pixel) {
-        float normComp[];
-        float comp[];
-
-        int red = (rgb >> 16) & 0xff;
-        int green = (rgb >> 8) & 0xff;
-        int blue = rgb & 0xff;
-        int alpha = (rgb >> 24) & 0xff;
-
-        comp = new float[3];
-        if (is_sRGB || is_LINEAR_RGB) {
-            if (is_LINEAR_RGB) {
-                if (LINEAR_RGB_Length == 8) {
-                    red = to_LINEAR_8RGB_LUT[red] & 0xff;
-                    green = to_LINEAR_8RGB_LUT[green] & 0xff;
-                    blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
-                } else {
-                    red = to_LINEAR_16RGB_LUT[red] & 0xffff;
-                    green = to_LINEAR_16RGB_LUT[green] & 0xffff;
-                    blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
-                }
-            }
-            comp[0] = red / fFactor;
-            comp[1] = green / fFactor;
-            comp[2] = blue / fFactor;
-            if (!hasAlpha) {
-                normComp = comp;
-            } else {
-                float normAlpha = alpha / 255.0f;
-                normComp = new float[numComponents];
-                for (int i = 0; i < numColorComponents; i++) {
-                    normComp[i] = comp[i];
-                }
-                normComp[numColorComponents] = normAlpha;
-            }
-        } else {
-            comp[0] = red / fFactor;
-            comp[1] = green / fFactor;
-            comp[2] = blue / fFactor;
-            float[] defComp = cs.fromRGB(comp);
-            if (!hasAlpha) {
-                normComp = defComp;
-            } else {
-                float normAlpha = alpha / 255.0f;
-                normComp = new float[numComponents];
-                for (int i = 0; i < numColorComponents; i++) {
-                    normComp[i] = defComp[i];
-                }
-                normComp[numColorComponents] = normAlpha;
-            }
-        }
-        if (hasAlpha && isAlphaPremultiplied) {
-            normComp[0] *= normComp[numColorComponents];
-            normComp[1] *= normComp[numColorComponents];
-            normComp[2] *= normComp[numColorComponents];
-        }
-
-        return getDataElements(normComp, 0, pixel);
-    }
-
-    @Override
-    public WritableRaster getAlphaRaster(WritableRaster raster) {
-        if (!hasAlpha) {
-            return null;
-        }
-
-        int x = raster.getMinX();
-        int y = raster.getMinY();
-        int bandList[] = new int[1];
-        bandList[0] = raster.getNumBands() - 1;
-
-        return raster.createWritableChild(x, y, raster.getWidth(), raster.getHeight(), x, y,
-                bandList);
-    }
-
-    @Override
-    public ColorModel coerceData(WritableRaster raster, boolean isAlphaPremultiplied) {
-        if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
-            return this;
-        }
-
-        int minX = raster.getMinX();
-        int minY = raster.getMinY();
-        int w = raster.getWidth();
-        int h = raster.getHeight();
-
-        if (isAlphaPremultiplied) {
-            switch (transferType) {
-                case DataBuffer.TYPE_BYTE:
-                case DataBuffer.TYPE_USHORT:
-                case DataBuffer.TYPE_INT:
-                    float alphaFactor = maxValues[numColorComponents];
-                    int iComponents[] = null;
-                    int iTransparentComponents[] = new int[numComponents];
-                    for (int i = 0; i < h; i++, minY++) {
-                        for (int j = 0, x = minX; j < w; j++, x++) {
-                            iComponents = raster.getPixel(x, minY, iComponents);
-                            if (iComponents[numColorComponents] == 0) {
-                                raster.setPixel(x, minY, iTransparentComponents);
-                            } else {
-                                float alpha = iComponents[numColorComponents] / alphaFactor;
-                                for (int n = 0; n < numColorComponents; n++) {
-                                    iComponents[n] = (int)(alpha * iComponents[n] + 0.5f);
-                                }
-                                raster.setPixel(x, minY, iComponents);
-                            }
-                        }
-
-                    }
-                    break;
-
-                case DataBuffer.TYPE_SHORT:
-                    float sAlphaFactor = maxValues[numColorComponents];
-                    short sComponents[] = null;
-                    short sTransparentComponents[] = new short[numComponents];
-                    for (int i = 0; i < h; i++, minY++) {
-                        for (int j = 0, x = minX; j < w; j++, x++) {
-                            sComponents = (short[])raster.getDataElements(x, minY, sComponents);
-                            if (sComponents[numColorComponents] == 0) {
-                                raster.setDataElements(x, minY, sTransparentComponents);
-                            } else {
-                                float alpha = sComponents[numColorComponents] / sAlphaFactor;
-                                for (int n = 0; n < numColorComponents; n++) {
-                                    sComponents[n] = (byte)(alpha * sComponents[n] + 0.5f);
-                                }
-                                raster.setDataElements(x, minY, sComponents);
-                            }
-                        }
-
-                    }
-                    break;
-
-                case DataBuffer.TYPE_FLOAT:
-                    float fComponents[] = null;
-                    float fTransparentComponents[] = new float[numComponents];
-                    for (int i = 0; i < h; i++, minY++) {
-                        for (int j = 0, x = minX; j < w; j++, x++) {
-                            fComponents = raster.getPixel(x, minY, fComponents);
-                            if (fComponents[numColorComponents] == 0.0f) {
-                                raster.setDataElements(x, minY, fTransparentComponents);
-                            } else {
-                                float alpha = fComponents[numColorComponents];
-                                for (int n = 0; n < numColorComponents; n++) {
-                                    fComponents[n] = fComponents[n] * alpha;
-                                }
-                                raster.setPixel(x, minY, fComponents);
-                            }
-                        }
-
-                    }
-                    break;
-
-                case DataBuffer.TYPE_DOUBLE:
-                    double dComponents[] = null;
-                    double dTransparentComponents[] = new double[numComponents];
-                    for (int i = 0; i < h; i++, minY++) {
-                        for (int j = 0, x = minX; j < w; j++, x++) {
-                            dComponents = raster.getPixel(x, minY, dComponents);
-                            if (dComponents[numColorComponents] == 0.0) {
-                                raster.setPixel(x, minY, dTransparentComponents);
-                            } else {
-                                double alpha = dComponents[numColorComponents];
-                                for (int n = 0; n < numColorComponents; n++) {
-                                    dComponents[n] = dComponents[n] * alpha;
-                                }
-                                raster.setPixel(x, minY, dComponents);
-                            }
-                        }
-
-                    }
-                    break;
-
-                default:
-                    // awt.219=This transferType is not supported by this color
-                    // model
-                    throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
-            }
-        } else {
-            switch (transferType) {
-                case DataBuffer.TYPE_BYTE:
-                case DataBuffer.TYPE_USHORT:
-                case DataBuffer.TYPE_INT:
-                    float alphaFactor = maxValues[numColorComponents];
-                    int iComponents[] = null;
-                    int iTransparentComponents[] = new int[numComponents];
-                    for (int i = 0; i < h; i++, minY++) {
-                        for (int j = 0, x = minX; j < w; j++, x++) {
-                            iComponents = raster.getPixel(x, minY, iComponents);
-                            if (iComponents[numColorComponents] == 0) {
-                                raster.setPixel(x, minY, iTransparentComponents);
-                            } else {
-                                float alpha = iComponents[numColorComponents] / alphaFactor;
-                                for (int n = 0; n < numColorComponents; n++) {
-                                    iComponents[n] = (int)(iComponents[n] / alpha + 0.5f);
-                                }
-                                raster.setPixel(x, minY, iComponents);
-                            }
-                        }
-
-                    }
-                    break;
-
-                case DataBuffer.TYPE_SHORT:
-                    float sAlphaFactor = maxValues[numColorComponents];
-                    short sComponents[] = null;
-                    short sTransparentComponents[] = new short[numComponents];
-                    for (int i = 0; i < h; i++, minY++) {
-                        for (int j = 0, x = minX; j < w; j++, x++) {
-                            sComponents = (short[])raster.getDataElements(x, minY, sComponents);
-                            if (sComponents[numColorComponents] == 0) {
-                                raster.setDataElements(x, minY, sTransparentComponents);
-                            } else {
-                                float alpha = sComponents[numColorComponents] / sAlphaFactor;
-                                for (int n = 0; n < numColorComponents; n++) {
-                                    sComponents[n] = (byte)(sComponents[n] / alpha + 0.5f);
-                                }
-                                raster.setDataElements(x, minY, sComponents);
-                            }
-                        }
-
-                    }
-                    break;
-
-                case DataBuffer.TYPE_FLOAT:
-                    float fComponents[] = null;
-                    float fTransparentComponents[] = new float[numComponents];
-                    for (int i = 0; i < h; i++, minY++) {
-                        for (int j = 0, x = minX; j < w; j++, x++) {
-                            fComponents = raster.getPixel(x, minY, fComponents);
-                            if (fComponents[numColorComponents] == 0.0f) {
-                                raster.setDataElements(x, minY, fTransparentComponents);
-                            } else {
-                                float alpha = fComponents[numColorComponents];
-                                for (int n = 0; n < numColorComponents; n++) {
-                                    fComponents[n] = fComponents[n] / alpha;
-                                }
-                                raster.setPixel(x, minY, fComponents);
-                            }
-                        }
-
-                    }
-                    break;
-
-                case DataBuffer.TYPE_DOUBLE:
-                    double dComponents[] = null;
-                    double dTransparentComponents[] = new double[numComponents];
-                    for (int i = 0; i < h; i++, minY++) {
-                        for (int j = 0, x = minX; j < w; j++, x++) {
-                            dComponents = raster.getPixel(x, minY, dComponents);
-                            if (dComponents[numColorComponents] == 0.0) {
-                                raster.setPixel(x, minY, dTransparentComponents);
-                            } else {
-                                double alpha = dComponents[numColorComponents];
-                                for (int n = 0; n < numColorComponents; n++) {
-                                    dComponents[n] = dComponents[n] / alpha;
-                                }
-                                raster.setPixel(x, minY, dComponents);
-                            }
-                        }
-
-                    }
-                    break;
-                default:
-                    // awt.219=This transferType is not supported by this color
-                    // model
-                    throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
-            }
-        }
-
-        if (!signed) {
-            return new ComponentColorModel(cs, bits, hasAlpha, isAlphaPremultiplied, transparency,
-                    transferType);
-        }
-
-        return new ComponentColorModel(cs, null, hasAlpha, isAlphaPremultiplied, transparency,
-                transferType);
-    }
-
-    @Override
-    public int[] getComponents(Object pixel, int[] components, int offset) {
-        if (donotSupportUnnormalized) {
-            // awt.213=This ComponentColorModel does not support the
-            // unnormalized form
-            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
-        }
-
-        if (components == null) {
-            components = new int[offset + numComponents];
-        } else if (offset + numComponents > components.length) {
-            // awt.218=The components array is not large enough to hold all the
-            // color and alpha components
-            throw new IllegalArgumentException(Messages.getString("awt.218")); //$NON-NLS-1$
-        }
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])pixel;
-
-                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
-                    components[idx] = ba[i] & 0xff;
-                }
-                return components;
-
-            case DataBuffer.TYPE_USHORT:
-                short sa[] = (short[])pixel;
-                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
-                    components[idx] = sa[i] & 0xffff;
-                }
-                return components;
-
-            case DataBuffer.TYPE_INT:
-                int ia[] = (int[])pixel;
-                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
-                    components[idx] = ia[i];
-                }
-                return components;
-
-            default:
-                // awt.217=The transfer type of this ComponentColorModel is not
-                // one
-                // of the following transfer types: DataBuffer.TYPE_BYTE,
-                // DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
-                throw new UnsupportedOperationException(Messages.getString("awt.217")); //$NON-NLS-1$
-        }
-
-    }
-
-    @Override
-    public float[] getNormalizedComponents(Object pixel, float normComponents[], int normOffset) {
-
-        if (normComponents == null) {
-            normComponents = new float[numComponents + normOffset];
-        }
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])pixel;
-                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                    normComponents[idx] = (ba[i] & 0xff) * scaleFactors[i];
-                }
-                break;
-
-            case DataBuffer.TYPE_USHORT:
-                short usa[] = (short[])pixel;
-                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                    normComponents[idx] = (usa[i] & 0xffff) * scaleFactors[i];
-                }
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int ia[] = (int[])pixel;
-                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                    normComponents[idx] = ia[i] * scaleFactors[i];
-                }
-                break;
-
-            case DataBuffer.TYPE_SHORT:
-                short sa[] = (short[])pixel;
-                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                    normComponents[idx] = sa[i] * scaleFactors[i];
-                }
-                break;
-
-            case DataBuffer.TYPE_FLOAT:
-                float fa[] = (float[])pixel;
-                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                    normComponents[idx] = fa[i];
-                }
-                break;
-
-            case DataBuffer.TYPE_DOUBLE:
-                double da[] = (double[])pixel;
-                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
-                    normComponents[idx] = (float)da[i];
-                }
-                break;
-
-            default:
-                // awt.21A=This ComponentColorModel does not support this
-                // transferType
-                throw new IllegalArgumentException(Messages.getString("awt.21A")); //$NON-NLS-1$
-        }
-
-        if (needAlphaDivide) {
-            float alpha = normComponents[normOffset + numColorComponents];
-            for (int i = 0, idx = normOffset; i < numColorComponents; i++, idx++) {
-                normComponents[idx] /= alpha;
-            }
-        }
-
-        if (needScale) {
-            for (int i = 0, idx = normOffset; i < numColorComponents; i++, idx++) {
-                normComponents[idx] = minVals[i] + ranges[i] * normComponents[idx];
-            }
-        }
-        return normComponents;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof ComponentColorModel)) {
-            return false;
-        }
-        return super.equals(obj);
-    }
-
-    @Override
-    public int getRed(Object inData) {
-        return getRGBComponent(inData, 0);
-    }
-
-    @Override
-    public int getRGB(Object inData) {
-        int alpha = getAlpha(inData);
-        if (cs.getType() == ColorSpace.TYPE_GRAY) {
-            int gray = getRed(inData);
-            return (alpha << 24 | gray << 16 | gray << 8 | gray);
-        }
-        return (alpha << 24 | getRed(inData) << 16 | getGreen(inData) << 8 | getBlue(inData));
-    }
-
-    @Override
-    public int getGreen(Object inData) {
-        return getRGBComponent(inData, 1);
-    }
-
-    @Override
-    public int getBlue(Object inData) {
-        return getRGBComponent(inData, 2);
-    }
-
-    @Override
-    public int getAlpha(Object inData) {
-        if (!hasAlpha) {
-            return 255;
-        }
-        int alpha = 0;
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE: {
-                byte ba[] = (byte[])inData;
-                alpha = ba[numColorComponents] & 0xff;
-                if (bits[numColorComponents] != 8) {
-                    return alphaLUT[alpha] & 0xff;
-                }
-                return alpha;
-            }
-            case DataBuffer.TYPE_USHORT: {
-                short usa[] = (short[])inData;
-                alpha = usa[numColorComponents] & 0xffff;
-                if (bits[numColorComponents] != 8) {
-                    return alphaLUT[alpha] & 0xff;
-                }
-                return alpha;
-            }
-            case DataBuffer.TYPE_INT: {
-                int ia[] = (int[])inData;
-                alpha = ia[numColorComponents];
-                if (bits[numColorComponents] != 8) {
-                    return alphaLUT[alpha] & 0xff;
-                }
-                return alpha;
-            }
-            case DataBuffer.TYPE_SHORT: {
-                short sa[] = (short[])inData;
-                alpha = sa[numColorComponents];
-                if (bits[numColorComponents] != 8) {
-                    return alphaLUT[alpha] & 0xff;
-                }
-                return alpha;
-            }
-            case DataBuffer.TYPE_FLOAT: {
-                float fa[] = (float[])inData;
-                return (int)(fa[numColorComponents] * 255.0f + 0.5f);
-            }
-            case DataBuffer.TYPE_DOUBLE: {
-                double da[] = (double[])inData;
-                return (int)(da[numColorComponents] * 255.0 + 0.5);
-            }
-            default: {
-                // awt.214=This Color Model doesn't support this transferType
-                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-            }
-        }
-    }
-
-    @Override
-    public WritableRaster createCompatibleWritableRaster(int w, int h) {
-        SampleModel sm = createCompatibleSampleModel(w, h);
-        DataBuffer db = sm.createDataBuffer();
-        return Raster.createWritableRaster(sm, db, null);
-    }
-
-    @Override
-    public boolean isCompatibleSampleModel(SampleModel sm) {
-        if (!(sm instanceof ComponentSampleModel)) {
-            return false;
-        }
-        if (numComponents != sm.getNumBands()) {
-            return false;
-        }
-        if (transferType != sm.getTransferType()) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public SampleModel createCompatibleSampleModel(int w, int h) {
-        int bandOffsets[] = new int[numComponents];
-        for (int i = 0; i < numComponents; i++) {
-            bandOffsets[i] = i;
-        }
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-            case DataBuffer.TYPE_USHORT:
-                return new PixelInterleavedSampleModel(transferType, w, h, numComponents, w
-                        * numComponents, bandOffsets);
-
-            default:
-                return new ComponentSampleModel(transferType, w, h, numComponents, w
-                        * numComponents, bandOffsets);
-        }
-    }
-
-    @Override
-    public boolean isCompatibleRaster(Raster raster) {
-        SampleModel sm = raster.getSampleModel();
-        if (!(sm instanceof ComponentSampleModel)) {
-            return false;
-        }
-
-        if (sm.getNumBands() != numComponents) {
-            return false;
-        }
-        if (raster.getTransferType() != transferType) {
-            return false;
-        }
-
-        int sampleSizes[] = sm.getSampleSize();
-        for (int i = 0; i < numComponents; i++) {
-            if (bits[i] != sampleSizes[i]) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public float[] getNormalizedComponents(int components[], int offset, float normComponents[],
-            int normOffset) {
-        if (donotSupportUnnormalized) {
-            // awt.213=This ComponentColorModel does not support the
-            // unnormalized form
-            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
-        }
-
-        return super.getNormalizedComponents(components, offset, normComponents, normOffset);
-    }
-
-    @Override
-    public int getDataElement(int[] components, int offset) {
-        if (numComponents > 1) {
-            // awt.212=There is more than one component in this ColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
-        }
-        if (donotSupportUnnormalized) {
-            // awt.213=This ComponentColorModel does not support the
-            // unnormalized form
-            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
-        }
-        return components[offset];
-    }
-
-    @Override
-    public int[] getUnnormalizedComponents(float[] normComponents, int normOffset,
-            int[] components, int offset) {
-
-        if (donotSupportUnnormalized) {
-            // awt.213=This ComponentColorModel does not support the
-            // unnormalized form
-            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
-        }
-
-        if (normComponents.length - normOffset < numComponents) {
-            // awt.21B=The length of normComponents minus normOffset is less
-            // than numComponents
-            throw new IllegalArgumentException(Messages.getString("awt.21B")); //$NON-NLS-1$
-        }
-
-        return super.getUnnormalizedComponents(normComponents, normOffset, components, offset);
-    }
-
-    @Override
-    public int getDataElement(float normComponents[], int normOffset) {
-        if (numComponents > 1) {
-            // awt.212=There is more than one component in this ColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
-        }
-        if (signed) {
-            // awt.210=The component value for this ColorModel is signed
-            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
-        }
-
-        Object pixel = getDataElements(normComponents, normOffset, null);
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])pixel;
-                return ba[0] & 0xff;
-            case DataBuffer.TYPE_USHORT:
-                short sa[] = (short[])pixel;
-                return sa[0] & 0xffff;
-            case DataBuffer.TYPE_INT:
-                int ia[] = (int[])pixel;
-                return ia[0];
-            default:
-                // awt.211=Pixel values for this ColorModel are not conveniently
-                // representable as a single int
-                throw new IllegalArgumentException(Messages.getString("awt.211")); //$NON-NLS-1$
-        }
-    }
-
-    @Override
-    public int[] getComponents(int pixel, int components[], int offset) {
-        if (numComponents > 1) {
-            // awt.212=There is more than one component in this ColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
-        }
-        if (donotSupportUnnormalized) {
-            // awt.213=This ComponentColorModel does not support the
-            // unnormalized form
-            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
-        }
-
-        if (components == null) {
-            components = new int[offset + 1];
-        }
-
-        components[offset] = pixel & maxValues[0];
-        return components;
-    }
-
-    @Override
-    public int getRed(int pixel) {
-        float rgb[] = toRGB(pixel);
-        return (int)(rgb[0] * 255.0f + 0.5f);
-    }
-
-    @Override
-    public int getRGB(int pixel) {
-        return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) | (getGreen(pixel) << 8)
-                | getBlue(pixel);
-    }
-
-    @Override
-    public int getGreen(int pixel) {
-        float rgb[] = toRGB(pixel);
-        return (int)(rgb[1] * 255.0f + 0.5f);
-    }
-
-    @Override
-    public int getBlue(int pixel) {
-        float rgb[] = toRGB(pixel);
-        return (int)(rgb[2] * 255.0f + 0.5f);
-    }
-
-    @Override
-    public int getAlpha(int pixel) {
-
-        // This method throw IllegalArgumentException according to
-        // Java API Spacification
-        if (signed) {
-            // awt.210=The component value for this ColorModel is signed
-            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
-        }
-
-        if (numComponents > 1) {
-            // awt.212=There is more than one component in this ColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
-        }
-
-        return 255;
-    }
-
-    /**
-     * Initialization of Lookup tables.
-     */
-    private void initLUTs() {
-        is_sRGB = cs.isCS_sRGB();
-        is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
-
-        if (hasAlpha && bits[numColorComponents] != 8 && integral) {
-            alphaLUT = new byte[maxValues[numColorComponents] + 1];
-            for (int i = 0; i <= maxValues[numColorComponents]; i++) {
-                alphaLUT[i] = (byte)(scaleFactors[numColorComponents] * i + 0.5f);
-            }
-        }
-
-        if (is_LINEAR_RGB) {
-            if (maxBitLength > 8) {
-                LINEAR_RGB_Length = 16;
-                from_LINEAR_RGB_LUT = LUTColorConverter.getFrom16lRGBtosRGB_LUT();
-                to_LINEAR_16RGB_LUT = LUTColorConverter.getFromsRGBto16lRGB_LUT();
-            } else {
-                LINEAR_RGB_Length = 8;
-                from_LINEAR_RGB_LUT = LUTColorConverter.getFrom8lRGBtosRGB_LUT();
-                to_LINEAR_8RGB_LUT = LUTColorConverter.getFromsRGBto8lRGB_LUT();
-            }
-            fFactor = ((1 << LINEAR_RGB_Length) - 1);
-        } else {
-            fFactor = 255.0f;
-        }
-
-        if (!isAlphaPremultiplied && integral) {
-            colorLUTs = new byte[3][];
-
-            if (is_sRGB) {
-                for (int i = 0; i < numColorComponents; i++) {
-                    if (bits[i] != 8) {
-                        for (int j = 0; j < i; j++) {
-                            if (bits[i] == bits[j]) {
-                                colorLUTs[i] = colorLUTs[j];
-                                break;
-                            }
-                        }
-                        colorLUTs[i] = new byte[maxValues[i] + 1];
-                        for (int j = 0; j <= maxValues[0]; j++) {
-                            colorLUTs[i][j] = (byte)(scaleFactors[i] * j + 0.5f);
-                        }
-                    }
-                }
-            }
-
-            if (is_LINEAR_RGB) {
-
-                for (int i = 0; i < numColorComponents; i++) {
-                    if (bits[i] != LINEAR_RGB_Length) {
-                        for (int j = 0; j < i; j++) {
-                            if (bits[i] == bits[j]) {
-                                colorLUTs[i] = colorLUTs[j];
-                                break;
-                            }
-                        }
-                        colorLUTs[i] = new byte[maxValues[i] + 1];
-                        for (int j = 0; j <= maxValues[0]; j++) {
-                            int idx;
-                            if (LINEAR_RGB_Length == 8) {
-                                idx = (int)(scaleFactors[i] * j + 0.5f);
-                            } else {
-                                idx = (int)(scaleFactors[i] * j * 257.0f + 0.5f);
-                            }
-                            colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
-                        }
-                    }
-                }
-            }
-
-        }
-    }
-
-    /**
-     * To rgb.
-     * 
-     * @param pixel
-     *            the integer representation of the pixel.
-     * @return the array of normalized sRGB components.
-     */
-    private float[] toRGB(int pixel) {
-
-        // This method throw IllegalArgumentException according to
-        // Java API Spacification
-        if (signed) {
-            // awt.210=The component value for this ColorModel is signed
-            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
-        }
-
-        if (numComponents > 1) {
-            // awt.212=There is more than one component in this ColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
-        }
-
-        Object obj = null;
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = new byte[1];
-                ba[0] = (byte)pixel;
-                obj = ba;
-                break;
-
-            case DataBuffer.TYPE_USHORT:
-                short sa[] = new short[1];
-                sa[0] = (short)pixel;
-                obj = sa;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int ia[] = new int[1];
-                ia[0] = pixel;
-                obj = ia;
-                break;
-
-        }
-
-        return cs.toRGB(getNormalizedComponents(obj, null, 0));
-    }
-
-    /**
-     * Gets the RGB component.
-     * 
-     * @param pixel
-     *            the pixel.
-     * @param idx
-     *            the index of component.
-     * @return the RGB value from 0 to 255 pixel's component.
-     */
-    private int getRGBComponent(Object pixel, int idx) {
-        if (is_sRGB) {
-            int comp = getDefComponent(pixel, idx);
-            if (calcValue || bits[idx] == 8) {
-                return comp;
-            }
-            return colorLUTs[idx][comp] & 0xff;
-        } else if (is_LINEAR_RGB) {
-            int comp = getDefComponent(pixel, idx);
-            if (calcValue || bits[idx] == LINEAR_RGB_Length) {
-                return from_LINEAR_RGB_LUT[comp] & 0xff;
-            }
-            return colorLUTs[idx][comp] & 0xff;
-        }
-
-        float normComp[] = getNormalizedComponents(pixel, null, 0);
-        float rgbComp[] = cs.toRGB(normComp);
-        return (int)(rgbComp[idx] * 255.0f + 0.5f);
-    }
-
-    /**
-     * Gets the def component.
-     * 
-     * @param pixel
-     *            the pixel.
-     * @param idx
-     *            the index of component.
-     * @return the tentative value of the pixel component.
-     */
-    private int getDefComponent(Object pixel, int idx) {
-        int comp = 0;
-        calcValue = false;
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])pixel;
-                comp = ba[idx] & 0xff;
-                if (needAlphaDivide) {
-                    int alpha = ba[numColorComponents] & 0xff;
-                    if (alpha == 0) {
-                        comp = 0;
-                    } else {
-                        float normAlpha = scaleFactors[numColorComponents] * alpha;
-                        comp = (int)(comp * fFactor / normAlpha + 0.5f);
-                    }
-                    calcValue = true;
-                }
-                return comp;
-
-            case DataBuffer.TYPE_USHORT:
-                short usa[] = (short[])pixel;
-                comp = usa[idx] & 0xffff;
-                if (needAlphaDivide) {
-                    int alpha = usa[numColorComponents] & 0xffff;
-                    if (alpha == 0) {
-                        comp = 0;
-                    } else {
-                        float normAlpha = scaleFactors[numColorComponents] * alpha;
-                        comp = (int)(comp * fFactor / normAlpha + 0.5f);
-                    }
-                    calcValue = true;
-                }
-                return comp;
-
-            case DataBuffer.TYPE_INT:
-                int ia[] = (int[])pixel;
-                comp = ia[idx];
-                if (needAlphaDivide) {
-                    int alpha = ia[numColorComponents];
-                    if (alpha == 0) {
-                        comp = 0;
-                    } else {
-                        float normAlpha = scaleFactors[numColorComponents] * alpha;
-                        comp = (int)(comp * fFactor / normAlpha + 0.5f);
-                    }
-                    calcValue = true;
-                }
-                return comp;
-
-            case DataBuffer.TYPE_SHORT:
-                short sa[] = (short[])pixel;
-                comp = sa[idx];
-                if (needAlphaDivide) {
-                    int alpha = sa[numColorComponents];
-                    if (alpha == 0) {
-                        comp = 0;
-                    } else {
-                        float normAlpha = scaleFactors[numColorComponents] * alpha;
-                        comp = (int)(comp * fFactor / normAlpha + 0.5f);
-                    }
-                    calcValue = true;
-                }
-                return comp;
-
-            case DataBuffer.TYPE_FLOAT:
-                float fa[] = (float[])pixel;
-                if (needAlphaDivide) {
-                    float alpha = fa[numColorComponents];
-                    if (fa[numColorComponents] == 0.0f) {
-                        comp = 0;
-                    } else {
-                        comp = (int)(fa[idx] * fFactor / alpha + 0.5f);
-                    }
-                } else {
-                    comp = (int)(fa[idx] * fFactor + 0.5f);
-                }
-                calcValue = true;
-                return comp;
-
-            case DataBuffer.TYPE_DOUBLE:
-                double da[] = (double[])pixel;
-                if (needAlphaDivide) {
-                    if (da[numColorComponents] == 0.0) {
-                        comp = 0;
-                    } else {
-                        comp = (int)(da[idx] * fFactor / da[numColorComponents] + 0.5);
-                    }
-                } else {
-                    comp = (int)(da[idx] * fFactor + 0.5);
-                }
-                calcValue = true;
-                return comp;
-
-            default:
-                // awt.214=This Color Model doesn't support this transferType
-                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-        }
-    }
-
-}
diff --git a/awt/java/awt/image/ComponentSampleModel.java b/awt/java/awt/image/ComponentSampleModel.java
deleted file mode 100644
index 7f81409..0000000
--- a/awt/java/awt/image/ComponentSampleModel.java
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.util.Arrays;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The ComponentSampleModel class represents a set of image data whose each
- * element - the sample of a pixel - takes one data element of the DataBuffer.
- * <p>
- * The Bank indices denote the correspondence between the bank of data buffers
- * and a band of image data. The Pixel stride is the number of data array
- * elements between two samples for the same band on the same scanline. The
- * pixel stride for a BandedSampleModel is one. The scanline stride represents
- * the number of data array elements between a specified sample and the
- * corresponding sample in the same column in the next scanline. The array of
- * band offsets gives the starting offsets within each data banks of the in the
- * DataBuffer. The bank indices represents the indices within each bank of the
- * DataBuffer corresponding to a band of image data.
- * 
- * @since Android 1.0
- */
-public class ComponentSampleModel extends SampleModel {
-
-    /**
-     * The band offsets array of this ComponentSampleModel.
-     */
-    protected int bandOffsets[];
-
-    /**
-     * The bank indices array of this ComponentSampleModel.
-     */
-    protected int bankIndices[];
-
-    /**
-     * The number of bands in this ComponentSampleModel.
-     */
-    protected int numBands;
-
-    /**
-     * The number banks of this ComponentSampleModel.
-     */
-    protected int numBanks;
-
-    /**
-     * The scanline stride of this ComponentSampleModel.
-     */
-    protected int scanlineStride;
-
-    /**
-     * The pixel stride of this ComponentSampleModel.
-     */
-    protected int pixelStride;
-
-    /**
-     * Instantiates a new ComponentSampleModel with the specified properties.
-     * 
-     * @param dataType
-     *            the data type of samples.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param pixelStride
-     *            the pixel stride of the image data.
-     * @param scanlineStride
-     *            the scanline stride of the image data.
-     * @param bankIndices
-     *            the array of the bank indices.
-     * @param bandOffsets
-     *            the array of the band offsets.
-     */
-    public ComponentSampleModel(int dataType, int w, int h, int pixelStride, int scanlineStride,
-            int bankIndices[], int bandOffsets[]) {
-
-        super(dataType, w, h, bandOffsets.length);
-
-        if (pixelStride < 0) {
-            // awt.24B=Pixel stride must be >= 0
-            throw new IllegalArgumentException(Messages.getString("awt.24B")); //$NON-NLS-1$
-        }
-
-        if (scanlineStride < 0) {
-            // awt.24C=Scanline stride must be >= 0
-            throw new IllegalArgumentException(Messages.getString("awt.24C")); //$NON-NLS-1$
-        }
-
-        if (bankIndices.length != bandOffsets.length) {
-            // awt.24D=Bank Indices length must be equal Bank Offsets length
-            throw new IllegalArgumentException(Messages.getString("awt.24D")); //$NON-NLS-1$
-        }
-
-        this.pixelStride = pixelStride;
-        this.scanlineStride = scanlineStride;
-        this.bandOffsets = bandOffsets.clone();
-        this.bankIndices = bankIndices.clone();
-        this.numBands = bandOffsets.length;
-
-        int maxBank = 0;
-        for (int i = 0; i < bankIndices.length; i++) {
-            if (bankIndices[i] < 0) {
-                // awt.24E=Index of {0} bank must be >= 0
-                throw new IllegalArgumentException(Messages.getString("awt.24E", i)); //$NON-NLS-1$
-            }
-            if (bankIndices[i] > maxBank) {
-                maxBank = bankIndices[i];
-            }
-        }
-        this.numBanks = maxBank + 1;
-
-    }
-
-    /**
-     * Instantiates a new ComponentSampleModel with the specified properties.
-     * 
-     * @param dataType
-     *            the data type of the samples.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param pixelStride
-     *            the pixel stride of the image data.
-     * @param scanlineStride
-     *            the scanline stride of the image data.
-     * @param bandOffsets
-     *            the band offsets.
-     */
-    public ComponentSampleModel(int dataType, int w, int h, int pixelStride, int scanlineStride,
-            int bandOffsets[]) {
-
-        super(dataType, w, h, bandOffsets.length);
-        if (pixelStride < 0) {
-            // awt.24B=Pixel stride must be >= 0
-            throw new IllegalArgumentException(Messages.getString("awt.24B")); //$NON-NLS-1$
-        }
-
-        if (scanlineStride < 0) {
-            // awt.24C=Scanline stride must be >= 0
-            throw new IllegalArgumentException(Messages.getString("awt.24C")); //$NON-NLS-1$
-        }
-
-        this.pixelStride = pixelStride;
-        this.scanlineStride = scanlineStride;
-        this.bandOffsets = bandOffsets.clone();
-        this.numBands = bandOffsets.length;
-        this.numBanks = 1;
-
-        this.bankIndices = new int[numBands];
-        for (int i = 0; i < numBands; i++) {
-            bankIndices[i] = 0;
-        }
-    }
-
-    @Override
-    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE:
-                byte bdata[];
-                if (obj == null) {
-                    bdata = new byte[numBands];
-                } else {
-                    bdata = (byte[])obj;
-                }
-
-                for (int i = 0; i < numBands; i++) {
-                    bdata[i] = (byte)getSample(x, y, i, data);
-                }
-
-                obj = bdata;
-                break;
-
-            case DataBuffer.TYPE_SHORT:
-            case DataBuffer.TYPE_USHORT:
-                short sdata[];
-                if (obj == null) {
-                    sdata = new short[numBands];
-                } else {
-                    sdata = (short[])obj;
-                }
-
-                for (int i = 0; i < numBands; i++) {
-                    sdata[i] = (short)getSample(x, y, i, data);
-                }
-
-                obj = sdata;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int idata[];
-                if (obj == null) {
-                    idata = new int[numBands];
-                } else {
-                    idata = (int[])obj;
-                }
-
-                for (int i = 0; i < numBands; i++) {
-                    idata[i] = getSample(x, y, i, data);
-                }
-
-                obj = idata;
-                break;
-
-            case DataBuffer.TYPE_FLOAT:
-                float fdata[];
-                if (obj == null) {
-                    fdata = new float[numBands];
-                } else {
-                    fdata = (float[])obj;
-                }
-
-                for (int i = 0; i < numBands; i++) {
-                    fdata[i] = getSampleFloat(x, y, i, data);
-                }
-
-                obj = fdata;
-                break;
-
-            case DataBuffer.TYPE_DOUBLE:
-                double ddata[];
-                if (obj == null) {
-                    ddata = new double[numBands];
-                } else {
-                    ddata = (double[])obj;
-                }
-
-                for (int i = 0; i < numBands; i++) {
-                    ddata[i] = getSampleDouble(x, y, i, data);
-                }
-
-                obj = ddata;
-                break;
-        }
-
-        return obj;
-    }
-
-    @Override
-    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE:
-                byte barr[] = (byte[])obj;
-                for (int i = 0; i < numBands; i++) {
-                    setSample(x, y, i, barr[i] & 0xff, data);
-                }
-                break;
-
-            case DataBuffer.TYPE_SHORT:
-            case DataBuffer.TYPE_USHORT:
-                short sarr[] = (short[])obj;
-                for (int i = 0; i < numBands; i++) {
-                    setSample(x, y, i, sarr[i] & 0xffff, data);
-                }
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int iarr[] = (int[])obj;
-                for (int i = 0; i < numBands; i++) {
-                    setSample(x, y, i, iarr[i], data);
-                }
-                break;
-
-            case DataBuffer.TYPE_FLOAT:
-                float farr[] = (float[])obj;
-                for (int i = 0; i < numBands; i++) {
-                    setSample(x, y, i, farr[i], data);
-                }
-                break;
-
-            case DataBuffer.TYPE_DOUBLE:
-                double darr[] = (double[])obj;
-                for (int i = 0; i < numBands; i++) {
-                    setSample(x, y, i, darr[i], data);
-                }
-                break;
-        }
-    }
-
-    /**
-     * Compares this ComponentSampleModel with the specified Object.
-     * 
-     * @param o
-     *            the Object.
-     * @return true, if the object is a ComponentSampleModel with identical data
-     *         values to this ComponentSampleModel, false otherwise.
-     */
-    @Override
-    public boolean equals(Object o) {
-        if ((o == null) || !(o instanceof ComponentSampleModel)) {
-            return false;
-        }
-        ComponentSampleModel model = (ComponentSampleModel)o;
-        return this.width == model.width && this.height == model.height
-                && this.numBands == model.numBands && this.dataType == model.dataType
-                && Arrays.equals(this.bandOffsets, model.bandOffsets)
-                && Arrays.equals(this.bankIndices, model.bankIndices)
-                && this.numBands == model.numBands && this.numBanks == model.numBanks
-                && this.scanlineStride == model.scanlineStride
-                && this.pixelStride == model.pixelStride;
-    }
-
-    /**
-     * @see java.awt.image.SampleModel#createSubsetSampleModel(int[])
-     */
-    @Override
-    public SampleModel createSubsetSampleModel(int bands[]) {
-        if (bands.length > this.numBands) {
-            // awt.64=The number of the bands in the subset is greater than the
-            // number of bands in the sample model
-            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
-        }
-
-        int indices[] = new int[bands.length];
-        int offsets[] = new int[bands.length];
-
-        for (int i = 0; i < bands.length; i++) {
-            indices[i] = bankIndices[bands[i]];
-            offsets[i] = bandOffsets[bands[i]];
-        }
-
-        return new ComponentSampleModel(dataType, width, height, pixelStride, scanlineStride,
-                indices, offsets);
-
-    }
-
-    @Override
-    public SampleModel createCompatibleSampleModel(int w, int h) {
-        return new ComponentSampleModel(dataType, w, h, pixelStride, pixelStride * w, bankIndices,
-                bandOffsets);
-    }
-
-    @Override
-    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
-        int pixel[];
-
-        if (iArray == null) {
-            pixel = new int[numBands];
-        } else {
-            pixel = iArray;
-        }
-
-        for (int i = 0; i < numBands; i++) {
-            pixel[i] = getSample(x, y, i, data);
-        }
-
-        return pixel;
-    }
-
-    @Override
-    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
-        for (int i = 0; i < numBands; i++) {
-            setSample(x, y, i, iArray[i], data);
-        }
-    }
-
-    @Override
-    public int getSample(int x, int y, int b, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        return data.getElem(bankIndices[b], y * scanlineStride + x * pixelStride + bandOffsets[b]);
-    }
-
-    @Override
-    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        return data.getElemFloat(bankIndices[b], y * scanlineStride + x * pixelStride
-                + bandOffsets[b]);
-    }
-
-    @Override
-    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        return data.getElemDouble(bankIndices[b], y * scanlineStride + x * pixelStride
-                + bandOffsets[b]);
-    }
-
-    @Override
-    public int[] getPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x > this.width || x + w > this.width || y > this.height
-                || y + h > this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int pixels[] = null;
-        int idx = 0;
-
-        if (iArray == null) {
-            pixels = new int[w * h * numBands];
-        } else {
-            pixels = iArray;
-        }
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < numBands; n++) {
-                    pixels[idx++] = getSample(j, i, n, data);
-                }
-            }
-        }
-
-        return pixels;
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int idx = 0;
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < numBands; n++) {
-                    setSample(j, i, n, iArray[idx++], data);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, int s, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        data.setElem(bankIndices[b], y * scanlineStride + x * pixelStride + bandOffsets[b], s);
-    }
-
-    @Override
-    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int samples[];
-        int idx = 0;
-
-        if (iArray == null) {
-            samples = new int[w * h];
-        } else {
-            samples = iArray;
-        }
-
-        if (data == null) {
-            // awt.295=data is null
-            throw new NullPointerException(Messages.getString("awt.295")); //$NON-NLS-1$
-        }
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                samples[idx++] = getSample(j, i, b, data);
-            }
-        }
-
-        return samples;
-    }
-
-    @Override
-    public void setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int idx = 0;
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                setSample(j, i, b, iArray[idx++], data);
-            }
-        }
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, float s, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        data.setElemFloat(bankIndices[b], y * scanlineStride + x * pixelStride + bandOffsets[b], s);
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, double s, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        data
-                .setElemDouble(bankIndices[b], y * scanlineStride + x * pixelStride
-                        + bandOffsets[b], s);
-    }
-
-    @Override
-    public DataBuffer createDataBuffer() {
-        DataBuffer data = null;
-
-        int maxOffset = bandOffsets[0];
-        for (int i = 1; i < bandOffsets.length; i++) {
-            if (bandOffsets[i] > maxOffset) {
-                maxOffset = bandOffsets[i];
-            }
-        }
-        int size = (height - 1) * scanlineStride + (width - 1) * pixelStride + maxOffset + 1;
-
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE:
-                data = new DataBufferByte(size, numBanks);
-                break;
-            case DataBuffer.TYPE_SHORT:
-                data = new DataBufferShort(size, numBanks);
-                break;
-            case DataBuffer.TYPE_USHORT:
-                data = new DataBufferUShort(size, numBanks);
-                break;
-            case DataBuffer.TYPE_INT:
-                data = new DataBufferInt(size, numBanks);
-                break;
-            case DataBuffer.TYPE_FLOAT:
-                data = new DataBufferFloat(size, numBanks);
-                break;
-            case DataBuffer.TYPE_DOUBLE:
-                data = new DataBufferDouble(size, numBanks);
-                break;
-        }
-
-        return data;
-
-    }
-
-    /**
-     * Gets the offset of the specified band of the specified pixel.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param b
-     *            the band.
-     * @return the offset of the specified band of the specified pixel.
-     */
-    public int getOffset(int x, int y, int b) {
-        return y * scanlineStride + x * pixelStride + bandOffsets[b];
-    }
-
-    /**
-     * Gets the offset of the first band of the specified pixel.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @return the offset of the first band of the specified pixel.
-     */
-    public int getOffset(int x, int y) {
-        return y * scanlineStride + x * pixelStride + bandOffsets[0];
-    }
-
-    @Override
-    public final int getSampleSize(int band) {
-        return DataBuffer.getDataTypeSize(dataType);
-    }
-
-    @Override
-    public final int[] getSampleSize() {
-        int sampleSizes[] = new int[numBands];
-        int size = DataBuffer.getDataTypeSize(dataType);
-
-        for (int i = 0; i < numBands; i++) {
-            sampleSizes[i] = size;
-        }
-        return sampleSizes;
-    }
-
-    /**
-     * Gets an array of bank indices corresponding to this ComponentSampleModel.
-     * 
-     * @return the array of bank indices.
-     */
-    public final int[] getBankIndices() {
-        return bankIndices.clone();
-    }
-
-    /**
-     * Gets an array of the band offsets corresponding to this
-     * ComponentSampleModel.
-     * 
-     * @return the array of band offsets.
-     */
-    public final int[] getBandOffsets() {
-        return bandOffsets.clone();
-    }
-
-    /**
-     * Gets a hash code of this ComponentSampleModel object.
-     * 
-     * @return a hash code of this ComponentSampleModel object.
-     */
-    @Override
-    public int hashCode() {
-        int hash = 0;
-        int tmp = 0;
-
-        hash = width;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= height;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= numBands;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= dataType;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        for (int element : bandOffsets) {
-            hash ^= element;
-            tmp = hash >>> 24;
-            hash <<= 8;
-            hash |= tmp;
-        }
-        for (int element : bankIndices) {
-            hash ^= element;
-            tmp = hash >>> 24;
-            hash <<= 8;
-            hash |= tmp;
-        }
-        hash ^= pixelStride;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-
-        hash ^= scanlineStride;
-        return hash;
-    }
-
-    /**
-     * Gets the scanline stride of this ComponentSampleModel.
-     * 
-     * @return the scanline stride of this ComponentSampleModel.
-     */
-    public final int getScanlineStride() {
-        return scanlineStride;
-    }
-
-    /**
-     * Gets the pixel stride.
-     * 
-     * @return the pixel stride.
-     */
-    public final int getPixelStride() {
-        return pixelStride;
-    }
-
-    @Override
-    public final int getNumDataElements() {
-        return numBands;
-    }
-
-}
diff --git a/awt/java/awt/image/ConvolveOp.java b/awt/java/awt/image/ConvolveOp.java
deleted file mode 100644
index 6eb8909..0000000
--- a/awt/java/awt/image/ConvolveOp.java
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Sep 29, 2005
- */
-
-package java.awt.image;
-
-import java.awt.*;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.util.Arrays;
-
-import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The ConvolveOp class convolves from the source data to the destination using
- * a convolution kernel. Each output pixel is represented as the result of
- * multiplying the kernel and the surround of the input pixel.
- * 
- * @since Android 1.0
- */
-public class ConvolveOp implements BufferedImageOp, RasterOp {
-
-    /**
-     * The Constant EDGE_ZERO_FILL indicates that pixels at the edge of the
-     * destination image are set to zero.
-     */
-    public static final int EDGE_ZERO_FILL = 0;
-
-    /**
-     * The Constant EDGE_NO_OP indicates that pixels at the edge of the source
-     * image are converted to the edge pixels in the destination without
-     * modification.
-     */
-    public static final int EDGE_NO_OP = 1;
-
-    /**
-     * The kernel.
-     */
-    private Kernel kernel;
-
-    /**
-     * The edge cond.
-     */
-    private int edgeCond;
-
-    /**
-     * The rhs.
-     */
-    private RenderingHints rhs = null;
-
-    static {
-        // TODO
-        // System.loadLibrary("imageops");
-    }
-
-    /**
-     * Instantiates a new ConvolveOp object with the specified Kernel and
-     * specified edges condition.
-     * 
-     * @param kernel
-     *            the specified Kernel.
-     * @param edgeCondition
-     *            the specified edge condition.
-     * @param hints
-     *            the RenderingHints object, or null.
-     */
-    public ConvolveOp(Kernel kernel, int edgeCondition, RenderingHints hints) {
-        this.kernel = kernel;
-        this.edgeCond = edgeCondition;
-        this.rhs = hints;
-    }
-
-    /**
-     * Instantiates a new ConvolveOp object with the specified Kernel and
-     * EDGE_ZERO_FILL edge condition.
-     * 
-     * @param kernel
-     *            the specified Kernel.
-     */
-    public ConvolveOp(Kernel kernel) {
-        this.kernel = kernel;
-        this.edgeCond = EDGE_ZERO_FILL;
-    }
-
-    /**
-     * Gets the Kernel object of this ConvolveOp.
-     * 
-     * @return the Kernel object of this ConvolveOp.
-     */
-    public final Kernel getKernel() {
-        return (Kernel)kernel.clone();
-    }
-
-    public final RenderingHints getRenderingHints() {
-        return rhs;
-    }
-
-    /**
-     * Gets the edge condition of this ConvolveOp.
-     * 
-     * @return the edge condition: EDGE_NO_OP or EDGE_ZERO_FILL.
-     */
-    public int getEdgeCondition() {
-        return edgeCond;
-    }
-
-    public final Rectangle2D getBounds2D(Raster src) {
-        return src.getBounds();
-    }
-
-    public final Rectangle2D getBounds2D(BufferedImage src) {
-        return getBounds2D(src.getRaster());
-    }
-
-    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
-        if (dstPt == null) {
-            dstPt = new Point2D.Float();
-        }
-
-        dstPt.setLocation(srcPt);
-        return dstPt;
-    }
-
-    public WritableRaster createCompatibleDestRaster(Raster src) {
-        return src.createCompatibleWritableRaster();
-    }
-
-    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
-        if (dstCM == null) {
-            dstCM = src.getColorModel();
-        }
-
-        if (dstCM instanceof IndexColorModel) {
-            dstCM = ColorModel.getRGBdefault();
-        }
-
-        WritableRaster r = dstCM.isCompatibleSampleModel(src.getSampleModel()) ? src.getRaster()
-                .createCompatibleWritableRaster(src.getWidth(), src.getHeight()) : dstCM
-                .createCompatibleWritableRaster(src.getWidth(), src.getHeight());
-
-        return new BufferedImage(dstCM, r, dstCM.isAlphaPremultiplied(), null);
-    }
-
-    public final WritableRaster filter(Raster src, WritableRaster dst) {
-        if (src == null) { // Should throw according to spec
-            // awt.256=Source raster is null
-            throw new NullPointerException(Messages.getString("awt.256")); //$NON-NLS-1$
-        }
-
-        if (src == dst) {
-            // awt.257=Source raster is equal to destination
-            throw new IllegalArgumentException(Messages.getString("awt.257")); //$NON-NLS-1$
-        }
-
-        if (dst == null) {
-            dst = createCompatibleDestRaster(src);
-        } else if (src.getNumBands() != dst.getNumBands()) {
-            // awt.258=Number of source bands ({0}) is not equal to number of
-            // destination bands ({1})
-            throw new IllegalArgumentException(Messages.getString(
-                    "awt.258", src.getNumBands(), dst.getNumBands())); //$NON-NLS-1$
-        }
-
-        // TODO
-        // if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM) != 0)
-        if (slowFilter(src, dst) != 0) {
-            // awt.21F=Unable to transform source
-            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
-        }
-
-        return dst;
-    }
-
-    /**
-     * Slow filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @return the int.
-     */
-    private int slowFilter(Raster src, WritableRaster dst) {
-        try {
-            SampleModel sm = src.getSampleModel();
-
-            int numBands = src.getNumBands();
-            int srcHeight = src.getHeight();
-            int srcWidth = src.getWidth();
-
-            int xOrigin = kernel.getXOrigin();
-            int yOrigin = kernel.getYOrigin();
-            int kWidth = kernel.getWidth();
-            int kHeight = kernel.getHeight();
-            float[] data = kernel.getKernelData(null);
-
-            int srcMinX = src.getMinX();
-            int srcMinY = src.getMinY();
-            int dstMinX = dst.getMinX();
-            int dstMinY = dst.getMinY();
-
-            int srcConvMaxX = srcWidth - (kWidth - xOrigin - 1);
-            int srcConvMaxY = srcHeight - (kHeight - yOrigin - 1);
-
-            int[] maxValues = new int[numBands];
-            int[] masks = new int[numBands];
-            int[] sampleSizes = sm.getSampleSize();
-
-            for (int i = 0; i < numBands; i++) {
-                maxValues[i] = (1 << sampleSizes[i]) - 1;
-                masks[i] = ~(maxValues[i]);
-            }
-
-            // Processing bounds
-            float[] pixels = null;
-            pixels = src.getPixels(srcMinX, srcMinY, srcWidth, srcHeight, pixels);
-            float[] newPixels = new float[pixels.length];
-            int rowLength = srcWidth * numBands;
-            if (this.edgeCond == ConvolveOp.EDGE_NO_OP) {
-                // top
-                int start = 0;
-                int length = yOrigin * rowLength;
-                System.arraycopy(pixels, start, newPixels, start, length);
-                // bottom
-                start = (srcHeight - (kHeight - yOrigin - 1)) * rowLength;
-                length = (kHeight - yOrigin - 1) * rowLength;
-                System.arraycopy(pixels, start, newPixels, start, length);
-                // middle
-                length = xOrigin * numBands;
-                int length1 = (kWidth - xOrigin - 1) * numBands;
-                start = yOrigin * rowLength;
-                int start1 = (yOrigin + 1) * rowLength - length1;
-                for (int i = yOrigin; i < (srcHeight - (kHeight - yOrigin - 1)); i++) {
-                    System.arraycopy(pixels, start, newPixels, start, length);
-                    System.arraycopy(pixels, start1, newPixels, start1, length1);
-                    start += rowLength;
-                    start1 += rowLength;
-                }
-
-            }
-
-            // Cycle over pixels to be calculated
-            for (int i = yOrigin; i < srcConvMaxY; i++) {
-                for (int j = xOrigin; j < srcConvMaxX; j++) {
-
-                    // Take kernel data in backward direction, convolution
-                    int kernelIdx = data.length - 1;
-
-                    int pixelIndex = i * rowLength + j * numBands;
-                    for (int hIdx = 0, rasterHIdx = i - yOrigin; hIdx < kHeight; hIdx++, rasterHIdx++) {
-                        for (int wIdx = 0, rasterWIdx = j - xOrigin; wIdx < kWidth; wIdx++, rasterWIdx++) {
-                            int curIndex = rasterHIdx * rowLength + rasterWIdx * numBands;
-                            for (int idx = 0; idx < numBands; idx++) {
-                                newPixels[pixelIndex + idx] += data[kernelIdx]
-                                        * pixels[curIndex + idx];
-                            }
-                            kernelIdx--;
-                        }
-                    }
-
-                    // Check for overflow now
-                    for (int idx = 0; idx < numBands; idx++) {
-                        if (((int)newPixels[pixelIndex + idx] & masks[idx]) != 0) {
-                            if (newPixels[pixelIndex + idx] < 0) {
-                                newPixels[pixelIndex + idx] = 0;
-                            } else {
-                                newPixels[pixelIndex + idx] = maxValues[idx];
-                            }
-                        }
-                    }
-                }
-            }
-
-            dst.setPixels(dstMinX, dstMinY, srcWidth, srcHeight, newPixels);
-        } catch (Exception e) { // Something goes wrong, signal error
-            return 1;
-        }
-        return 0;
-    }
-
-    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
-        if (src == null) {
-            // awt.259=Source image is null
-            throw new NullPointerException(Messages.getString("awt.259")); //$NON-NLS-1$
-        }
-
-        if (src == dst) {
-            // awt.25A=Source equals to destination
-            throw new IllegalArgumentException(Messages.getString("awt.25A")); //$NON-NLS-1$
-        }
-
-        ColorModel srcCM = src.getColorModel();
-        BufferedImage finalDst = null;
-
-        if (srcCM instanceof IndexColorModel) {
-            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), true);
-            srcCM = src.getColorModel();
-        }
-
-        if (dst == null) {
-            dst = createCompatibleDestImage(src, srcCM);
-        } else {
-            if (!srcCM.equals(dst.getColorModel())) {
-                // Treat BufferedImage.TYPE_INT_RGB and
-                // BufferedImage.TYPE_INT_ARGB as same
-                if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src.getType() == BufferedImage.TYPE_INT_ARGB) && (dst
-                        .getType() == BufferedImage.TYPE_INT_RGB || dst.getType() == BufferedImage.TYPE_INT_ARGB))) {
-                    finalDst = dst;
-                    dst = createCompatibleDestImage(src, srcCM);
-                }
-            }
-        }
-
-        // Skip alpha channel for TYPE_INT_RGB images
-        // TODO
-        // if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) != 0)
-        if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
-            // awt.21F=Unable to transform source
-            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
-        }
-
-        if (finalDst != null) {
-            Graphics2D g = finalDst.createGraphics();
-            g.setComposite(AlphaComposite.Src);
-            g.drawImage(dst, 0, 0, null);
-        } else {
-            finalDst = dst;
-        }
-
-        return finalDst;
-    }
-
-    // TODO remove when this method is used
-    /**
-     * Ipp filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @param imageType
-     *            the image type.
-     * @return the int.
-     */
-    @SuppressWarnings("unused")
-    private int ippFilter(Raster src, WritableRaster dst, int imageType) {
-        int srcStride, dstStride;
-        boolean skipChannel = false;
-        int channels;
-        int offsets[] = null;
-
-        switch (imageType) {
-            case BufferedImage.TYPE_INT_RGB:
-            case BufferedImage.TYPE_INT_BGR: {
-                channels = 4;
-                srcStride = src.getWidth() * 4;
-                dstStride = dst.getWidth() * 4;
-                skipChannel = true;
-                break;
-            }
-
-            case BufferedImage.TYPE_INT_ARGB:
-            case BufferedImage.TYPE_INT_ARGB_PRE:
-            case BufferedImage.TYPE_4BYTE_ABGR:
-            case BufferedImage.TYPE_4BYTE_ABGR_PRE: {
-                channels = 4;
-                srcStride = src.getWidth() * 4;
-                dstStride = dst.getWidth() * 4;
-                break;
-            }
-
-            case BufferedImage.TYPE_BYTE_GRAY: {
-                channels = 1;
-                srcStride = src.getWidth();
-                dstStride = dst.getWidth();
-                break;
-            }
-
-            case BufferedImage.TYPE_3BYTE_BGR: {
-                channels = 3;
-                srcStride = src.getWidth() * 3;
-                dstStride = dst.getWidth() * 3;
-                break;
-            }
-
-            case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in
-                // native code?
-            case BufferedImage.TYPE_USHORT_565_RGB:
-            case BufferedImage.TYPE_USHORT_555_RGB:
-            case BufferedImage.TYPE_BYTE_BINARY: {
-                return slowFilter(src, dst);
-            }
-
-            default: {
-                SampleModel srcSM = src.getSampleModel();
-                SampleModel dstSM = dst.getSampleModel();
-
-                if (srcSM instanceof PixelInterleavedSampleModel
-                        && dstSM instanceof PixelInterleavedSampleModel) {
-                    // Check PixelInterleavedSampleModel
-                    if (srcSM.getDataType() != DataBuffer.TYPE_BYTE
-                            || dstSM.getDataType() != DataBuffer.TYPE_BYTE) {
-                        return slowFilter(src, dst);
-                    }
-
-                    channels = srcSM.getNumBands(); // Have IPP functions for 1,
-                    // 3 and 4 channels
-                    if (!(channels == 1 || channels == 3 || channels == 4)) {
-                        return slowFilter(src, dst);
-                    }
-
-                    srcStride = ((ComponentSampleModel)srcSM).getScanlineStride();
-                    dstStride = ((ComponentSampleModel)dstSM).getScanlineStride();
-                } else if (srcSM instanceof SinglePixelPackedSampleModel
-                        && dstSM instanceof SinglePixelPackedSampleModel) {
-                    // Check SinglePixelPackedSampleModel
-                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)srcSM;
-                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel)dstSM;
-
-                    channels = sppsm1.getNumBands();
-
-                    // TYPE_INT_RGB, TYPE_INT_ARGB...
-                    if (sppsm1.getDataType() != DataBuffer.TYPE_INT
-                            || sppsm2.getDataType() != DataBuffer.TYPE_INT
-                            || !(channels == 3 || channels == 4)) {
-                        return slowFilter(src, dst);
-                    }
-
-                    // Check compatibility of sample models
-                    if (!Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets())
-                            || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) {
-                        return slowFilter(src, dst);
-                    }
-
-                    for (int i = 0; i < channels; i++) {
-                        if (sppsm1.getSampleSize(i) != 8) {
-                            return slowFilter(src, dst);
-                        }
-                    }
-
-                    if (channels == 3) { // Cannot skip channel, don't know
-                        // which is alpha...
-                        channels = 4;
-                    }
-
-                    srcStride = sppsm1.getScanlineStride() * 4;
-                    dstStride = sppsm2.getScanlineStride() * 4;
-                } else {
-                    return slowFilter(src, dst);
-                }
-
-                // Fill offsets if there's a child raster
-                if (src.getParent() != null || dst.getParent() != null) {
-                    if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
-                            || dst.getSampleModelTranslateX() != 0
-                            || dst.getSampleModelTranslateY() != 0) {
-                        offsets = new int[4];
-                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
-                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
-                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
-                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
-                    }
-                }
-            }
-        }
-
-        Object srcData, dstData;
-        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
-        try {
-            srcData = dbAccess.getData(src.getDataBuffer());
-            dstData = dbAccess.getData(dst.getDataBuffer());
-        } catch (IllegalArgumentException e) {
-            return -1; // Unknown data buffer type
-        }
-
-        return ippFilter32f(kernel.data, kernel.getWidth(), kernel.getHeight(),
-                kernel.getXOrigin(), kernel.getYOrigin(), edgeCond, srcData, src.getWidth(), src
-                        .getHeight(), srcStride, dstData, dst.getWidth(), dst.getHeight(),
-                dstStride, channels, skipChannel, offsets);
-    }
-
-    /**
-     * Ipp filter32f.
-     * 
-     * @param kernel
-     *            the kernel.
-     * @param kWidth
-     *            the k width.
-     * @param kHeight
-     *            the k height.
-     * @param anchorX
-     *            the anchor x.
-     * @param anchorY
-     *            the anchor y.
-     * @param borderType
-     *            the border type.
-     * @param src
-     *            the src.
-     * @param srcWidth
-     *            the src width.
-     * @param srcHeight
-     *            the src height.
-     * @param srcStride
-     *            the src stride.
-     * @param dst
-     *            the dst.
-     * @param dstWidth
-     *            the dst width.
-     * @param dstHeight
-     *            the dst height.
-     * @param dstStride
-     *            the dst stride.
-     * @param channels
-     *            the channels.
-     * @param skipChannel
-     *            the skip channel.
-     * @param offsets
-     *            the offsets.
-     * @return the int.
-     */
-    private native int ippFilter32f(float kernel[], int kWidth, int kHeight, int anchorX,
-            int anchorY, int borderType, Object src, int srcWidth, int srcHeight, int srcStride,
-            Object dst, int dstWidth, int dstHeight, int dstStride, int channels,
-            boolean skipChannel, int offsets[]);
-}
diff --git a/awt/java/awt/image/CropImageFilter.java b/awt/java/awt/image/CropImageFilter.java
deleted file mode 100644
index 2f4ca78..0000000
--- a/awt/java/awt/image/CropImageFilter.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.util.Hashtable;
-
-/**
- * The CropImageFilter class crops a rectangular region of an source Image and
- * provides a source for a new image containing the extracted region.
- * 
- * @since Android 1.0
- */
-public class CropImageFilter extends ImageFilter {
-
-    /**
-     * The HEIGHT.
-     */
-    private final int X, Y, WIDTH, HEIGHT;
-
-    /**
-     * Instantiates a new CropImageFilter object with the specified rectangular
-     * area.
-     * 
-     * @param x
-     *            the X coordinate of rectangular area.
-     * @param y
-     *            the Y coordinate of rectangular area.
-     * @param w
-     *            the width of rectangular area.
-     * @param h
-     *            the height of rectangular area.
-     */
-    public CropImageFilter(int x, int y, int w, int h) {
-        X = x;
-        Y = y;
-        WIDTH = w;
-        HEIGHT = h;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void setProperties(Hashtable<?, ?> props) {
-        Hashtable<Object, Object> fprops;
-        if (props == null) {
-            fprops = new Hashtable<Object, Object>();
-        } else {
-            fprops = (Hashtable<Object, Object>)props.clone();
-        }
-        String propName = "Crop Filters"; //$NON-NLS-1$
-        String prop = "x=" + X + "; y=" + Y + "; width=" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-                WIDTH + "; height=" + HEIGHT; //$NON-NLS-1$
-        Object o = fprops.get(propName);
-        if (o != null) {
-            if (o instanceof String) {
-                prop = (String)o + "; " + prop; //$NON-NLS-1$
-            } else {
-                prop = o.toString() + "; " + prop; //$NON-NLS-1$
-            }
-        }
-        fprops.put(propName, prop);
-        consumer.setProperties(fprops);
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
-            int scansize) {
-
-        if (x + w < X || X + WIDTH < x || y + h < Y || Y + HEIGHT < y) {
-            return;
-        }
-
-        int destX, destY, destWidth, destHeight, endX, endY, srcEndX, srcEndY;
-
-        int newOffset = off;
-
-        endX = X + WIDTH;
-        endY = Y + HEIGHT;
-
-        srcEndX = x + w;
-        srcEndY = y + h;
-
-        if (x <= X) {
-            destX = 0;
-            newOffset += X;
-            if (endX >= srcEndX) {
-                destWidth = srcEndX - X;
-            } else {
-                destWidth = WIDTH;
-            }
-        } else {
-            destX = x - X;
-            if (endX >= srcEndX) {
-                destWidth = w;
-            } else {
-                destWidth = endX - x;
-            }
-        }
-
-        if (y <= Y) {
-            newOffset += scansize * (Y - y);
-            destY = 0;
-            if (endY >= srcEndY) {
-                destHeight = srcEndY - Y;
-            } else {
-                destHeight = HEIGHT;
-            }
-        } else {
-            destY = y - Y;
-            if (endY >= srcEndY) {
-                destHeight = h;
-            } else {
-                destHeight = endY - y;
-            }
-        }
-        consumer.setPixels(destX, destY, destWidth, destHeight, model, pixels, newOffset, scansize);
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
-            int scansize) {
-
-        if (x + w < X || X + WIDTH < x || y + h < Y || Y + HEIGHT < y) {
-            return;
-        }
-
-        int destX, destY, destWidth, destHeight, endX, endY, srcEndX, srcEndY;
-
-        int newOffset = off;
-
-        endX = X + WIDTH;
-        endY = Y + HEIGHT;
-
-        srcEndX = x + w;
-        srcEndY = y + h;
-
-        if (x <= X) {
-            destX = 0;
-            newOffset += X;
-            if (endX >= srcEndX) {
-                destWidth = srcEndX - X;
-            } else {
-                destWidth = WIDTH;
-            }
-        } else {
-            destX = x - X;
-            if (endX >= srcEndX) {
-                destWidth = w;
-            } else {
-                destWidth = endX - x;
-            }
-        }
-
-        if (y <= Y) {
-            newOffset += scansize * (Y - y);
-            destY = 0;
-            if (endY >= srcEndY) {
-                destHeight = srcEndY - Y;
-            } else {
-                destHeight = HEIGHT;
-            }
-        } else {
-            destY = y - Y;
-            if (endY >= srcEndY) {
-                destHeight = h;
-            } else {
-                destHeight = endY - y;
-            }
-        }
-        consumer.setPixels(destX, destY, destWidth, destHeight, model, pixels, newOffset, scansize);
-    }
-
-    @Override
-    public void setDimensions(int w, int h) {
-        consumer.setDimensions(WIDTH, HEIGHT);
-    }
-
-}
diff --git a/awt/java/awt/image/DataBuffer.java b/awt/java/awt/image/DataBuffer.java
deleted file mode 100644
index 92f900f..0000000
--- a/awt/java/awt/image/DataBuffer.java
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import org.apache.harmony.awt.gl.image.DataBufferListener;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class DataBuffer is a wrapper class for a data array to be used for the
- * situation where a suite of functionality acts on a set of data in a
- * consistent way even though the primitive type of the data may vary from one
- * use to the next.
- * 
- * @since Android 1.0
- */
-public abstract class DataBuffer {
-
-    /**
-     * The Constant TYPE_BYTE.
-     */
-    public static final int TYPE_BYTE = 0;
-
-    /**
-     * The Constant TYPE_USHORT.
-     */
-    public static final int TYPE_USHORT = 1;
-
-    /**
-     * The Constant TYPE_SHORT.
-     */
-    public static final int TYPE_SHORT = 2;
-
-    /**
-     * The Constant TYPE_INT.
-     */
-    public static final int TYPE_INT = 3;
-
-    /**
-     * The Constant TYPE_FLOAT.
-     */
-    public static final int TYPE_FLOAT = 4;
-
-    /**
-     * The Constant TYPE_DOUBLE.
-     */
-    public static final int TYPE_DOUBLE = 5;
-
-    /**
-     * The Constant TYPE_UNDEFINED.
-     */
-    public static final int TYPE_UNDEFINED = 32;
-
-    /**
-     * The data type indicates the primitive type of the data in this
-     * DataBuffer.
-     */
-    protected int dataType;
-
-    /**
-     * The number of data arrays in this DataBuffer.
-     */
-    protected int banks;
-
-    /**
-     * The starting index for reading the data from the first (or only) internal
-     * data array.
-     */
-    protected int offset;
-
-    /**
-     * The length (number of elements) of the data arrays.
-     */
-    protected int size;
-
-    /**
-     * The starting indices for reading the data from the internal data arrays.
-     */
-    protected int offsets[];
-
-    /**
-     * The data changed.
-     */
-    boolean dataChanged = true;
-
-    /**
-     * The data taken.
-     */
-    boolean dataTaken = false;
-
-    /**
-     * The listener.
-     */
-    DataBufferListener listener;
-
-    static {
-        AwtImageBackdoorAccessorImpl.init();
-    }
-
-    /**
-     * Instantiates a new data buffer.
-     * 
-     * @param dataType
-     *            the data type.
-     * @param size
-     *            the length (number of elements) of the data arrays.
-     * @param numBanks
-     *            the number of data arrays to create.
-     * @param offsets
-     *            the starting indices for reading the data from the internal
-     *            data arrays.
-     */
-    protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
-        this.dataType = dataType;
-        this.size = size;
-        this.banks = numBanks;
-        this.offsets = offsets.clone();
-        this.offset = offsets[0];
-    }
-
-    /**
-     * Instantiates a new data buffer with all of the data arrays starting at
-     * the same index.
-     * 
-     * @param dataType
-     *            the data type.
-     * @param size
-     *            the length (number of elements) of the data arrays.
-     * @param numBanks
-     *            the number of data arrays to create.
-     * @param offset
-     *            the offset to use for all of the data arrays.
-     */
-    protected DataBuffer(int dataType, int size, int numBanks, int offset) {
-        this.dataType = dataType;
-        this.size = size;
-        this.banks = numBanks;
-        this.offset = offset;
-        this.offsets = new int[numBanks];
-        int i = 0;
-        while (i < numBanks) {
-            offsets[i++] = offset;
-        }
-    }
-
-    /**
-     * Instantiates a new data buffer with all of the data arrays read from the
-     * beginning (at offset zero).
-     * 
-     * @param dataType
-     *            the data type.
-     * @param size
-     *            the length (number of elements) of the data arrays.
-     * @param numBanks
-     *            the number of data arrays to create.
-     */
-    protected DataBuffer(int dataType, int size, int numBanks) {
-        this.dataType = dataType;
-        this.size = size;
-        this.banks = numBanks;
-        this.offset = 0;
-        this.offsets = new int[numBanks];
-    }
-
-    /**
-     * Instantiates a new data buffer with one internal data array read from the
-     * beginning (at offset zero).
-     * 
-     * @param dataType
-     *            the data type.
-     * @param size
-     *            the length (number of elements) of the data arrays.
-     */
-    protected DataBuffer(int dataType, int size) {
-        this.dataType = dataType;
-        this.size = size;
-        this.banks = 1;
-        this.offset = 0;
-        this.offsets = new int[1];
-    }
-
-    /**
-     * Sets the data value in the specified array at the specified index.
-     * 
-     * @param bank
-     *            the internal array to the data to.
-     * @param i
-     *            the index within the array where the data should be written.
-     * @param val
-     *            the value to write into the array.
-     */
-    public abstract void setElem(int bank, int i, int val);
-
-    /**
-     * Sets the float data value in the specified array at the specified index.
-     * 
-     * @param bank
-     *            the internal array to the data to.
-     * @param i
-     *            the index within the array where the data should be written.
-     * @param val
-     *            the value to write into the array.
-     */
-    public void setElemFloat(int bank, int i, float val) {
-        setElem(bank, i, (int)val);
-    }
-
-    /**
-     * Sets the double data value in the specified array at the specified index.
-     * 
-     * @param bank
-     *            the internal array to the data to.
-     * @param i
-     *            the index within the array where the data should be written.
-     * @param val
-     *            the value to write into the array.
-     */
-    public void setElemDouble(int bank, int i, double val) {
-        setElem(bank, i, (int)val);
-    }
-
-    /**
-     * Sets the data value in the first array at the specified index.
-     * 
-     * @param i
-     *            the index within the array where the data should be written.
-     * @param val
-     *            the value to write into the array.
-     */
-    public void setElem(int i, int val) {
-        setElem(0, i, val);
-    }
-
-    /**
-     * Gets the data value from the specified data array at the specified index.
-     * 
-     * @param bank
-     *            the data array to read from.
-     * @param i
-     *            the index within the array where the data should be read.
-     * @return the data element.
-     */
-    public abstract int getElem(int bank, int i);
-
-    /**
-     * Gets the float-type data value from the specified data array at the
-     * specified index.
-     * 
-     * @param bank
-     *            the data array to read from.
-     * @param i
-     *            the index within the array where the data should be read.
-     * @return the data element.
-     */
-    public float getElemFloat(int bank, int i) {
-        return getElem(bank, i);
-    }
-
-    /**
-     * Gets the double-type data value from the specified data array at the
-     * specified index.
-     * 
-     * @param bank
-     *            the data array to read from.
-     * @param i
-     *            the index within the array where the data should be read.
-     * @return the data element.
-     */
-    public double getElemDouble(int bank, int i) {
-        return getElem(bank, i);
-    }
-
-    /**
-     * Sets the float data value in the first array at the specified index.
-     * 
-     * @param i
-     *            the index within the array where the data should be written.
-     * @param val
-     *            the value to write into the array.
-     */
-    public void setElemFloat(int i, float val) {
-        setElemFloat(0, i, val);
-    }
-
-    /**
-     * Sets the double data value in the first array at the specified index.
-     * 
-     * @param i
-     *            the index within the array where the data should be written.
-     * @param val
-     *            the value to write into the array.
-     */
-    public void setElemDouble(int i, double val) {
-        setElemDouble(0, i, val);
-    }
-
-    /**
-     * Gets the data value from the first data array at the specified index and
-     * returns it as an integer.
-     * 
-     * @param i
-     *            the index within the array where the data should be read.
-     * @return the data element.
-     */
-    public int getElem(int i) {
-        return getElem(0, i);
-    }
-
-    /**
-     * Gets the data value from the first data array at the specified index and
-     * returns it as a float.
-     * 
-     * @param i
-     *            the index within the array where the data should be read.
-     * @return the data element.
-     */
-    public float getElemFloat(int i) {
-        return getElem(0, i);
-    }
-
-    /**
-     * Gets the data value from the first data array at the specified index and
-     * returns it as a double.
-     * 
-     * @param i
-     *            the index within the array where the data should be read.
-     * @return the data element.
-     */
-    public double getElemDouble(int i) {
-        return getElem(i);
-    }
-
-    /**
-     * Gets the array giving the offsets corresponding to the internal data
-     * arrays.
-     * 
-     * @return the array of offsets.
-     */
-    public int[] getOffsets() {
-        return offsets;
-    }
-
-    /**
-     * Gets the size in bits of the primitive data type.
-     * 
-     * @return the size in bits of the primitive data type.
-     */
-    public int getSize() {
-        return size;
-    }
-
-    /**
-     * Gets the offset corresponding to the first internal data array.
-     * 
-     * @return the offset.
-     */
-    public int getOffset() {
-        return offset;
-    }
-
-    /**
-     * Gets the number of data arrays in this DataBuffer.
-     * 
-     * @return the number of data arrays.
-     */
-    public int getNumBanks() {
-        return banks;
-    }
-
-    /**
-     * Gets the primitive type of this buffer's data.
-     * 
-     * @return the data type.
-     */
-    public int getDataType() {
-        return this.dataType;
-    }
-
-    /**
-     * Gets the size in bits of the primitive data type.
-     * 
-     * @param type
-     *            the primitive type.
-     * @return the size in bits of the primitive data type.
-     */
-    public static int getDataTypeSize(int type) {
-        switch (type) {
-
-            case TYPE_BYTE:
-                return 8;
-
-            case TYPE_USHORT:
-            case TYPE_SHORT:
-                return 16;
-
-            case TYPE_INT:
-            case TYPE_FLOAT:
-                return 32;
-
-            case TYPE_DOUBLE:
-                return 64;
-
-            default:
-                // awt.22C=Unknown data type {0}
-                throw new IllegalArgumentException(Messages.getString("awt.22C", type)); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Notifies the listener that the data has changed.
-     */
-    void notifyChanged() {
-        if (listener != null && !dataChanged) {
-            dataChanged = true;
-            listener.dataChanged();
-        }
-    }
-
-    /**
-     * Notifies the listener that the data has been released.
-     */
-    void notifyTaken() {
-        if (listener != null && !dataTaken) {
-            dataTaken = true;
-            listener.dataTaken();
-        }
-    }
-
-    /**
-     * Release the data.
-     */
-    void releaseData() {
-        if (listener != null && dataTaken) {
-            dataTaken = false;
-            listener.dataReleased();
-        }
-    }
-
-    /**
-     * Adds the data buffer listener.
-     * 
-     * @param listener
-     *            the listener.
-     */
-    void addDataBufferListener(DataBufferListener listener) {
-        this.listener = listener;
-    }
-
-    /**
-     * Removes the data buffer listener.
-     */
-    void removeDataBufferListener() {
-        listener = null;
-    }
-
-    /**
-     * Validate.
-     */
-    void validate() {
-        dataChanged = false;
-    }
-
-}
diff --git a/awt/java/awt/image/DataBufferByte.java b/awt/java/awt/image/DataBufferByte.java
deleted file mode 100644
index 3407de8..0000000
--- a/awt/java/awt/image/DataBufferByte.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-/**
- * The Class DataBufferByte is the subclass of DataBuffer for the case where the
- * underlying data is of type byte.
- * 
- * @since Android 1.0
- */
-public final class DataBufferByte extends DataBuffer {
-
-    /**
-     * The data.
-     */
-    byte data[][];
-
-    /**
-     * Instantiates a new data buffer of type unsigned short.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param offsets
-     *            the starting indices for reading the data from the internal
-     *            data arrays.
-     */
-    public DataBufferByte(byte dataArrays[][], int size, int offsets[]) {
-        super(TYPE_BYTE, size, dataArrays.length, offsets);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type unsigned short.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     */
-    public DataBufferByte(byte dataArrays[][], int size) {
-        super(TYPE_BYTE, size, dataArrays.length);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type unsigned short with a single
-     * underlying array of data.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     * @param offset
-     *            the starting index to use when reading the data.
-     */
-    public DataBufferByte(byte dataArray[], int size, int offset) {
-        super(TYPE_BYTE, size, 1, offset);
-        data = new byte[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new data buffer of type unsigned short with a single
-     * underlying array of data starting at index 0.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferByte(byte dataArray[], int size) {
-        super(TYPE_BYTE, size);
-        data = new byte[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type unsigned short with offsets
-     * equal to zero.
-     * 
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param numBanks
-     *            the number of data arrays to create.
-     */
-    public DataBufferByte(int size, int numBanks) {
-        super(TYPE_BYTE, size, numBanks);
-        data = new byte[numBanks][];
-        int i = 0;
-        while (i < numBanks) {
-            data[i++] = new byte[size];
-        }
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type unsigned short with a single
-     * underlying array of data starting at index 0.
-     * 
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferByte(int size) {
-        super(TYPE_BYTE, size);
-        data = new byte[1][];
-        data[0] = new byte[size];
-    }
-
-    @Override
-    public void setElem(int bank, int i, int val) {
-        data[bank][offsets[bank] + i] = (byte)val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElem(int i, int val) {
-        data[0][offset + i] = (byte)val;
-        notifyChanged();
-    }
-
-    @Override
-    public int getElem(int bank, int i) {
-        return (data[bank][offsets[bank] + i]) & 0xff;
-    }
-
-    /**
-     * Gets the data of the specified internal data array.
-     * 
-     * @param bank
-     *            the index of the desired data array.
-     * @return the data.
-     */
-    public byte[] getData(int bank) {
-        notifyTaken();
-        return data[bank];
-    }
-
-    @Override
-    public int getElem(int i) {
-        return (data[0][offset + i]) & 0xff;
-    }
-
-    /**
-     * Gets the bank data.
-     * 
-     * @return the bank data.
-     */
-    public byte[][] getBankData() {
-        notifyTaken();
-        return data.clone();
-    }
-
-    /**
-     * Gets the data of the first data array.
-     * 
-     * @return the data.
-     */
-    public byte[] getData() {
-        notifyTaken();
-        return data[0];
-    }
-
-}
diff --git a/awt/java/awt/image/DataBufferDouble.java b/awt/java/awt/image/DataBufferDouble.java
deleted file mode 100644
index 5d0a516..0000000
--- a/awt/java/awt/image/DataBufferDouble.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-/**
- * The Class DataBufferDouble is the subclass of DataBuffer for the case where
- * the underlying data is of type double.
- * 
- * @since Android 1.0
- */
-public final class DataBufferDouble extends DataBuffer {
-
-    /**
-     * The data.
-     */
-    double data[][];
-
-    /**
-     * Instantiates a new data buffer of type double.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param offsets
-     *            the starting indices for reading the data from the internal
-     *            data arrays.
-     */
-    public DataBufferDouble(double dataArrays[][], int size, int offsets[]) {
-        super(TYPE_DOUBLE, size, dataArrays.length, offsets);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type double.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     */
-    public DataBufferDouble(double dataArrays[][], int size) {
-        super(TYPE_DOUBLE, size, dataArrays.length);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type double with a single underlying
-     * array of data.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     * @param offset
-     *            the starting index to use when reading the data.
-     */
-    public DataBufferDouble(double dataArray[], int size, int offset) {
-        super(TYPE_DOUBLE, size, 1, offset);
-        data = new double[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new data buffer of type double with a single underlying
-     * array of data starting at index 0.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferDouble(double dataArray[], int size) {
-        super(TYPE_DOUBLE, size);
-        data = new double[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type double with offsets equal to
-     * zero.
-     * 
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param numBanks
-     *            the number of data arrays to create.
-     */
-    public DataBufferDouble(int size, int numBanks) {
-        super(TYPE_DOUBLE, size, numBanks);
-        data = new double[numBanks][];
-        int i = 0;
-        while (i < numBanks) {
-            data[i++] = new double[size];
-        }
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type double with a single
-     * underlying array of data starting at index 0.
-     * 
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferDouble(int size) {
-        super(TYPE_DOUBLE, size);
-        data = new double[1][];
-        data[0] = new double[size];
-    }
-
-    @Override
-    public void setElem(int bank, int i, int val) {
-        data[bank][offsets[bank] + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElemFloat(int bank, int i, float val) {
-        data[bank][offsets[bank] + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElemDouble(int bank, int i, double val) {
-        data[bank][offsets[bank] + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElem(int i, int val) {
-        data[0][offset + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public int getElem(int bank, int i) {
-        return (int)(data[bank][offsets[bank] + i]);
-    }
-
-    @Override
-    public float getElemFloat(int bank, int i) {
-        return (float)(data[bank][offsets[bank] + i]);
-    }
-
-    @Override
-    public double getElemDouble(int bank, int i) {
-        return data[bank][offsets[bank] + i];
-    }
-
-    @Override
-    public void setElemFloat(int i, float val) {
-        data[0][offset + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElemDouble(int i, double val) {
-        data[0][offset + i] = val;
-        notifyChanged();
-    }
-
-    /**
-     * Gets the data of the specified internal data array.
-     * 
-     * @param bank
-     *            the index of the desired data array.
-     * @return the data.
-     */
-    public double[] getData(int bank) {
-        notifyTaken();
-        return data[bank];
-    }
-
-    @Override
-    public int getElem(int i) {
-        return (int)(data[0][offset + i]);
-    }
-
-    @Override
-    public float getElemFloat(int i) {
-        return (float)(data[0][offset + i]);
-    }
-
-    @Override
-    public double getElemDouble(int i) {
-        return data[0][offset + i];
-    }
-
-    /**
-     * Gets the bank data.
-     * 
-     * @return the bank data.
-     */
-    public double[][] getBankData() {
-        notifyTaken();
-        return data.clone();
-    }
-
-    /**
-     * Gets the data of the first data array.
-     * 
-     * @return the data.
-     */
-    public double[] getData() {
-        notifyTaken();
-        return data[0];
-    }
-}
diff --git a/awt/java/awt/image/DataBufferFloat.java b/awt/java/awt/image/DataBufferFloat.java
deleted file mode 100644
index 9a4a6bf..0000000
--- a/awt/java/awt/image/DataBufferFloat.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-/**
- * The Class DataBufferFloat is the subclass of DataBuffer for the case where
- * the underlying data is float.
- * 
- * @since Android 1.0
- */
-public final class DataBufferFloat extends DataBuffer {
-
-    /**
-     * The data.
-     */
-    float data[][];
-
-    /**
-     * Instantiates a new data buffer of type float.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param offsets
-     *            the starting indices for reading the data from the internal
-     *            data arrays.
-     */
-    public DataBufferFloat(float dataArrays[][], int size, int offsets[]) {
-        super(TYPE_FLOAT, size, dataArrays.length, offsets);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type float.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     */
-    public DataBufferFloat(float dataArrays[][], int size) {
-        super(TYPE_FLOAT, size, dataArrays.length);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type float with a single underlying
-     * array of data.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     * @param offset
-     *            the starting index to use when reading the data.
-     */
-    public DataBufferFloat(float dataArray[], int size, int offset) {
-        super(TYPE_FLOAT, size, 1, offset);
-        data = new float[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new data buffer of type float with a single underlying
-     * array of data starting at index 0.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferFloat(float dataArray[], int size) {
-        super(TYPE_FLOAT, size);
-        data = new float[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type float with offsets equal to
-     * zero.
-     * 
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param numBanks
-     *            the number of data arrays to create.
-     */
-    public DataBufferFloat(int size, int numBanks) {
-        super(TYPE_FLOAT, size, numBanks);
-        data = new float[numBanks][];
-        int i = 0;
-        while (i < numBanks) {
-            data[i++] = new float[size];
-        }
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type float with a single
-     * underlying array of data starting at index 0.
-     * 
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferFloat(int size) {
-        super(TYPE_FLOAT, size);
-        data = new float[1][];
-        data[0] = new float[size];
-    }
-
-    @Override
-    public void setElem(int bank, int i, int val) {
-        data[bank][offsets[bank] + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElemFloat(int bank, int i, float val) {
-        data[bank][offsets[bank] + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElemDouble(int bank, int i, double val) {
-        data[bank][offsets[bank] + i] = (float)val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElem(int i, int val) {
-        data[0][offset + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public int getElem(int bank, int i) {
-        return (int)(data[bank][offsets[bank] + i]);
-    }
-
-    @Override
-    public float getElemFloat(int bank, int i) {
-        return data[bank][offsets[bank] + i];
-    }
-
-    @Override
-    public double getElemDouble(int bank, int i) {
-        return data[bank][offsets[bank] + i];
-    }
-
-    @Override
-    public void setElemFloat(int i, float val) {
-        data[0][offset + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElemDouble(int i, double val) {
-        data[0][offset + i] = (float)val;
-        notifyChanged();
-    }
-
-    /**
-     * Gets the data of the specified internal data array.
-     * 
-     * @param bank
-     *            the index of the desired array.
-     * @return the data.
-     */
-    public float[] getData(int bank) {
-        notifyTaken();
-        return data[bank];
-    }
-
-    @Override
-    public int getElem(int i) {
-        return (int)(data[0][offset + i]);
-    }
-
-    @Override
-    public float getElemFloat(int i) {
-        return data[0][offset + i];
-    }
-
-    @Override
-    public double getElemDouble(int i) {
-        return data[0][offset + i];
-    }
-
-    /**
-     * Gets the bank data.
-     * 
-     * @return the bank data.
-     */
-    public float[][] getBankData() {
-        notifyTaken();
-        return data.clone();
-    }
-
-    /**
-     * Gets the data of the first data array.
-     * 
-     * @return the data.
-     */
-    public float[] getData() {
-        notifyTaken();
-        return data[0];
-    }
-}
diff --git a/awt/java/awt/image/DataBufferInt.java b/awt/java/awt/image/DataBufferInt.java
deleted file mode 100644
index 380a127..0000000
--- a/awt/java/awt/image/DataBufferInt.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-/**
- * The Class DataBufferInt is the subclass of DataBuffer for the case where the
- * underlying data is of type integer.
- * 
- * @since Android 1.0
- */
-public final class DataBufferInt extends DataBuffer {
-
-    /**
-     * The data.
-     */
-    int data[][];
-
-    /**
-     * Instantiates a new data buffer of type integer.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param offsets
-     *            the starting indices for reading the data from the internal
-     *            data arrays.
-     */
-    public DataBufferInt(int dataArrays[][], int size, int offsets[]) {
-        super(TYPE_INT, size, dataArrays.length, offsets);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type integer.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     */
-    public DataBufferInt(int dataArrays[][], int size) {
-        super(TYPE_INT, size, dataArrays.length);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type integer with a single underlying
-     * array of data.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     * @param offset
-     *            the starting index to use when reading the data.
-     */
-    public DataBufferInt(int dataArray[], int size, int offset) {
-        super(TYPE_INT, size, 1, offset);
-        data = new int[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new data buffer of type integer with a single underlying
-     * array of data starting at index 0.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferInt(int dataArray[], int size) {
-        super(TYPE_INT, size);
-        data = new int[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type integer with offsets equal
-     * to zero.
-     * 
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param numBanks
-     *            the number of data arrays to create.
-     */
-    public DataBufferInt(int size, int numBanks) {
-        super(TYPE_INT, size, numBanks);
-        data = new int[numBanks][];
-        int i = 0;
-        while (i < numBanks) {
-            data[i++] = new int[size];
-        }
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type integer with a single
-     * underlying array of data starting at index 0.
-     * 
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferInt(int size) {
-        super(TYPE_INT, size);
-        data = new int[1][];
-        data[0] = new int[size];
-    }
-
-    @Override
-    public void setElem(int bank, int i, int val) {
-        data[bank][offsets[bank] + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElem(int i, int val) {
-        data[0][offset + i] = val;
-        notifyChanged();
-    }
-
-    @Override
-    public int getElem(int bank, int i) {
-        return data[bank][offsets[bank] + i];
-    }
-
-    /**
-     * Gets the data of the specified internal data array.
-     * 
-     * @param bank
-     *            the index of the desired data array.
-     * @return the data.
-     */
-    public int[] getData(int bank) {
-        notifyTaken();
-        return data[bank];
-    }
-
-    @Override
-    public int getElem(int i) {
-        return data[0][offset + i];
-    }
-
-    /**
-     * Gets the bank data.
-     * 
-     * @return the bank data.
-     */
-    public int[][] getBankData() {
-        notifyTaken();
-        return data.clone();
-    }
-
-    /**
-     * Gets the data of the first data array.
-     * 
-     * @return the data.
-     */
-    public int[] getData() {
-        notifyTaken();
-        return data[0];
-    }
-}
diff --git a/awt/java/awt/image/DataBufferShort.java b/awt/java/awt/image/DataBufferShort.java
deleted file mode 100644
index 1b11b29..0000000
--- a/awt/java/awt/image/DataBufferShort.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-/**
- * The Class DataBufferShort is the subclass of DataBuffer for the case where
- * the underlying data is short.
- * 
- * @since Android 1.0
- */
-public final class DataBufferShort extends DataBuffer {
-
-    /**
-     * The data.
-     */
-    short data[][];
-
-    /**
-     * Instantiates a new data buffer of type short.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param offsets
-     *            the starting indices for reading the data from the internal
-     *            data arrays.
-     */
-    public DataBufferShort(short dataArrays[][], int size, int offsets[]) {
-        super(TYPE_SHORT, size, dataArrays.length, offsets);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type short.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     */
-    public DataBufferShort(short dataArrays[][], int size) {
-        super(TYPE_SHORT, size, dataArrays.length);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type short with a single underlying
-     * array of data.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     * @param offset
-     *            the starting index to use when reading the data.
-     */
-    public DataBufferShort(short dataArray[], int size, int offset) {
-        super(TYPE_SHORT, size, 1, offset);
-        data = new short[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new data buffer of type short with a single underlying
-     * array of data starting at index 0.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferShort(short dataArray[], int size) {
-        super(TYPE_SHORT, size);
-        data = new short[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new data buffer of type short with offsets equal to zero.
-     * 
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param numBanks
-     *            the number of data arrays to create.
-     */
-    public DataBufferShort(int size, int numBanks) {
-        super(TYPE_SHORT, size, numBanks);
-        data = new short[numBanks][];
-        int i = 0;
-        while (i < numBanks) {
-            data[i++] = new short[size];
-        }
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type short with a single
-     * underlying array of data starting at index 0.
-     * 
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferShort(int size) {
-        super(TYPE_SHORT, size);
-        data = new short[1][];
-        data[0] = new short[size];
-    }
-
-    @Override
-    public void setElem(int bank, int i, int val) {
-        data[bank][offsets[bank] + i] = (short)val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElem(int i, int val) {
-        data[0][offset + i] = (short)val;
-        notifyChanged();
-    }
-
-    @Override
-    public int getElem(int bank, int i) {
-        return (data[bank][offsets[bank] + i]);
-    }
-
-    /**
-     * Gets the data of the specified internal data array.
-     * 
-     * @param bank
-     *            the index of the desired data array.
-     * @return the data.
-     */
-    public short[] getData(int bank) {
-        notifyTaken();
-        return data[bank];
-    }
-
-    @Override
-    public int getElem(int i) {
-        return (data[0][offset + i]);
-    }
-
-    /**
-     * Gets the bank data.
-     * 
-     * @return the bank data.
-     */
-    public short[][] getBankData() {
-        notifyTaken();
-        return data.clone();
-    }
-
-    /**
-     * Gets the data of the first data array.
-     * 
-     * @return the data.
-     */
-    public short[] getData() {
-        notifyTaken();
-        return data[0];
-    }
-}
diff --git a/awt/java/awt/image/DataBufferUShort.java b/awt/java/awt/image/DataBufferUShort.java
deleted file mode 100644
index 58d9d83..0000000
--- a/awt/java/awt/image/DataBufferUShort.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class DataBufferUShort is the subclass of DataBuffer for the case where
- * the underlying data is unsigned short.
- * 
- * @since Android 1.0
- */
-public final class DataBufferUShort extends DataBuffer {
-
-    /**
-     * The data.
-     */
-    short data[][];
-
-    /**
-     * Instantiates a new data buffer of type unsigned short.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param offsets
-     *            the starting indices for reading the data from the internal
-     *            data arrays.
-     */
-    public DataBufferUShort(short dataArrays[][], int size, int offsets[]) {
-        super(TYPE_USHORT, size, dataArrays.length, offsets);
-        for (int i = 0; i < dataArrays.length; i++) {
-            if (dataArrays[i].length < offsets[i] + size) {
-                // awt.28d=Length of dataArray[{0}] is less than size +
-                // offset[{1}]
-                throw new IllegalArgumentException(Messages.getString("awt.28D", i, i)); //$NON-NLS-1$
-            }
-        }
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type unsigned short.
-     * 
-     * @param dataArrays
-     *            the data arrays to copy the data from.
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     */
-    public DataBufferUShort(short dataArrays[][], int size) {
-        super(TYPE_USHORT, size, dataArrays.length);
-        data = dataArrays.clone();
-    }
-
-    /**
-     * Instantiates a new data buffer of type unsigned short with a single
-     * underlying array of data.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     * @param offset
-     *            the starting index to use when reading the data.
-     */
-    public DataBufferUShort(short dataArray[], int size, int offset) {
-        super(TYPE_USHORT, size, 1, offset);
-        if (dataArray.length < size + offset) {
-            // awt.28E=Length of dataArray is less than size + offset
-            throw new IllegalArgumentException(Messages.getString("awt.28E")); //$NON-NLS-1$
-        }
-        data = new short[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new data buffer of type unsigned short with a single
-     * underlying array of data starting at index 0.
-     * 
-     * @param dataArray
-     *            the data array to copy the data from.
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferUShort(short dataArray[], int size) {
-        super(TYPE_USHORT, size);
-        data = new short[1][];
-        data[0] = dataArray;
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type unsigned short with offsets
-     * equal to zero.
-     * 
-     * @param size
-     *            the length (number of elements) to use from the data arrays.
-     * @param numBanks
-     *            the number of data arrays to create.
-     */
-    public DataBufferUShort(int size, int numBanks) {
-        super(TYPE_USHORT, size, numBanks);
-        data = new short[numBanks][];
-        int i = 0;
-        while (i < numBanks) {
-            data[i++] = new short[size];
-        }
-    }
-
-    /**
-     * Instantiates a new empty data buffer of type unsigned short with a single
-     * underlying array of data starting at index 0.
-     * 
-     * @param size
-     *            the length (number of elements) to use.
-     */
-    public DataBufferUShort(int size) {
-        super(TYPE_USHORT, size);
-        data = new short[1][];
-        data[0] = new short[size];
-    }
-
-    @Override
-    public void setElem(int bank, int i, int val) {
-        data[bank][offsets[bank] + i] = (short)val;
-        notifyChanged();
-    }
-
-    @Override
-    public void setElem(int i, int val) {
-        data[0][offset + i] = (short)val;
-        notifyChanged();
-    }
-
-    @Override
-    public int getElem(int bank, int i) {
-        return (data[bank][offsets[bank] + i]) & 0xffff;
-    }
-
-    /**
-     * Gets the data of the specified internal data array.
-     * 
-     * @param bank
-     *            the index of the desired data array.
-     * @return the data.
-     */
-    public short[] getData(int bank) {
-        notifyTaken();
-        return data[bank];
-    }
-
-    @Override
-    public int getElem(int i) {
-        return (data[0][offset + i]) & 0xffff;
-    }
-
-    /**
-     * Gets the bank data.
-     * 
-     * @return the bank data.
-     */
-    public short[][] getBankData() {
-        notifyTaken();
-        return data.clone();
-    }
-
-    /**
-     * Gets the data of the first data array.
-     * 
-     * @return the data.
-     */
-    public short[] getData() {
-        notifyTaken();
-        return data[0];
-    }
-}
diff --git a/awt/java/awt/image/DirectColorModel.java b/awt/java/awt/image/DirectColorModel.java
deleted file mode 100644
index 700eb7a..0000000
--- a/awt/java/awt/image/DirectColorModel.java
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.color.ColorSpace;
-import java.awt.Transparency;
-import java.util.Arrays;
-
-import org.apache.harmony.awt.gl.color.LUTColorConverter;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class DirectColorModel represents a standard (packed) RGB color model
- * with additional support for converting between sRGB color space and 8 or 16
- * bit linear RGB color space using lookup tables.
- * 
- * @since Android 1.0
- */
-public class DirectColorModel extends PackedColorModel {
-
-    /**
-     * The from_ linea r_ rg b_ lut.
-     */
-    private byte from_LINEAR_RGB_LUT[]; // Lookup table for conversion from
-
-    // Linear RGB Color Space into sRGB
-
-    /**
-     * The to_ linea r_8 rg b_ lut.
-     */
-    private byte to_LINEAR_8RGB_LUT[]; // Lookup table for conversion from
-
-    // sRGB Color Space into Linear RGB
-    // 8 bit
-
-    /**
-     * The to_ linea r_16 rg b_ lut.
-     */
-    private short to_LINEAR_16RGB_LUT[]; // Lookup table for conversion from
-
-    // sRGB Color Space into Linear RGB
-    // 16 bit
-
-    /**
-     * The alpha lut.
-     */
-    private byte alphaLUT[]; // Lookup table for scale alpha value
-
-    /**
-     * The color lu ts.
-     */
-    private byte colorLUTs[][]; // Lookup tables for scale color values
-
-    /**
-     * The is_s rgb.
-     */
-    private boolean is_sRGB; // ColorModel has sRGB ColorSpace
-
-    /**
-     * The is_ linea r_ rgb.
-     */
-    private boolean is_LINEAR_RGB; // Color Model has Linear RGB Color
-
-    // Space
-
-    /**
-     * The LINEA r_ rg b_ length.
-     */
-    private int LINEAR_RGB_Length; // Linear RGB bit length
-
-    /**
-     * The factor.
-     */
-    private float fFactor; // Scale factor
-
-    /**
-     * Instantiates a new direct color model.
-     * 
-     * @param space
-     *            the color space.
-     * @param bits
-     *            the array of component masks.
-     * @param rmask
-     *            the bitmask corresponding to the red band.
-     * @param gmask
-     *            the bitmask corresponding to the green band.
-     * @param bmask
-     *            the bitmask corresponding to the blue band.
-     * @param amask
-     *            the bitmask corresponding to the alpha band.
-     * @param isAlphaPremultiplied
-     *            whether the alpha is pre-multiplied in this color model.
-     * @param transferType
-     *            the transfer type (primitive java type to use for the
-     *            components).
-     * @throws IllegalArgumentException
-     *             if the number of bits in the combined bitmasks for the color
-     *             bands is less than one or greater than 32.
-     */
-    public DirectColorModel(ColorSpace space, int bits, int rmask, int gmask, int bmask, int amask,
-            boolean isAlphaPremultiplied, int transferType) {
-
-        super(space, bits, rmask, gmask, bmask, amask, isAlphaPremultiplied,
-                (amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT), transferType);
-
-        initLUTs();
-    }
-
-    /**
-     * Instantiates a new direct color model, determining the transfer type from
-     * the bits array, the transparency from the alpha mask, and the default
-     * color space {@link ColorSpace#CS_sRGB}.
-     * 
-     * @param bits
-     *            the array of component masks.
-     * @param rmask
-     *            the bitmask corresponding to the red band.
-     * @param gmask
-     *            the bitmask corresponding to the green band.
-     * @param bmask
-     *            the bitmask corresponding to the blue band.
-     * @param amask
-     *            the bitmask corresponding to the alpha band.
-     */
-    public DirectColorModel(int bits, int rmask, int gmask, int bmask, int amask) {
-
-        super(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits, rmask, gmask, bmask, amask, false,
-                (amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT), ColorModel
-                        .getTransferType(bits));
-
-        initLUTs();
-    }
-
-    /**
-     * Instantiates a new direct color model with no alpha channel, determining
-     * the transfer type from the bits array, the default color space
-     * {@link ColorSpace#CS_sRGB}, and with the transparency set to
-     * {@link Transparency#OPAQUE}.
-     * 
-     * @param bits
-     *            the array of component masks.
-     * @param rmask
-     *            the bitmask corresponding to the red band.
-     * @param gmask
-     *            the bitmask corresponding to the green band.
-     * @param bmask
-     *            the bitmask corresponding to the blue band.
-     */
-    public DirectColorModel(int bits, int rmask, int gmask, int bmask) {
-        this(bits, rmask, gmask, bmask, 0);
-    }
-
-    @Override
-    public Object getDataElements(int components[], int offset, Object obj) {
-        int pixel = 0;
-        for (int i = 0; i < numComponents; i++) {
-            pixel |= (components[offset + i] << offsets[i]) & componentMasks[i];
-        }
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[];
-                if (obj == null) {
-                    ba = new byte[1];
-                } else {
-                    ba = (byte[])obj;
-                }
-                ba[0] = (byte)pixel;
-                obj = ba;
-                break;
-
-            case DataBuffer.TYPE_USHORT:
-                short sa[];
-                if (obj == null) {
-                    sa = new short[1];
-                } else {
-                    sa = (short[])obj;
-                }
-                sa[0] = (short)pixel;
-                obj = sa;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int ia[];
-                if (obj == null) {
-                    ia = new int[1];
-                } else {
-                    ia = (int[])obj;
-                }
-                ia[0] = pixel;
-                obj = ia;
-                break;
-
-            default:
-                // awt.214=This Color Model doesn't support this transferType
-                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-        }
-
-        return obj;
-    }
-
-    @Override
-    public Object getDataElements(int rgb, Object pixel) {
-        if (equals(ColorModel.getRGBdefault())) {
-            int ia[];
-            if (pixel == null) {
-                ia = new int[1];
-            } else {
-                ia = (int[])pixel;
-            }
-            ia[0] = rgb;
-            return ia;
-        }
-
-        int alpha = (rgb >> 24) & 0xff;
-        int red = (rgb >> 16) & 0xff;
-        int green = (rgb >> 8) & 0xff;
-        int blue = rgb & 0xff;
-
-        float comp[] = new float[numColorComponents];
-        float normComp[] = null;
-
-        if (is_sRGB || is_LINEAR_RGB) {
-            if (is_LINEAR_RGB) {
-                if (LINEAR_RGB_Length == 8) {
-                    red = to_LINEAR_8RGB_LUT[red] & 0xff;
-                    green = to_LINEAR_8RGB_LUT[green] & 0xff;
-                    blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
-                } else {
-                    red = to_LINEAR_16RGB_LUT[red] & 0xffff;
-                    green = to_LINEAR_16RGB_LUT[green] & 0xffff;
-                    blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
-                }
-            }
-            comp[0] = red / fFactor;
-            comp[1] = green / fFactor;
-            comp[2] = blue / fFactor;
-            if (!hasAlpha) {
-                normComp = comp;
-            } else {
-                float normAlpha = alpha / 255.0f;
-                normComp = new float[numComponents];
-                for (int i = 0; i < numColorComponents; i++) {
-                    normComp[i] = comp[i];
-                }
-                normComp[numColorComponents] = normAlpha;
-            }
-        } else {
-            comp[0] = red / fFactor;
-            comp[1] = green / fFactor;
-            comp[2] = blue / fFactor;
-            float rgbComp[] = cs.fromRGB(comp);
-            if (!hasAlpha) {
-                normComp = rgbComp;
-            } else {
-                float normAlpha = alpha / 255.0f;
-                normComp = new float[numComponents];
-                for (int i = 0; i < numColorComponents; i++) {
-                    normComp[i] = rgbComp[i];
-                }
-                normComp[numColorComponents] = normAlpha;
-            }
-        }
-
-        int pxl = 0;
-        if (hasAlpha) {
-            float normAlpha = normComp[numColorComponents];
-            alpha = (int)(normAlpha * maxValues[numColorComponents] + 0.5f);
-            if (isAlphaPremultiplied) {
-                red = (int)(normComp[0] * normAlpha * maxValues[0] + 0.5f);
-                green = (int)(normComp[1] * normAlpha * maxValues[1] + 0.5f);
-                blue = (int)(normComp[2] * normAlpha * maxValues[2] + 0.5f);
-            } else {
-                red = (int)(normComp[0] * maxValues[0] + 0.5f);
-                green = (int)(normComp[1] * maxValues[1] + 0.5f);
-                blue = (int)(normComp[2] * maxValues[2] + 0.5f);
-            }
-            pxl = (alpha << offsets[3]) & componentMasks[3];
-        } else {
-            red = (int)(normComp[0] * maxValues[0] + 0.5f);
-            green = (int)(normComp[1] * maxValues[1] + 0.5f);
-            blue = (int)(normComp[2] * maxValues[2] + 0.5f);
-        }
-
-        pxl |= ((red << offsets[0]) & componentMasks[0])
-                | ((green << offsets[1]) & componentMasks[1])
-                | ((blue << offsets[2]) & componentMasks[2]);
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[];
-                if (pixel == null) {
-                    ba = new byte[1];
-                } else {
-                    ba = (byte[])pixel;
-                }
-                ba[0] = (byte)pxl;
-                return ba;
-
-            case DataBuffer.TYPE_USHORT:
-                short sa[];
-                if (pixel == null) {
-                    sa = new short[1];
-                } else {
-                    sa = (short[])pixel;
-                }
-                sa[0] = (short)pxl;
-                return sa;
-
-            case DataBuffer.TYPE_INT:
-                int ia[];
-                if (pixel == null) {
-                    ia = new int[1];
-                } else {
-                    ia = (int[])pixel;
-                }
-                ia[0] = pxl;
-                return ia;
-
-            default:
-                // awt.214=This Color Model doesn't support this transferType
-                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-        }
-    }
-
-    @Override
-    public final ColorModel coerceData(WritableRaster raster, boolean isAlphaPremultiplied) {
-
-        if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
-            return this;
-        }
-
-        int minX = raster.getMinX();
-        int minY = raster.getMinY();
-        int w = raster.getWidth();
-        int h = raster.getHeight();
-
-        int components[] = null;
-        int transparentComponents[] = new int[numComponents];
-
-        float alphaFactor = maxValues[numColorComponents];
-
-        if (isAlphaPremultiplied) {
-            switch (transferType) {
-                case DataBuffer.TYPE_BYTE:
-                case DataBuffer.TYPE_USHORT:
-                case DataBuffer.TYPE_INT:
-                    for (int i = 0; i < h; i++, minY++) {
-                        for (int j = 0, x = minX; j < w; j++, x++) {
-                            components = raster.getPixel(x, minY, components);
-                            if (components[numColorComponents] == 0) {
-                                raster.setPixel(x, minY, transparentComponents);
-                            } else {
-                                float alpha = components[numColorComponents] / alphaFactor;
-                                for (int n = 0; n < numColorComponents; n++) {
-                                    components[n] = (int)(alpha * components[n] + 0.5f);
-                                }
-                                raster.setPixel(x, minY, components);
-                            }
-                        }
-
-                    }
-                    break;
-
-                default:
-                    // awt.214=This Color Model doesn't support this
-                    // transferType
-                    throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-            }
-        } else {
-            switch (transferType) {
-                case DataBuffer.TYPE_BYTE:
-                case DataBuffer.TYPE_USHORT:
-                case DataBuffer.TYPE_INT:
-                    for (int i = 0; i < h; i++, minY++) {
-                        for (int j = 0, x = minX; j < w; j++, x++) {
-                            components = raster.getPixel(x, minY, components);
-                            if (components[numColorComponents] != 0) {
-                                float alpha = alphaFactor / components[numColorComponents];
-                                for (int n = 0; n < numColorComponents; n++) {
-                                    components[n] = (int)(alpha * components[n] + 0.5f);
-                                }
-                                raster.setPixel(x, minY, components);
-                            }
-                        }
-
-                    }
-                    break;
-
-                default:
-                    // awt.214=This Color Model doesn't support this
-                    // transferType
-                    throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-            }
-
-        }
-
-        return new DirectColorModel(cs, pixel_bits, componentMasks[0], componentMasks[1],
-                componentMasks[2], componentMasks[3], isAlphaPremultiplied, transferType);
-    }
-
-    @Override
-    public String toString() {
-        // The output format based on 1.5 release behaviour.
-        // It could be reveled such way:
-        // BufferedImage bi = new BufferedImage(1, 1,
-        // BufferedImage.TYPE_INT_ARGB);
-        // ColorModel cm = bi.getColorModel();
-        // System.out.println(cm.toString());
-        String str = "DirectColorModel:" + " rmask = " + //$NON-NLS-1$ //$NON-NLS-2$
-                Integer.toHexString(componentMasks[0]) + " gmask = " + //$NON-NLS-1$
-                Integer.toHexString(componentMasks[1]) + " bmask = " + //$NON-NLS-1$
-                Integer.toHexString(componentMasks[2]) + " amask = " + //$NON-NLS-1$
-                (!hasAlpha ? "0" : Integer.toHexString(componentMasks[3])); //$NON-NLS-1$
-
-        return str;
-    }
-
-    @Override
-    public final int[] getComponents(Object pixel, int components[], int offset) {
-
-        if (components == null) {
-            components = new int[numComponents + offset];
-        }
-
-        int intPixel = 0;
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])pixel;
-                intPixel = ba[0] & 0xff;
-                break;
-
-            case DataBuffer.TYPE_USHORT:
-                short sa[] = (short[])pixel;
-                intPixel = sa[0] & 0xffff;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int ia[] = (int[])pixel;
-                intPixel = ia[0];
-                break;
-
-            default:
-                // awt.22D=This transferType ( {0} ) is not supported by this
-                // color model
-                throw new UnsupportedOperationException(Messages.getString("awt.22D", //$NON-NLS-1$
-                        transferType));
-        }
-
-        return getComponents(intPixel, components, offset);
-    }
-
-    @Override
-    public int getRed(Object inData) {
-        int pixel = 0;
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])inData;
-                pixel = ba[0] & 0xff;
-                break;
-
-            case DataBuffer.TYPE_USHORT:
-                short sa[] = (short[])inData;
-                pixel = sa[0] & 0xffff;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int ia[] = (int[])inData;
-                pixel = ia[0];
-                break;
-
-            default:
-                // awt.214=This Color Model doesn't support this transferType
-                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-        }
-        return getRed(pixel);
-    }
-
-    @Override
-    public int getRGB(Object inData) {
-        int pixel = 0;
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])inData;
-                pixel = ba[0] & 0xff;
-                break;
-
-            case DataBuffer.TYPE_USHORT:
-                short sa[] = (short[])inData;
-                pixel = sa[0] & 0xffff;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int ia[] = (int[])inData;
-                pixel = ia[0];
-                break;
-
-            default:
-                // awt.214=This Color Model doesn't support this transferType
-                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-        }
-        return getRGB(pixel);
-    }
-
-    @Override
-    public int getGreen(Object inData) {
-        int pixel = 0;
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])inData;
-                pixel = ba[0] & 0xff;
-                break;
-
-            case DataBuffer.TYPE_USHORT:
-                short sa[] = (short[])inData;
-                pixel = sa[0] & 0xffff;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int ia[] = (int[])inData;
-                pixel = ia[0];
-                break;
-
-            default:
-                // awt.214=This Color Model doesn't support this transferType
-                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-        }
-        return getGreen(pixel);
-    }
-
-    @Override
-    public int getBlue(Object inData) {
-        int pixel = 0;
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])inData;
-                pixel = ba[0] & 0xff;
-                break;
-
-            case DataBuffer.TYPE_USHORT:
-                short sa[] = (short[])inData;
-                pixel = sa[0] & 0xffff;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int ia[] = (int[])inData;
-                pixel = ia[0];
-                break;
-
-            default:
-                // awt.214=This Color Model doesn't support this transferType
-                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-        }
-        return getBlue(pixel);
-    }
-
-    @Override
-    public int getAlpha(Object inData) {
-        int pixel = 0;
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])inData;
-                pixel = ba[0] & 0xff;
-                break;
-
-            case DataBuffer.TYPE_USHORT:
-                short sa[] = (short[])inData;
-                pixel = sa[0] & 0xffff;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int ia[] = (int[])inData;
-                pixel = ia[0];
-                break;
-
-            default:
-                // awt.214=This Color Model doesn't support this transferType
-                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
-        }
-        return getAlpha(pixel);
-    }
-
-    @Override
-    public final WritableRaster createCompatibleWritableRaster(int w, int h) {
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new IllegalArgumentException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        int bandMasks[] = componentMasks.clone();
-
-        if (pixel_bits > 16) {
-            return Raster.createPackedRaster(DataBuffer.TYPE_INT, w, h, bandMasks, null);
-        } else if (pixel_bits > 8) {
-            return Raster.createPackedRaster(DataBuffer.TYPE_USHORT, w, h, bandMasks, null);
-        } else {
-            return Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h, bandMasks, null);
-        }
-    }
-
-    @Override
-    public boolean isCompatibleRaster(Raster raster) {
-        SampleModel sm = raster.getSampleModel();
-        if (!(sm instanceof SinglePixelPackedSampleModel)) {
-            return false;
-        }
-
-        SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel)sm;
-
-        if (sppsm.getNumBands() != numComponents) {
-            return false;
-        }
-        if (raster.getTransferType() != transferType) {
-            return false;
-        }
-
-        int maskBands[] = sppsm.getBitMasks();
-        return Arrays.equals(maskBands, componentMasks);
-    }
-
-    @Override
-    public int getDataElement(int components[], int offset) {
-        int pixel = 0;
-        for (int i = 0; i < numComponents; i++) {
-            pixel |= (components[offset + i] << offsets[i]) & componentMasks[i];
-        }
-        return pixel;
-    }
-
-    @Override
-    public final int[] getComponents(int pixel, int components[], int offset) {
-        if (components == null) {
-            components = new int[numComponents + offset];
-        }
-        for (int i = 0; i < numComponents; i++) {
-            components[offset + i] = (pixel & componentMasks[i]) >> offsets[i];
-        }
-        return components;
-    }
-
-    @Override
-    public final int getRed(int pixel) {
-        if (is_sRGB) {
-            return getComponentFrom_sRGB(pixel, 0);
-        }
-        if (is_LINEAR_RGB) {
-            return getComponentFrom_LINEAR_RGB(pixel, 0);
-        }
-        return getComponentFrom_RGB(pixel, 0);
-    }
-
-    @Override
-    public final int getRGB(int pixel) {
-        return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) | (getGreen(pixel) << 8)
-                | getBlue(pixel);
-    }
-
-    @Override
-    public final int getGreen(int pixel) {
-        if (is_sRGB) {
-            return getComponentFrom_sRGB(pixel, 1);
-        }
-        if (is_LINEAR_RGB) {
-            return getComponentFrom_LINEAR_RGB(pixel, 1);
-        }
-        return getComponentFrom_RGB(pixel, 1);
-    }
-
-    @Override
-    public final int getBlue(int pixel) {
-        if (is_sRGB) {
-            return getComponentFrom_sRGB(pixel, 2);
-        }
-        if (is_LINEAR_RGB) {
-            return getComponentFrom_LINEAR_RGB(pixel, 2);
-        }
-        return getComponentFrom_RGB(pixel, 2);
-    }
-
-    @Override
-    public final int getAlpha(int pixel) {
-        if (!hasAlpha) {
-            return 255;
-        }
-        int a = (pixel & componentMasks[3]) >>> offsets[3];
-        if (bits[3] == 8) {
-            return a;
-        }
-        return alphaLUT[a] & 0xff;
-    }
-
-    /**
-     * Gets the red mask.
-     * 
-     * @return the red mask.
-     */
-    public final int getRedMask() {
-        return componentMasks[0];
-    }
-
-    /**
-     * Gets the green mask.
-     * 
-     * @return the green mask.
-     */
-    public final int getGreenMask() {
-        return componentMasks[1];
-    }
-
-    /**
-     * Gets the blue mask.
-     * 
-     * @return the blue mask.
-     */
-    public final int getBlueMask() {
-        return componentMasks[2];
-    }
-
-    /**
-     * Gets the alpha mask.
-     * 
-     * @return the alpha mask.
-     */
-    public final int getAlphaMask() {
-        if (hasAlpha) {
-            return componentMasks[3];
-        }
-        return 0;
-    }
-
-    /**
-     * Initialization of Lookup tables.
-     */
-    private void initLUTs() {
-        is_sRGB = cs.isCS_sRGB();
-        is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
-
-        if (is_LINEAR_RGB) {
-            if (maxBitLength > 8) {
-                LINEAR_RGB_Length = 16;
-                from_LINEAR_RGB_LUT = LUTColorConverter.getFrom16lRGBtosRGB_LUT();
-                to_LINEAR_16RGB_LUT = LUTColorConverter.getFromsRGBto16lRGB_LUT();
-            } else {
-                LINEAR_RGB_Length = 8;
-                from_LINEAR_RGB_LUT = LUTColorConverter.getFrom8lRGBtosRGB_LUT();
-                to_LINEAR_8RGB_LUT = LUTColorConverter.getFromsRGBto8lRGB_LUT();
-            }
-            fFactor = ((1 << LINEAR_RGB_Length) - 1);
-        } else {
-            fFactor = 255.0f;
-        }
-
-        if (hasAlpha && bits[3] != 8) {
-            alphaLUT = new byte[maxValues[3] + 1];
-            for (int i = 0; i <= maxValues[3]; i++) {
-                alphaLUT[i] = (byte)(scales[3] * i + 0.5f);
-            }
-
-        }
-
-        if (!isAlphaPremultiplied) {
-            colorLUTs = new byte[3][];
-
-            if (is_sRGB) {
-                for (int i = 0; i < numColorComponents; i++) {
-                    if (bits[i] != 8) {
-                        for (int j = 0; j < i; j++) {
-                            if (bits[i] == bits[j]) {
-                                colorLUTs[i] = colorLUTs[j];
-                                break;
-                            }
-                        }
-                        colorLUTs[i] = new byte[maxValues[i] + 1];
-                        for (int j = 0; j <= maxValues[i]; j++) {
-                            colorLUTs[i][j] = (byte)(scales[i] * j + 0.5f);
-                        }
-                    }
-                }
-            }
-
-            if (is_LINEAR_RGB) {
-                for (int i = 0; i < numColorComponents; i++) {
-                    if (bits[i] != LINEAR_RGB_Length) {
-                        for (int j = 0; j < i; j++) {
-                            if (bits[i] == bits[j]) {
-                                colorLUTs[i] = colorLUTs[j];
-                                break;
-                            }
-                        }
-                        colorLUTs[i] = new byte[maxValues[i] + 1];
-                        for (int j = 0; j <= maxValues[0]; j++) {
-                            int idx;
-                            if (LINEAR_RGB_Length == 8) {
-                                idx = (int)(scales[i] * j + 0.5f);
-                            } else {
-                                idx = (int)(scales[i] * j * 257.0f + 0.5f);
-                            }
-                            colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
-                        }
-                    }
-                }
-            }
-
-        }
-    }
-
-    /**
-     * This method return RGB component value if Color Model has sRGB
-     * ColorSpace.
-     * 
-     * @param pixel
-     *            the integer representation of the pixel.
-     * @param idx
-     *            the index of the pixel component.
-     * @return the value of the pixel component scaled from 0 to 255.
-     */
-    private int getComponentFrom_sRGB(int pixel, int idx) {
-        int comp = (pixel & componentMasks[idx]) >> offsets[idx];
-        if (isAlphaPremultiplied) {
-            int alpha = (pixel & componentMasks[3]) >>> offsets[3];
-            comp = alpha == 0 ? 0 : (int)(scales[idx] * comp * 255.0f / (scales[3] * alpha) + 0.5f);
-        } else if (bits[idx] != 8) {
-            comp = colorLUTs[idx][comp] & 0xff;
-        }
-        return comp;
-    }
-
-    /**
-     * This method return RGB component value if Color Model has Linear RGB
-     * ColorSpace.
-     * 
-     * @param pixel
-     *            the integer representation of the pixel.
-     * @param idx
-     *            the index of the pixel component.
-     * @return the value of the pixel component scaled from 0 to 255.
-     */
-    private int getComponentFrom_LINEAR_RGB(int pixel, int idx) {
-        int comp = (pixel & componentMasks[idx]) >> offsets[idx];
-        if (isAlphaPremultiplied) {
-            float factor = ((1 << LINEAR_RGB_Length) - 1);
-            int alpha = (pixel & componentMasks[3]) >> offsets[3];
-            comp = alpha == 0 ? 0 : (int)(scales[idx] * comp * factor / (scales[3] * alpha) + 0.5f);
-        } else if (bits[idx] != LINEAR_RGB_Length) {
-            comp = colorLUTs[idx][comp] & 0xff;
-        } else {
-            comp = from_LINEAR_RGB_LUT[comp] & 0xff;
-        }
-        return comp;
-    }
-
-    /**
-     * This method return RGB component value if Color Model has arbitrary RGB
-     * ColorSapce.
-     * 
-     * @param pixel
-     *            the integer representation of the pixel.
-     * @param idx
-     *            the index of the pixel component.
-     * @return the value of the pixel component scaled from 0 to 255.
-     */
-    private int getComponentFrom_RGB(int pixel, int idx) {
-        int components[] = getComponents(pixel, null, 0);
-        float[] normComponents = getNormalizedComponents(components, 0, null, 0);
-        float[] sRGBcomponents = cs.toRGB(normComponents);
-        return (int)(sRGBcomponents[idx] * 255.0f + 0.5f);
-    }
-
-}
diff --git a/awt/java/awt/image/FilteredImageSource.java b/awt/java/awt/image/FilteredImageSource.java
deleted file mode 100644
index ed8558d..0000000
--- a/awt/java/awt/image/FilteredImageSource.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.util.Hashtable;
-
-/**
- * The FilteredImageSource class is used for producing image data for a new
- * filtered version of the original image using the specified filter object.
- * 
- * @since Android 1.0
- */
-public class FilteredImageSource implements ImageProducer {
-
-    /**
-     * The source.
-     */
-    private final ImageProducer source;
-
-    /**
-     * The filter.
-     */
-    private final ImageFilter filter;
-
-    /**
-     * The cons table.
-     */
-    private final Hashtable<ImageConsumer, ImageConsumer> consTable = new Hashtable<ImageConsumer, ImageConsumer>();
-
-    /**
-     * Instantiates a new FilteredImageSource object with the specified
-     * ImageProducer and the ImageFilter objects.
-     * 
-     * @param orig
-     *            the specified ImageProducer.
-     * @param imgf
-     *            the specified ImageFilter.
-     */
-    public FilteredImageSource(ImageProducer orig, ImageFilter imgf) {
-        source = orig;
-        filter = imgf;
-    }
-
-    public synchronized boolean isConsumer(ImageConsumer ic) {
-        if (ic != null) {
-            return consTable.containsKey(ic);
-        }
-        return false;
-    }
-
-    public void startProduction(ImageConsumer ic) {
-        addConsumer(ic);
-        ImageConsumer fic = consTable.get(ic);
-        source.startProduction(fic);
-    }
-
-    public void requestTopDownLeftRightResend(ImageConsumer ic) {
-        if (ic != null && isConsumer(ic)) {
-            ImageFilter fic = (ImageFilter)consTable.get(ic);
-            fic.resendTopDownLeftRight(source);
-        }
-    }
-
-    public synchronized void removeConsumer(ImageConsumer ic) {
-        if (ic != null && isConsumer(ic)) {
-            ImageConsumer fic = consTable.get(ic);
-            source.removeConsumer(fic);
-            consTable.remove(ic);
-        }
-    }
-
-    public synchronized void addConsumer(ImageConsumer ic) {
-        if (ic != null && !isConsumer(ic)) {
-            ImageConsumer fic = filter.getFilterInstance(ic);
-            source.addConsumer(fic);
-            consTable.put(ic, fic);
-        }
-    }
-}
diff --git a/awt/java/awt/image/ImageConsumer.java b/awt/java/awt/image/ImageConsumer.java
deleted file mode 100644
index caf87d1..0000000
--- a/awt/java/awt/image/ImageConsumer.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.util.Hashtable;
-
-/**
- * The ImageConsumer interface provides the data about the image and about how
- * its data is delivered. A ImageProducer provides all of the information about
- * the image using the methods defined in this interface.
- * 
- * @since Android 1.0
- */
-public interface ImageConsumer {
-
-    /**
-     * The Constant RANDOMPIXELORDER indicates that the pixels are delivered in
-     * a random order.
-     */
-    public static final int RANDOMPIXELORDER = 1;
-
-    /**
-     * The Constant TOPDOWNLEFTRIGHT indicates that the pixels are delivered in
-     * top-down, left-to-right order.
-     */
-    public static final int TOPDOWNLEFTRIGHT = 2;
-
-    /**
-     * The Constant COMPLETESCANLINES indicates that the pixels are delivered in
-     * complete scanline.
-     */
-    public static final int COMPLETESCANLINES = 4;
-
-    /**
-     * The Constant SINGLEPASS indicates that pixels are delivered in a single
-     * pass.
-     */
-    public static final int SINGLEPASS = 8;
-
-    /**
-     * The Constant SINGLEFRAME indicates that image consists of single frame.
-     */
-    public static final int SINGLEFRAME = 16;
-
-    /**
-     * The Constant IMAGEERROR indicates an image error during image producing.
-     */
-    public static final int IMAGEERROR = 1;
-
-    /**
-     * The Constant SINGLEFRAMEDONE indicates that only one of the image's
-     * frames is completed.
-     */
-    public static final int SINGLEFRAMEDONE = 2;
-
-    /**
-     * The Constant STATICIMAGEDONE indicates that the image is completed.
-     */
-    public static final int STATICIMAGEDONE = 3;
-
-    /**
-     * The Constant IMAGEABORTED indicates that the image producing process is
-     * aborted.
-     */
-    public static final int IMAGEABORTED = 4;
-
-    /**
-     * Sets the properties for the image associated with this ImageConsumer.
-     * 
-     * @param props
-     *            the properties for the image associated with this
-     *            ImageConsumer.
-     */
-    public void setProperties(Hashtable<?, ?> props);
-
-    /**
-     * Sets the ColorModel object.
-     * 
-     * @param model
-     *            the new ColorModel.
-     */
-    public void setColorModel(ColorModel model);
-
-    /**
-     * Sets the pixels for the specified rectangular area of the image.
-     * 
-     * @param x
-     *            the X coordinate of rectangular area.
-     * @param y
-     *            the Y coordinate of rectangular area.
-     * @param w
-     *            the width of rectangular area.
-     * @param h
-     *            the height of rectangular area.
-     * @param model
-     *            the specified ColorModel to be used for pixels converting.
-     * @param pixels
-     *            the array of pixels.
-     * @param off
-     *            the offset of pixels array.
-     * @param scansize
-     *            the distance from the one row of pixels to the next row in the
-     *            specified array.
-     */
-    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
-            int scansize);
-
-    /**
-     * Sets the pixels for the specified rectangular area of the image.
-     * 
-     * @param x
-     *            the X coordinate of rectangular area.
-     * @param y
-     *            the Y coordinate of rectangular area.
-     * @param w
-     *            the width of rectangular area.
-     * @param h
-     *            the height of rectangular area.
-     * @param model
-     *            the specified ColorModel to be used for pixels converting.
-     * @param pixels
-     *            the array of pixels.
-     * @param off
-     *            the offset of pixels array.
-     * @param scansize
-     *            the distance from the one row of pixels to the next row in the
-     *            specified array.
-     */
-    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
-            int scansize);
-
-    /**
-     * Sets the dimensions of a source image.
-     * 
-     * @param width
-     *            the width of the image.
-     * @param height
-     *            the height of the image.
-     */
-    public void setDimensions(int width, int height);
-
-    /**
-     * Sets the hint flags of pixels order, which is used by the ImageConsumer
-     * for obtaining pixels from the ImageProducer for which this ImageConsumer
-     * is added.
-     * 
-     * @param hintflags
-     *            the mask of hint flags.
-     */
-    public void setHints(int hintflags);
-
-    /**
-     * THis method is called in the one of the following cases:
-     * <ul>
-     * <li>The ImageProducer (for which this ImageConsumer is added) has been
-     * delivered all pixels of the source image.</li>
-     * <li>A one frame of an animation has been completed.</li>
-     * <li>An error while loading or producing of the image has occurred.
-     * </ul>
-     * 
-     * @param status
-     *            the status of image producing.
-     */
-    public void imageComplete(int status);
-
-}
diff --git a/awt/java/awt/image/ImageFilter.java b/awt/java/awt/image/ImageFilter.java
deleted file mode 100644
index d2c9f50..0000000
--- a/awt/java/awt/image/ImageFilter.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.util.Hashtable;
-
-/**
- * The ImageFilter class provides a filter for delivering image data from an
- * ImageProducer to an ImageConsumer.
- * 
- * @since Android 1.0
- */
-public class ImageFilter implements ImageConsumer, Cloneable {
-
-    /**
-     * The consumer.
-     */
-    protected ImageConsumer consumer;
-
-    /**
-     * Instantiates a new ImageFilter.
-     */
-    public ImageFilter() {
-        super();
-    }
-
-    /**
-     * Gets an instance of an ImageFilter object which performs the filtering
-     * for the specified ImageConsumer.
-     * 
-     * @param ic
-     *            the specified ImageConsumer.
-     * @return an ImageFilter used to perform the filtering for the specified
-     *         ImageConsumer.
-     */
-    public ImageFilter getFilterInstance(ImageConsumer ic) {
-        ImageFilter filter = (ImageFilter)clone();
-        filter.consumer = ic;
-        return filter;
-    }
-
-    @SuppressWarnings("unchecked")
-    public void setProperties(Hashtable<?, ?> props) {
-        Hashtable<Object, Object> fprops;
-        if (props == null) {
-            fprops = new Hashtable<Object, Object>();
-        } else {
-            fprops = (Hashtable<Object, Object>)props.clone();
-        }
-        String propName = "Filters"; //$NON-NLS-1$
-        String prop = "Null filter"; //$NON-NLS-1$
-        Object o = fprops.get(propName);
-        if (o != null) {
-            if (o instanceof String) {
-                prop = (String)o + "; " + prop; //$NON-NLS-1$
-            } else {
-                prop = o.toString() + "; " + prop; //$NON-NLS-1$
-            }
-        }
-        fprops.put(propName, prop);
-        consumer.setProperties(fprops);
-    }
-
-    /**
-     * Returns a copy of this ImageFilter.
-     * 
-     * @return a copy of this ImageFilter.
-     */
-    @Override
-    public Object clone() {
-        try {
-            return super.clone();
-        } catch (CloneNotSupportedException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Responds to a request for a Top-Down-Left-Right ordered resend of the
-     * pixel data from an ImageConsumer.
-     * 
-     * @param ip
-     *            the ImageProducer that provides this instance of the filter.
-     */
-    public void resendTopDownLeftRight(ImageProducer ip) {
-        ip.requestTopDownLeftRightResend(this);
-    }
-
-    public void setColorModel(ColorModel model) {
-        consumer.setColorModel(model);
-    }
-
-    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
-            int scansize) {
-        consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
-    }
-
-    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
-            int scansize) {
-        consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
-    }
-
-    public void setDimensions(int width, int height) {
-        consumer.setDimensions(width, height);
-    }
-
-    public void setHints(int hints) {
-        consumer.setHints(hints);
-    }
-
-    public void imageComplete(int status) {
-        consumer.imageComplete(status);
-    }
-
-}
diff --git a/awt/java/awt/image/ImageObserver.java b/awt/java/awt/image/ImageObserver.java
deleted file mode 100644
index 21ec41b..0000000
--- a/awt/java/awt/image/ImageObserver.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.Image;
-
-/**
- * the ImageObserver interface is an asynchronous update interface for receiving
- * notifications about Image construction status.
- * 
- * @since Android 1.0
- */
-public interface ImageObserver {
-
-    /**
-     * The Constant WIDTH indicates that the width of the image is available.
-     */
-    public static final int WIDTH = 1;
-
-    /**
-     * The Constant HEIGHT indicates that the width of the image is available.
-     */
-    public static final int HEIGHT = 2;
-
-    /**
-     * The Constant PROPERTIES indicates that the properties of the image are
-     * available.
-     */
-    public static final int PROPERTIES = 4;
-
-    /**
-     * The Constant SOMEBITS indicates that more bits needed for drawing a
-     * scaled variation of the image pixels are available.
-     */
-    public static final int SOMEBITS = 8;
-
-    /**
-     * The Constant FRAMEBITS indicates that complete frame of a image which was
-     * previously drawn is now available for drawing again.
-     */
-    public static final int FRAMEBITS = 16;
-
-    /**
-     * The Constant ALLBITS indicates that an image which was previously drawn
-     * is now complete and can be drawn again.
-     */
-    public static final int ALLBITS = 32;
-
-    /**
-     * The Constant ERROR indicates that error occurred.
-     */
-    public static final int ERROR = 64;
-
-    /**
-     * The Constant ABORT indicates that the image producing is aborted.
-     */
-    public static final int ABORT = 128;
-
-    /**
-     * This method is called when information about an Image interface becomes
-     * available. This method returns true if further updates are needed, false
-     * if not.
-     * 
-     * @param img
-     *            the image to be observed.
-     * @param infoflags
-     *            the bitwise OR combination of information flags: ABORT,
-     *            ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS,
-     *            WIDTH.
-     * @param x
-     *            the X coordinate.
-     * @param y
-     *            the Y coordinate.
-     * @param width
-     *            the width.
-     * @param height
-     *            the height.
-     * @return true if further updates are needed, false if not.
-     */
-    public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height);
-
-}
diff --git a/awt/java/awt/image/ImageProducer.java b/awt/java/awt/image/ImageProducer.java
deleted file mode 100644
index 9138be2..0000000
--- a/awt/java/awt/image/ImageProducer.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-/**
- * The ImageProducer provides an interface for objects which produce the image
- * data. ImageProducer is used for reconstructing the image. Each image contains
- * an ImageProducer.
- * 
- * @since Android 1.0
- */
-public interface ImageProducer {
-
-    /**
-     * Checks if the specified ImageConsumer is registered with this
-     * ImageProvider or not.
-     * 
-     * @param ic
-     *            the ImageConsumer to be checked.
-     * @return true, if the specified ImageConsumer is registered with this
-     *         ImageProvider, false otherwise.
-     */
-    public boolean isConsumer(ImageConsumer ic);
-
-    /**
-     * Starts a reconstruction of the image data which will be delivered to this
-     * consumer. This method adds the specified ImageConsumer before
-     * reconstructing the image.
-     * 
-     * @param ic
-     *            the specified ImageConsumer.
-     */
-    public void startProduction(ImageConsumer ic);
-
-    /**
-     * Requests the ImageProducer to resend the image data in
-     * ImageConsumer.TOPDOWNLEFTRIGHT order.
-     * 
-     * @param ic
-     *            the specified ImageConsumer.
-     */
-    public void requestTopDownLeftRightResend(ImageConsumer ic);
-
-    /**
-     * Deregisters the specified ImageConsumer.
-     * 
-     * @param ic
-     *            the specified ImageConsumer.
-     */
-    public void removeConsumer(ImageConsumer ic);
-
-    /**
-     * Adds the specified ImageConsumer object to this ImageProducer.
-     * 
-     * @param ic
-     *            the specified ImageConsumer.
-     */
-    public void addConsumer(ImageConsumer ic);
-
-}
diff --git a/awt/java/awt/image/ImagingOpException.java b/awt/java/awt/image/ImagingOpException.java
deleted file mode 100644
index e0c0127..0000000
--- a/awt/java/awt/image/ImagingOpException.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Oct 5, 2005
- */
-
-package java.awt.image;
-
-/**
- * The ImagingOpException class provides error notification when the
- * BufferedImageOp or RasterOp filter methods can not perform the desired filter
- * operation.
- * 
- * @since Android 1.0
- */
-public class ImagingOpException extends RuntimeException {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 8026288481846276658L;
-
-    /**
-     * Instantiates a new ImagingOpException with a detail message.
-     * 
-     * @param s
-     *            the detail message.
-     */
-    public ImagingOpException(String s) {
-        super(s);
-    }
-}
diff --git a/awt/java/awt/image/IndexColorModel.java b/awt/java/awt/image/IndexColorModel.java
deleted file mode 100644
index 0b06acd..0000000
--- a/awt/java/awt/image/IndexColorModel.java
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
-import java.math.BigInteger;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class IndexColorModel represents a color model in which the color values
- * of the pixels are read from a palette.
- * 
- * @since Android 1.0
- */
-public class IndexColorModel extends ColorModel {
-
-    /**
-     * The color map.
-     */
-    private int colorMap[]; // Color Map
-
-    /**
-     * The map size.
-     */
-    private int mapSize; // Color Map size
-
-    /**
-     * The transparent index.
-     */
-    private int transparentIndex; // Index of fully transparent pixel
-
-    /**
-     * The gray palette.
-     */
-    private boolean grayPalette; // Color Model has Color Map with Gray Pallete
-
-    /**
-     * The valid bits.
-     */
-    private BigInteger validBits; // Specify valid Color Map values
-
-    /**
-     * The Constant CACHESIZE.
-     */
-    private static final int CACHESIZE = 20; // Cache size. Cache used for
-
-    // improving performace of selection
-    // nearest color in Color Map
-
-    /**
-     * The cachetable.
-     */
-    private final int cachetable[] = new int[CACHESIZE * 2]; // Cache table -
-
-    // used for
-
-    // storing RGB values and that appropriate indices
-    // in the Color Map
-
-    /**
-     * The next insert idx.
-     */
-    private int nextInsertIdx = 0; // Next index for insertion into Cache table
-
-    /**
-     * The total inserted.
-     */
-    private int totalInserted = 0; // Number of inserted values into Cache table
-
-    /**
-     * Instantiates a new index color model.
-     * 
-     * @param bits
-     *            the array of component masks.
-     * @param size
-     *            the size of the color map.
-     * @param cmap
-     *            the array that gives the color mapping.
-     * @param start
-     *            the start index of the color mapping data within the cmap
-     *            array.
-     * @param transferType
-     *            the transfer type (primitive java type to use for the
-     *            components).
-     * @param validBits
-     *            a list of which bits represent valid colormap values, or null
-     *            if all are valid.
-     * @throws IllegalArgumentException
-     *             if the size of the color map is less than one.
-     */
-    public IndexColorModel(int bits, int size, int cmap[], int start, int transferType,
-            BigInteger validBits) {
-
-        super(bits, IndexColorModel.createBits(true), ColorSpace.getInstance(ColorSpace.CS_sRGB),
-                true, false, Transparency.OPAQUE, validateTransferType(transferType));
-
-        if (size < 1) {
-            // awt.264=Size of the color map is less than 1
-            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
-        }
-
-        mapSize = size;
-        colorMap = new int[mapSize];
-        transparentIndex = -1;
-
-        if (validBits != null) {
-            for (int i = 0; i < mapSize; i++) {
-                if (!validBits.testBit(i)) {
-                    this.validBits = validBits;
-                }
-                break;
-            }
-        }
-
-        transparency = Transparency.OPAQUE;
-        int alphaMask = 0xff000000;
-        int alpha = 0;
-
-        for (int i = 0; i < mapSize; i++, start++) {
-            colorMap[i] = cmap[start];
-            alpha = cmap[start] & alphaMask;
-
-            if (alpha == alphaMask) {
-                continue;
-            }
-            if (alpha == 0) {
-                if (transparentIndex < 0) {
-                    transparentIndex = i;
-                }
-                if (transparency == Transparency.OPAQUE) {
-                    transparency = Transparency.BITMASK;
-                }
-            } else if (alpha != alphaMask && transparency != Transparency.TRANSLUCENT) {
-                transparency = Transparency.TRANSLUCENT;
-            }
-
-        }
-        checkPalette();
-
-    }
-
-    /**
-     * Instantiates a new index color model.
-     * 
-     * @param bits
-     *            the array of component masks.
-     * @param size
-     *            the size of the color map.
-     * @param cmap
-     *            the array that gives the color mapping.
-     * @param start
-     *            the start index of the color mapping data within the cmap
-     *            array.
-     * @param hasalpha
-     *            whether this color model uses alpha.
-     * @param trans
-     *            the transparency supported, @see java.awt.Transparency.
-     * @param transferType
-     *            the transfer type (primitive java type to use for the
-     *            components).
-     * @throws IllegalArgumentException
-     *             if the size of the color map is less than one.
-     */
-    public IndexColorModel(int bits, int size, int cmap[], int start, boolean hasalpha, int trans,
-            int transferType) {
-
-        super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)), ColorSpace
-                .getInstance(ColorSpace.CS_sRGB), (hasalpha || (trans >= 0)), false,
-                Transparency.OPAQUE, validateTransferType(transferType));
-
-        if (size < 1) {
-            // awt.264=Size of the color map is less than 1
-            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
-        }
-
-        mapSize = size;
-        colorMap = new int[mapSize];
-        if (trans >= 0 && trans < mapSize) {
-            transparentIndex = trans;
-            transparency = Transparency.BITMASK;
-        } else {
-            transparentIndex = -1;
-            transparency = Transparency.OPAQUE;
-        }
-
-        int alphaMask = 0xff000000;
-        int alpha = 0;
-
-        for (int i = 0; i < mapSize; i++, start++) {
-            if (transparentIndex == i) {
-                colorMap[i] = cmap[start] & 0x00ffffff;
-                continue;
-            }
-            if (hasalpha) {
-                alpha = cmap[start] & alphaMask;
-                colorMap[i] = cmap[start];
-
-                if (alpha == alphaMask) {
-                    continue;
-                }
-                if (alpha == 0) {
-                    if (trans < 0) {
-                        trans = i;
-                    }
-                    if (transparency == Transparency.OPAQUE) {
-                        transparency = Transparency.BITMASK;
-                    }
-                } else if (alpha != 0 && transparency != Transparency.TRANSLUCENT) {
-                    transparency = Transparency.TRANSLUCENT;
-                }
-            } else {
-                colorMap[i] = alphaMask | cmap[start];
-            }
-        }
-        checkPalette();
-
-    }
-
-    /**
-     * Instantiates a new index color model by building the color map from
-     * arrays of red, green, blue, and alpha values.
-     * 
-     * @param bits
-     *            the array of component masks.
-     * @param size
-     *            the size of the color map.
-     * @param r
-     *            the array giving the red components of the entries in the
-     *            color map.
-     * @param g
-     *            the array giving the green components of the entries in the
-     *            color map.
-     * @param b
-     *            the array giving the blue components of the entries in the
-     *            color map.
-     * @param a
-     *            the array giving the alpha components of the entries in the
-     *            color map.
-     * @throws IllegalArgumentException
-     *             if the size of the color map is less than one.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if the size of one of the component arrays is less than the
-     *             size of the color map.
-     */
-    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[], byte a[]) {
-
-        super(bits, IndexColorModel.createBits(true), ColorSpace.getInstance(ColorSpace.CS_sRGB),
-                true, false, Transparency.OPAQUE, validateTransferType(ColorModel
-                        .getTransferType(bits)));
-
-        createColorMap(size, r, g, b, a, -1);
-        checkPalette();
-    }
-
-    /**
-     * Instantiates a new index color model by building the color map from
-     * arrays of red, green, and blue values.
-     * 
-     * @param bits
-     *            the array of component masks.
-     * @param size
-     *            the size of the color map.
-     * @param r
-     *            the array giving the red components of the entries in the
-     *            color map.
-     * @param g
-     *            the array giving the green components of the entries in the
-     *            color map.
-     * @param b
-     *            the array giving the blue components of the entries in the
-     *            color map.
-     * @param trans
-     *            the transparency supported, @see java.awt.Transparency.
-     * @throws IllegalArgumentException
-     *             if the size of the color map is less than one.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if the size of one of the component arrays is less than the
-     *             size of the color map.
-     */
-    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[], int trans) {
-
-        super(bits, IndexColorModel.createBits((trans >= 0)), ColorSpace
-                .getInstance(ColorSpace.CS_sRGB), (trans >= 0), false, Transparency.OPAQUE,
-                validateTransferType(ColorModel.getTransferType(bits)));
-
-        createColorMap(size, r, g, b, null, trans);
-        checkPalette();
-    }
-
-    /**
-     * Instantiates a new index color model by building the color map from
-     * arrays of red, green, and blue values.
-     * 
-     * @param bits
-     *            the array of component masks.
-     * @param size
-     *            the size of the color map.
-     * @param r
-     *            the array giving the red components of the entries in the
-     *            color map.
-     * @param g
-     *            the array giving the green components of the entries in the
-     *            color map.
-     * @param b
-     *            the array giving the blue components of the entries in the
-     *            color map.
-     * @throws IllegalArgumentException
-     *             if the size of the color map is less than one.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if the size of one of the component arrays is less than the
-     *             size of the color map.
-     */
-    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[]) {
-        super(bits, IndexColorModel.createBits(false), ColorSpace.getInstance(ColorSpace.CS_sRGB),
-                false, false, Transparency.OPAQUE, validateTransferType(ColorModel
-                        .getTransferType(bits)));
-
-        createColorMap(size, r, g, b, null, -1);
-        checkPalette();
-    }
-
-    /**
-     * Instantiates a new index color model.
-     * 
-     * @param bits
-     *            the array of component masks.
-     * @param size
-     *            the size of the color map.
-     * @param cmap
-     *            the array that gives the color mapping.
-     * @param start
-     *            the start index of the color mapping data within the cmap
-     *            array.
-     * @param hasalpha
-     *            whether this color model uses alpha.
-     * @param trans
-     *            the transparency supported, @see java.awt.Transparency.
-     * @throws IllegalArgumentException
-     *             if the size of the color map is less than one.
-     */
-    public IndexColorModel(int bits, int size, byte cmap[], int start, boolean hasalpha, int trans) {
-
-        super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)), ColorSpace
-                .getInstance(ColorSpace.CS_sRGB), (hasalpha || (trans >= 0)), false,
-                Transparency.OPAQUE, validateTransferType(ColorModel.getTransferType(bits)));
-
-        if (size < 1) {
-            // awt.264=Size of the color map is less than 1
-            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
-        }
-
-        mapSize = size;
-        colorMap = new int[mapSize];
-        transparentIndex = -1;
-
-        transparency = Transparency.OPAQUE;
-        int alpha = 0xff000000;
-
-        for (int i = 0; i < mapSize; i++) {
-            colorMap[i] = (cmap[start++] & 0xff) << 16 | (cmap[start++] & 0xff) << 8
-                    | (cmap[start++] & 0xff);
-            if (trans == i) {
-                if (transparency == Transparency.OPAQUE) {
-                    transparency = Transparency.BITMASK;
-                }
-                if (hasalpha) {
-                    start++;
-                }
-                continue;
-            }
-            if (hasalpha) {
-                alpha = cmap[start++] & 0xff;
-                if (alpha == 0) {
-                    if (transparency == Transparency.OPAQUE) {
-                        transparency = Transparency.BITMASK;
-                        if (trans < 0) {
-                            trans = i;
-                        }
-                    }
-                } else {
-                    if (alpha != 0xff && transparency != Transparency.TRANSLUCENT) {
-                        transparency = Transparency.TRANSLUCENT;
-                    }
-                }
-                alpha <<= 24;
-            }
-            colorMap[i] |= alpha;
-        }
-
-        if (trans >= 0 && trans < mapSize) {
-            transparentIndex = trans;
-        }
-        checkPalette();
-
-    }
-
-    /**
-     * Instantiates a new index color model.
-     * 
-     * @param bits
-     *            the array of component masks.
-     * @param size
-     *            the size of the color map.
-     * @param cmap
-     *            the array that gives the color mapping.
-     * @param start
-     *            the start index of the color mapping data within the cmap
-     *            array.
-     * @param hasalpha
-     *            whether this color model uses alpha.
-     * @throws IllegalArgumentException
-     *             if the size of the color map is less than one.
-     */
-    public IndexColorModel(int bits, int size, byte cmap[], int start, boolean hasalpha) {
-
-        this(bits, size, cmap, start, hasalpha, -1);
-    }
-
-    @Override
-    public Object getDataElements(int[] components, int offset, Object pixel) {
-        int rgb = (components[offset] << 16) | (components[offset + 1]) << 8
-                | components[offset + 2];
-        if (hasAlpha) {
-            rgb |= components[offset + 3] << 24;
-        } else {
-            rgb |= 0xff000000;
-        }
-        return getDataElements(rgb, pixel);
-    }
-
-    @Override
-    public synchronized Object getDataElements(int rgb, Object pixel) {
-        int red = (rgb >> 16) & 0xff;
-        int green = (rgb >> 8) & 0xff;
-        int blue = rgb & 0xff;
-        int alpha = rgb >>> 24;
-        int pixIdx = 0;
-
-        for (int i = 0; i < totalInserted; i++) {
-            int idx = i * 2;
-            if (rgb == cachetable[idx]) {
-                return createDataObject(cachetable[idx + 1], pixel);
-            }
-        }
-
-        if (!hasAlpha && grayPalette) {
-            int grey = (red * 77 + green * 150 + blue * 29 + 128) >>> 8;
-            int minError = 255;
-            int error = 0;
-
-            for (int i = 0; i < mapSize; i++) {
-                error = Math.abs((colorMap[i] & 0xff) - grey);
-                if (error < minError) {
-                    pixIdx = i;
-                    if (error == 0) {
-                        break;
-                    }
-                    minError = error;
-                }
-            }
-        } else if (alpha == 0 && transparentIndex > -1) {
-            pixIdx = transparentIndex;
-        } else {
-            int minAlphaError = 255;
-            int minError = 195075; // 255^2 + 255^2 + 255^2
-            int alphaError;
-            int error = 0;
-
-            for (int i = 0; i < mapSize; i++) {
-                int pix = colorMap[i];
-                if (rgb == pix) {
-                    pixIdx = i;
-                    break;
-                }
-                alphaError = Math.abs(alpha - (pix >>> 24));
-                if (alphaError <= minAlphaError) {
-                    minAlphaError = alphaError;
-
-                    int buf = ((pix >> 16) & 0xff) - red;
-                    error = buf * buf;
-
-                    if (error < minError) {
-                        buf = ((pix >> 8) & 0xff) - green;
-                        error += buf * buf;
-
-                        if (error < minError) {
-                            buf = (pix & 0xff) - blue;
-                            error += buf * buf;
-
-                            if (error < minError) {
-                                pixIdx = i;
-                                minError = error;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        cachetable[nextInsertIdx] = rgb;
-        cachetable[nextInsertIdx + 1] = pixIdx;
-
-        nextInsertIdx = (nextInsertIdx + 2) % (CACHESIZE * 2);
-        if (totalInserted < CACHESIZE) {
-            totalInserted++;
-        }
-
-        return createDataObject(pixIdx, pixel);
-    }
-
-    /**
-     * Converts an image from indexed to RGB format.
-     * 
-     * @param raster
-     *            the raster containing the source image.
-     * @param forceARGB
-     *            whether to use the default RGB color model.
-     * @return the buffered image.
-     * @throws IllegalArgumentException
-     *             if the raster is not compatible with this color model.
-     */
-    public BufferedImage convertToIntDiscrete(Raster raster, boolean forceARGB) {
-
-        if (!isCompatibleRaster(raster)) {
-            // awt.265=The raster argument is not compatible with this
-            // IndexColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.265")); //$NON-NLS-1$
-        }
-
-        ColorModel model;
-        if (forceARGB || transparency == Transparency.TRANSLUCENT) {
-            model = ColorModel.getRGBdefault();
-        } else if (transparency == Transparency.BITMASK) {
-            model = new DirectColorModel(25, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x01000000);
-        } else {
-            model = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
-        }
-
-        int w = raster.getWidth();
-        int h = raster.getHeight();
-
-        WritableRaster distRaster = model.createCompatibleWritableRaster(w, h);
-
-        int minX = raster.getMinX();
-        int minY = raster.getMinY();
-
-        Object obj = null;
-        int pixels[] = null;
-
-        for (int i = 0; i < h; i++, minY++) {
-            obj = raster.getDataElements(minX, minY, w, 1, obj);
-            if (obj instanceof byte[]) {
-                byte ba[] = (byte[])obj;
-                if (pixels == null) {
-                    pixels = new int[ba.length];
-                }
-                for (int j = 0; j < ba.length; j++) {
-                    pixels[j] = colorMap[ba[j] & 0xff];
-                }
-            } else if (obj instanceof short[]) {
-                short sa[] = (short[])obj;
-                if (pixels == null) {
-                    pixels = new int[sa.length];
-                }
-                for (int j = 0; j < sa.length; j++) {
-                    pixels[j] = colorMap[sa[j] & 0xffff];
-                }
-            }
-            if (obj instanceof int[]) {
-                int ia[] = (int[])obj;
-                if (pixels == null) {
-                    pixels = new int[ia.length];
-                }
-                for (int j = 0; j < ia.length; j++) {
-                    pixels[j] = colorMap[ia[j]];
-                }
-            }
-
-            distRaster.setDataElements(0, i, w, 1, pixels);
-        }
-
-        return new BufferedImage(model, distRaster, false, null);
-    }
-
-    /**
-     * Gets the valid pixels.
-     * 
-     * @return the valid pixels.
-     */
-    public BigInteger getValidPixels() {
-        return validBits;
-    }
-
-    @Override
-    public String toString() {
-        // The output format based on 1.5 release behaviour.
-        // It could be reveled such way:
-        // BufferedImage bi = new BufferedImage(1, 1,
-        // BufferedImage.TYPE_BYTE_INDEXED);
-        // ColorModel cm = bi.getColorModel();
-        // System.out.println(cm.toString());
-        String str = "IndexColorModel: #pixel_bits = " + pixel_bits + //$NON-NLS-1$
-                " numComponents = " + numComponents + " color space = " + cs + //$NON-NLS-1$ //$NON-NLS-2$
-                " transparency = "; //$NON-NLS-1$
-
-        if (transparency == Transparency.OPAQUE) {
-            str = str + "Transparency.OPAQUE"; //$NON-NLS-1$
-        } else if (transparency == Transparency.BITMASK) {
-            str = str + "Transparency.BITMASK"; //$NON-NLS-1$
-        } else {
-            str = str + "Transparency.TRANSLUCENT"; //$NON-NLS-1$
-        }
-
-        str = str + " transIndex = " + transparentIndex + " has alpha = " + //$NON-NLS-1$ //$NON-NLS-2$
-                hasAlpha + " isAlphaPre = " + isAlphaPremultiplied; //$NON-NLS-1$
-
-        return str;
-    }
-
-    @Override
-    public int[] getComponents(Object pixel, int components[], int offset) {
-        int pixIdx = -1;
-        if (pixel instanceof byte[]) {
-            byte ba[] = (byte[])pixel;
-            pixIdx = ba[0] & 0xff;
-        } else if (pixel instanceof short[]) {
-            short sa[] = (short[])pixel;
-            pixIdx = sa[0] & 0xffff;
-        } else if (pixel instanceof int[]) {
-            int ia[] = (int[])pixel;
-            pixIdx = ia[0];
-        } else {
-            // awt.219=This transferType is not supported by this color model
-            throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
-        }
-
-        return getComponents(pixIdx, components, offset);
-    }
-
-    @Override
-    public WritableRaster createCompatibleWritableRaster(int w, int h) {
-        WritableRaster raster;
-        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
-            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h, 1, pixel_bits, null);
-        } else if (pixel_bits <= 8) {
-            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h, 1, null);
-        } else if (pixel_bits <= 16) {
-            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT, w, h, 1, null);
-        } else {
-            // awt.266=The number of bits in a pixel is greater than 16
-            throw new UnsupportedOperationException(Messages.getString("awt.266")); //$NON-NLS-1$
-        }
-
-        return raster;
-    }
-
-    @Override
-    public boolean isCompatibleSampleModel(SampleModel sm) {
-        if (sm == null) {
-            return false;
-        }
-
-        if (!(sm instanceof MultiPixelPackedSampleModel) && !(sm instanceof ComponentSampleModel)) {
-            return false;
-        }
-
-        if (sm.getTransferType() != transferType) {
-            return false;
-        }
-        if (sm.getNumBands() != 1) {
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public SampleModel createCompatibleSampleModel(int w, int h) {
-        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
-            return new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, w, h, pixel_bits);
-        }
-        int bandOffsets[] = new int[1];
-        bandOffsets[0] = 0;
-        return new ComponentSampleModel(transferType, w, h, 1, w, bandOffsets);
-
-    }
-
-    @Override
-    public boolean isCompatibleRaster(Raster raster) {
-        int sampleSize = raster.getSampleModel().getSampleSize(0);
-        return (raster.getTransferType() == transferType && raster.getNumBands() == 1 && (1 << sampleSize) >= mapSize);
-    }
-
-    @Override
-    public int getDataElement(int components[], int offset) {
-        int rgb = (components[offset] << 16) | (components[offset + 1]) << 8
-                | components[offset + 2];
-
-        if (hasAlpha) {
-            rgb |= components[offset + 3] << 24;
-        } else {
-            rgb |= 0xff000000;
-        }
-
-        int pixel;
-
-        switch (transferType) {
-            case DataBuffer.TYPE_BYTE:
-                byte ba[] = (byte[])getDataElements(rgb, null);
-                pixel = ba[0] & 0xff;
-                break;
-            case DataBuffer.TYPE_USHORT:
-                short sa[] = (short[])getDataElements(rgb, null);
-                pixel = sa[0] & 0xffff;
-                break;
-            default:
-                // awt.267=The transferType is invalid
-                throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
-        }
-
-        return pixel;
-    }
-
-    /**
-     * Gets the color map.
-     * 
-     * @param rgb
-     *            the destination array where the color map is written.
-     */
-    public final void getRGBs(int rgb[]) {
-        System.arraycopy(colorMap, 0, rgb, 0, mapSize);
-    }
-
-    /**
-     * Gets the red component of the color map.
-     * 
-     * @param r
-     *            the destination array.
-     */
-    public final void getReds(byte r[]) {
-        for (int i = 0; i < mapSize; i++) {
-            r[i] = (byte)(colorMap[i] >> 16);
-        }
-    }
-
-    /**
-     * Gets the green component of the color map.
-     * 
-     * @param g
-     *            the destination array.
-     */
-    public final void getGreens(byte g[]) {
-        for (int i = 0; i < mapSize; i++) {
-            g[i] = (byte)(colorMap[i] >> 8);
-        }
-    }
-
-    /**
-     * Gets the blue component of the color map.
-     * 
-     * @param b
-     *            the destination array.
-     */
-    public final void getBlues(byte b[]) {
-        for (int i = 0; i < mapSize; i++) {
-            b[i] = (byte)colorMap[i];
-        }
-    }
-
-    /**
-     * Gets the alpha component of the color map.
-     * 
-     * @param a
-     *            the destination array.
-     */
-    public final void getAlphas(byte a[]) {
-        for (int i = 0; i < mapSize; i++) {
-            a[i] = (byte)(colorMap[i] >> 24);
-        }
-    }
-
-    @Override
-    public int[] getComponents(int pixel, int components[], int offset) {
-        if (components == null) {
-            components = new int[offset + numComponents];
-        }
-
-        components[offset + 0] = getRed(pixel);
-        components[offset + 1] = getGreen(pixel);
-        components[offset + 2] = getBlue(pixel);
-        if (hasAlpha && (components.length - offset) > 3) {
-            components[offset + 3] = getAlpha(pixel);
-        }
-
-        return components;
-    }
-
-    /**
-     * Checks if the specified pixel is valid for this color model.
-     * 
-     * @param pixel
-     *            the pixel.
-     * @return true, if the pixel is valid.
-     */
-    public boolean isValid(int pixel) {
-        if (validBits == null) {
-            return (pixel >= 0 && pixel < mapSize);
-        }
-        return (pixel < mapSize && validBits.testBit(pixel));
-    }
-
-    @Override
-    public final int getRed(int pixel) {
-        return (colorMap[pixel] >> 16) & 0xff;
-    }
-
-    @Override
-    public final int getRGB(int pixel) {
-        return colorMap[pixel];
-    }
-
-    @Override
-    public final int getGreen(int pixel) {
-        return (colorMap[pixel] >> 8) & 0xff;
-    }
-
-    @Override
-    public final int getBlue(int pixel) {
-        return colorMap[pixel] & 0xff;
-    }
-
-    @Override
-    public final int getAlpha(int pixel) {
-        return (colorMap[pixel] >> 24) & 0xff;
-    }
-
-    @Override
-    public int[] getComponentSize() {
-        return bits.clone();
-    }
-
-    /**
-     * Checks if this color model validates pixels.
-     * 
-     * @return true, if all pixels are valid, otherwise false.
-     */
-    public boolean isValid() {
-        return (validBits == null);
-    }
-
-    @Override
-    public void finalize() {
-        // TODO: implement
-        return;
-    }
-
-    /**
-     * Gets the index that represents the transparent pixel.
-     * 
-     * @return the index that represents the transparent pixel.
-     */
-    public final int getTransparentPixel() {
-        return transparentIndex;
-    }
-
-    @Override
-    public int getTransparency() {
-        return transparency;
-    }
-
-    /**
-     * Gets the size of the color map.
-     * 
-     * @return the map size.
-     */
-    public final int getMapSize() {
-        return mapSize;
-    }
-
-    /**
-     * Creates the color map.
-     * 
-     * @param size
-     *            the size.
-     * @param r
-     *            the r.
-     * @param g
-     *            the g.
-     * @param b
-     *            the b.
-     * @param a
-     *            the a.
-     * @param trans
-     *            the trans.
-     */
-    private void createColorMap(int size, byte r[], byte g[], byte b[], byte a[], int trans) {
-        if (size < 1) {
-            // awt.264=Size of the color map is less than 1
-            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
-        }
-
-        mapSize = size;
-        colorMap = new int[mapSize];
-        if (trans >= 0 && trans < mapSize) {
-            transparency = Transparency.BITMASK;
-            transparentIndex = trans;
-        } else {
-            transparency = Transparency.OPAQUE;
-            transparentIndex = -1;
-        }
-        int alpha = 0;
-
-        for (int i = 0; i < mapSize; i++) {
-            colorMap[i] = ((r[i] & 0xff) << 16) | ((g[i] & 0xff) << 8) | (b[i] & 0xff);
-
-            if (trans == i) {
-                continue;
-            }
-
-            if (a == null) {
-                colorMap[i] |= 0xff000000;
-            } else {
-                alpha = a[i] & 0xff;
-                if (alpha == 0xff) {
-                    colorMap[i] |= 0xff000000;
-                } else if (alpha == 0) {
-                    if (transparency == Transparency.OPAQUE) {
-                        transparency = Transparency.BITMASK;
-                    }
-                    if (transparentIndex < 0) {
-                        transparentIndex = i;
-                    }
-                } else {
-                    colorMap[i] |= (a[i] & 0xff) << 24;
-                    if (transparency != Transparency.TRANSLUCENT) {
-                        transparency = Transparency.TRANSLUCENT;
-                    }
-                }
-            }
-
-        }
-
-    }
-
-    /**
-     * This method checking, if Color Map has Gray palette.
-     */
-    private void checkPalette() {
-        grayPalette = false;
-        if (transparency > Transparency.OPAQUE) {
-            return;
-        }
-        int rgb = 0;
-
-        for (int i = 0; i < mapSize; i++) {
-            rgb = colorMap[i];
-            if (((rgb >> 16) & 0xff) != ((rgb >> 8) & 0xff) || ((rgb >> 8) & 0xff) != (rgb & 0xff)) {
-                return;
-            }
-        }
-        grayPalette = true;
-    }
-
-    /**
-     * Construction an array pixel representation.
-     * 
-     * @param colorMapIdx
-     *            the index into Color Map.
-     * @param pixel
-     *            the pixel
-     * @return the pixel representation array.
-     */
-    private Object createDataObject(int colorMapIdx, Object pixel) {
-        if (pixel == null) {
-            switch (transferType) {
-                case DataBuffer.TYPE_BYTE:
-                    byte[] ba = new byte[1];
-                    ba[0] = (byte)colorMapIdx;
-                    pixel = ba;
-                    break;
-                case DataBuffer.TYPE_USHORT:
-                    short[] sa = new short[1];
-                    sa[0] = (short)colorMapIdx;
-                    pixel = sa;
-                    break;
-                default:
-                    // awt.267=The transferType is invalid
-                    throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
-            }
-        } else if (pixel instanceof byte[] && transferType == DataBuffer.TYPE_BYTE) {
-            byte ba[] = (byte[])pixel;
-            ba[0] = (byte)colorMapIdx;
-            pixel = ba;
-        } else if (pixel instanceof short[] && transferType == DataBuffer.TYPE_USHORT) {
-            short[] sa = (short[])pixel;
-            sa[0] = (short)colorMapIdx;
-            pixel = sa;
-        } else if (pixel instanceof int[]) {
-            int ia[] = (int[])pixel;
-            ia[0] = colorMapIdx;
-            pixel = ia;
-        } else {
-            // awt.268=The pixel is not a primitive array of type transferType
-            throw new ClassCastException(Messages.getString("awt.268")); //$NON-NLS-1$
-        }
-        return pixel;
-    }
-
-    /**
-     * Creates the bits.
-     * 
-     * @param hasAlpha
-     *            the has alpha.
-     * @return the int[].
-     */
-    private static int[] createBits(boolean hasAlpha) {
-
-        int numChannels;
-        if (hasAlpha) {
-            numChannels = 4;
-        } else {
-            numChannels = 3;
-        }
-
-        int bits[] = new int[numChannels];
-        for (int i = 0; i < numChannels; i++) {
-            bits[i] = 8;
-        }
-
-        return bits;
-
-    }
-
-    /**
-     * Validate transfer type.
-     * 
-     * @param transferType
-     *            the transfer type.
-     * @return the int.
-     */
-    private static int validateTransferType(int transferType) {
-        if (transferType != DataBuffer.TYPE_BYTE && transferType != DataBuffer.TYPE_USHORT) {
-            // awt.269=The transferType is not one of DataBuffer.TYPE_BYTE or
-            // DataBuffer.TYPE_USHORT
-            throw new IllegalArgumentException(Messages.getString("awt.269")); //$NON-NLS-1$
-        }
-        return transferType;
-    }
-
-    /**
-     * Checks if is gray palette.
-     * 
-     * @return true, if is gray palette.
-     */
-    boolean isGrayPallete() {
-        return grayPalette;
-    }
-
-}
diff --git a/awt/java/awt/image/Kernel.java b/awt/java/awt/image/Kernel.java
deleted file mode 100644
index a59d27a..0000000
--- a/awt/java/awt/image/Kernel.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Sep 28, 2005
- */
-
-package java.awt.image;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Kernel class provides a matrix. This matrix is stored as a float array
- * which describes how a specified pixel affects the value calculated for the
- * pixel's position in the output image of a filtering operation. The X, Y
- * origins indicate the kernel matrix element which corresponds to the pixel
- * position for which an output value is being calculated.
- * 
- * @since Android 1.0
- */
-public class Kernel implements Cloneable {
-
-    /**
-     * The x origin.
-     */
-    private final int xOrigin;
-
-    /**
-     * The y origin.
-     */
-    private final int yOrigin;
-
-    /**
-     * The width.
-     */
-    private int width;
-
-    /**
-     * The height.
-     */
-    private int height;
-
-    /**
-     * The data.
-     */
-    float data[];
-
-    /**
-     * Instantiates a new Kernel with the specified float array. The
-     * width*height elements of the data array are copied.
-     * 
-     * @param width
-     *            the width of the Kernel.
-     * @param height
-     *            the height of the Kernel.
-     * @param data
-     *            the data of Kernel.
-     */
-    public Kernel(int width, int height, float[] data) {
-        int dataLength = width * height;
-        if (data.length < dataLength) {
-            // awt.22B=Length of data should not be less than width*height
-            throw new IllegalArgumentException(Messages.getString("awt.22B")); //$NON-NLS-1$
-        }
-
-        this.width = width;
-        this.height = height;
-
-        this.data = new float[dataLength];
-        System.arraycopy(data, 0, this.data, 0, dataLength);
-
-        xOrigin = (width - 1) / 2;
-        yOrigin = (height - 1) / 2;
-    }
-
-    /**
-     * Gets the width of this Kernel.
-     * 
-     * @return the width of this Kernel.
-     */
-    public final int getWidth() {
-        return width;
-    }
-
-    /**
-     * Gets the height of this Kernel.
-     * 
-     * @return the height of this Kernel.
-     */
-    public final int getHeight() {
-        return height;
-    }
-
-    /**
-     * Gets the float data array of this Kernel.
-     * 
-     * @param data
-     *            the float array where the resulted data will be stored.
-     * @return the float data array of this Kernel.
-     */
-    public final float[] getKernelData(float[] data) {
-        if (data == null) {
-            data = new float[this.data.length];
-        }
-        System.arraycopy(this.data, 0, data, 0, this.data.length);
-
-        return data;
-    }
-
-    /**
-     * Gets the X origin of this Kernel.
-     * 
-     * @return the X origin of this Kernel.
-     */
-    public final int getXOrigin() {
-        return xOrigin;
-    }
-
-    /**
-     * Gets the Y origin of this Kernel.
-     * 
-     * @return the Y origin of this Kernel.
-     */
-    public final int getYOrigin() {
-        return yOrigin;
-    }
-
-    /**
-     * Returns a copy of this Kernel object.
-     * 
-     * @return the copy of this Kernel object.
-     */
-    @Override
-    public Object clone() {
-        return new Kernel(width, height, data);
-    }
-}
diff --git a/awt/java/awt/image/LookupOp.java b/awt/java/awt/image/LookupOp.java
deleted file mode 100644
index 3362c5c..0000000
--- a/awt/java/awt/image/LookupOp.java
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Oct 14, 2005
- */
-
-package java.awt.image;
-
-import java.awt.*;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.Point2D;
-import java.util.Arrays;
-
-import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The LookupOp class performs a lookup operation which transforms a source
- * image by filtering each band using a table of data. The table may contain a
- * single array or it may contain a different data array for each band of the
- * image.
- * 
- * @since Android 1.0
- */
-public class LookupOp implements BufferedImageOp, RasterOp {
-
-    /**
-     * The lut.
-     */
-    private final LookupTable lut;
-
-    /**
-     * The hints.
-     */
-    private RenderingHints hints;
-
-    // TODO remove when this field is used
-    /**
-     * The can use ipp.
-     */
-    @SuppressWarnings("unused")
-    private final boolean canUseIpp;
-
-    // We don't create levels/values when it is possible to reuse old
-    /**
-     * The cached levels.
-     */
-    private int cachedLevels[];
-
-    /**
-     * The cached values.
-     */
-    private int cachedValues[];
-
-    // Number of channels for which cache is valid.
-    // If negative number of channels is same as positive but skipAlpha was
-    // specified
-    /**
-     * The valid for channels.
-     */
-    private int validForChannels;
-
-    /**
-     * The level initializer.
-     */
-    static int levelInitializer[] = new int[0x10000];
-
-    static {
-        // TODO
-        // System.loadLibrary("imageops");
-
-        for (int i = 1; i <= 0x10000; i++) {
-            levelInitializer[i - 1] = i;
-        }
-    }
-
-    /**
-     * Instantiates a new LookupOp object from the specified LookupTable object
-     * and a RenderingHints object.
-     * 
-     * @param lookup
-     *            the specified LookupTable object.
-     * @param hints
-     *            the RenderingHints object or null.
-     */
-    public LookupOp(LookupTable lookup, RenderingHints hints) {
-        if (lookup == null) {
-            throw new NullPointerException(Messages.getString("awt.01", "lookup")); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-        lut = lookup;
-        this.hints = hints;
-        canUseIpp = lut instanceof ByteLookupTable || lut instanceof ShortLookupTable;
-    }
-
-    /**
-     * Gets the LookupTable of the specified Object.
-     * 
-     * @return the LookupTable of the specified Object.
-     */
-    public final LookupTable getTable() {
-        return lut;
-    }
-
-    public final RenderingHints getRenderingHints() {
-        return hints;
-    }
-
-    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
-        if (dstPt == null) {
-            dstPt = new Point2D.Float();
-        }
-
-        dstPt.setLocation(srcPt);
-        return dstPt;
-    }
-
-    public final Rectangle2D getBounds2D(Raster src) {
-        return src.getBounds();
-    }
-
-    public final Rectangle2D getBounds2D(BufferedImage src) {
-        return getBounds2D(src.getRaster());
-    }
-
-    public WritableRaster createCompatibleDestRaster(Raster src) {
-        return src.createCompatibleWritableRaster();
-    }
-
-    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
-        if (dstCM == null) {
-            dstCM = src.getColorModel();
-
-            // Sync transfer type with LUT for component color model
-            if (dstCM instanceof ComponentColorModel) {
-                int transferType = dstCM.getTransferType();
-                if (lut instanceof ByteLookupTable) {
-                    transferType = DataBuffer.TYPE_BYTE;
-                } else if (lut instanceof ShortLookupTable) {
-                    transferType = DataBuffer.TYPE_SHORT;
-                }
-
-                dstCM = new ComponentColorModel(dstCM.cs, dstCM.hasAlpha(),
-                        dstCM.isAlphaPremultiplied, dstCM.transparency, transferType);
-            }
-        }
-
-        WritableRaster r = dstCM.isCompatibleSampleModel(src.getSampleModel()) ? src.getRaster()
-                .createCompatibleWritableRaster(src.getWidth(), src.getHeight()) : dstCM
-                .createCompatibleWritableRaster(src.getWidth(), src.getHeight());
-
-        return new BufferedImage(dstCM, r, dstCM.isAlphaPremultiplied(), null);
-    }
-
-    public final WritableRaster filter(Raster src, WritableRaster dst) {
-        if (dst == null) {
-            dst = createCompatibleDestRaster(src);
-        } else {
-            if (src.getNumBands() != dst.getNumBands()) {
-                throw new IllegalArgumentException(Messages.getString("awt.237")); //$NON-NLS-1$            }
-            }
-            if (src.getWidth() != dst.getWidth()) {
-                throw new IllegalArgumentException(Messages.getString("awt.28F")); //$NON-NLS-1$            }
-            }
-            if (src.getHeight() != dst.getHeight()) {
-                throw new IllegalArgumentException(Messages.getString("awt.290")); //$NON-NLS-1$            }
-            }
-        }
-
-        if (lut.getNumComponents() != 1 && lut.getNumComponents() != src.getNumBands()) {
-            // awt.238=The number of arrays in the LookupTable does not meet the
-            // restrictions
-            throw new IllegalArgumentException(Messages.getString("awt.238")); //$NON-NLS-1$
-        }
-
-        // TODO
-        // if (!canUseIpp || ippFilter(src, dst, BufferedImage.TYPE_CUSTOM,
-        // false) != 0)
-        if (slowFilter(src, dst, false) != 0) {
-            // awt.21F=Unable to transform source
-            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
-        }
-
-        return dst;
-    }
-
-    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
-        ColorModel srcCM = src.getColorModel();
-
-        if (srcCM instanceof IndexColorModel) {
-            // awt.220=Source should not have IndexColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.220")); //$NON-NLS-1$
-        }
-
-        // Check if the number of scaling factors matches the number of bands
-        int nComponents = srcCM.getNumComponents();
-        int nLUTComponents = lut.getNumComponents();
-        boolean skipAlpha;
-        if (srcCM.hasAlpha()) {
-            if (nLUTComponents == 1 || nLUTComponents == nComponents - 1) {
-                skipAlpha = true;
-            } else if (nLUTComponents == nComponents) {
-                skipAlpha = false;
-            } else {
-                // awt.229=Number of components in the LUT does not match the
-                // number of bands
-                throw new IllegalArgumentException(Messages.getString("awt.229")); //$NON-NLS-1$
-            }
-        } else if (nLUTComponents == 1 || nLUTComponents == nComponents) {
-            skipAlpha = false;
-        } else {
-            // awt.229=Number of components in the LUT does not match the number
-            // of bands
-            throw new IllegalArgumentException(Messages.getString("awt.229")); //$NON-NLS-1$
-        }
-
-        BufferedImage finalDst = null;
-        if (dst == null) {
-            finalDst = dst;
-            dst = createCompatibleDestImage(src, null);
-        } else {
-            if (src.getWidth() != dst.getWidth()) {
-                throw new IllegalArgumentException(Messages.getString("awt.291")); //$NON-NLS-1$
-            }
-
-            if (src.getHeight() != dst.getHeight()) {
-                throw new IllegalArgumentException(Messages.getString("awt.292")); //$NON-NLS-1$
-            }
-
-            if (!srcCM.equals(dst.getColorModel())) {
-                // Treat BufferedImage.TYPE_INT_RGB and
-                // BufferedImage.TYPE_INT_ARGB as same
-                if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src.getType() == BufferedImage.TYPE_INT_ARGB) && (dst
-                        .getType() == BufferedImage.TYPE_INT_RGB || dst.getType() == BufferedImage.TYPE_INT_ARGB))) {
-                    finalDst = dst;
-                    dst = createCompatibleDestImage(src, null);
-                }
-            }
-        }
-
-        // TODO
-        // if (!canUseIpp || ippFilter(src.getRaster(), dst.getRaster(),
-        // src.getType(), skipAlpha) != 0)
-        if (slowFilter(src.getRaster(), dst.getRaster(), skipAlpha) != 0) {
-            // awt.21F=Unable to transform source
-            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
-        }
-
-        if (finalDst != null) {
-            Graphics2D g = finalDst.createGraphics();
-            g.setComposite(AlphaComposite.Src);
-            g.drawImage(dst, 0, 0, null);
-        } else {
-            finalDst = dst;
-        }
-
-        return dst;
-    }
-
-    /**
-     * Slow filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @param skipAlpha
-     *            the skip alpha.
-     * @return the int.
-     */
-    private final int slowFilter(Raster src, WritableRaster dst, boolean skipAlpha) {
-        int minSrcX = src.getMinX();
-        int minDstX = dst.getMinX();
-        int minSrcY = src.getMinY();
-        int minDstY = dst.getMinY();
-
-        int skippingChannels = skipAlpha ? 1 : 0;
-        int numBands2Process = src.getNumBands() - skippingChannels;
-
-        int numBands = src.getNumBands();
-        int srcHeight = src.getHeight();
-        int srcWidth = src.getWidth();
-
-        int[] pixels = null;
-        int offset = lut.getOffset();
-
-        if (lut instanceof ByteLookupTable) {
-            byte[][] byteData = ((ByteLookupTable)lut).getTable();
-            pixels = src.getPixels(minSrcX, minSrcY, srcWidth, srcHeight, pixels);
-
-            if (lut.getNumComponents() != 1) {
-                for (int i = 0; i < pixels.length; i += numBands) {
-                    for (int b = 0; b < numBands2Process; b++) {
-                        pixels[i + b] = byteData[b][pixels[i + b] - offset] & 0xFF;
-                    }
-                }
-            } else {
-                for (int i = 0; i < pixels.length; i += numBands) {
-                    for (int b = 0; b < numBands2Process; b++) {
-                        pixels[i + b] = byteData[0][pixels[i + b] - offset] & 0xFF;
-                    }
-                }
-            }
-
-            dst.setPixels(minDstX, minDstY, srcWidth, srcHeight, pixels);
-        } else if (lut instanceof ShortLookupTable) {
-            short[][] shortData = ((ShortLookupTable)lut).getTable();
-            pixels = src.getPixels(minSrcX, minSrcY, srcWidth, srcHeight, pixels);
-
-            if (lut.getNumComponents() != 1) {
-                for (int i = 0; i < pixels.length; i += numBands) {
-                    for (int b = 0; b < numBands2Process; b++) {
-                        pixels[i + b] = shortData[b][pixels[i + b] - offset] & 0xFFFF;
-                    }
-                }
-            } else {
-                for (int i = 0; i < pixels.length; i += numBands) {
-                    for (int b = 0; b < numBands2Process; b++) {
-                        pixels[i + b] = shortData[0][pixels[i + b] - offset] & 0xFFFF;
-                    }
-                }
-            }
-
-            dst.setPixels(minDstX, minDstY, srcWidth, srcHeight, pixels);
-        } else {
-            int pixel[] = new int[src.getNumBands()];
-            int maxY = minSrcY + srcHeight;
-            int maxX = minSrcX + srcWidth;
-            for (int srcY = minSrcY, dstY = minDstY; srcY < maxY; srcY++, dstY++) {
-                for (int srcX = minSrcX, dstX = minDstX; srcX < maxX; srcX++, dstX++) {
-                    src.getPixel(srcX, srcY, pixel);
-                    lut.lookupPixel(pixel, pixel);
-                    dst.setPixel(dstX, dstY, pixel);
-                }
-            }
-        }
-
-        return 0;
-    }
-
-    /**
-     * Creates the byte levels.
-     * 
-     * @param channels
-     *            the channels.
-     * @param skipAlpha
-     *            the skip alpha.
-     * @param levels
-     *            the levels.
-     * @param values
-     *            the values.
-     * @param channelsOrder
-     *            the channels order.
-     */
-    private final void createByteLevels(int channels, boolean skipAlpha, int levels[],
-            int values[], int channelsOrder[]) {
-        byte data[][] = ((ByteLookupTable)lut).getTable();
-        int nLevels = data[0].length;
-        int offset = lut.getOffset();
-
-        // Use one data array for all channels or use several data arrays
-        int dataIncrement = data.length > 1 ? 1 : 0;
-
-        for (int ch = 0, dataIdx = 0; ch < channels; dataIdx += dataIncrement, ch++) {
-            int channelOffset = channelsOrder == null ? ch : channelsOrder[ch];
-            int channelBase = nLevels * channelOffset;
-
-            // Skip last channel if needed, zero values are OK -
-            // no changes to the channel information will be done in IPP
-            if ((channelOffset == channels - 1 && skipAlpha) || (dataIdx >= data.length)) {
-                continue;
-            }
-
-            System.arraycopy(levelInitializer, offset, levels, channelBase, nLevels);
-            for (int from = 0, to = channelBase; from < nLevels; from++, to++) {
-                values[to] = data[dataIdx][from] & 0xFF;
-            }
-        }
-    }
-
-    /**
-     * Creates the short levels.
-     * 
-     * @param channels
-     *            the channels.
-     * @param skipAlpha
-     *            the skip alpha.
-     * @param levels
-     *            the levels.
-     * @param values
-     *            the values.
-     * @param channelsOrder
-     *            the channels order.
-     */
-    private final void createShortLevels(int channels, boolean skipAlpha, int levels[],
-            int values[], int channelsOrder[]) {
-        short data[][] = ((ShortLookupTable)lut).getTable();
-        int nLevels = data[0].length;
-        int offset = lut.getOffset();
-
-        // Use one data array for all channels or use several data arrays
-        int dataIncrement = data.length > 1 ? 1 : 0;
-
-        for (int ch = 0, dataIdx = 0; ch < channels; dataIdx += dataIncrement, ch++) {
-            int channelOffset = channelsOrder == null ? ch : channelsOrder[ch];
-
-            // Skip last channel if needed, zero values are OK -
-            // no changes to the channel information will be done in IPP
-            if ((channelOffset == channels - 1 && skipAlpha) || (dataIdx >= data.length)) {
-                continue;
-            }
-
-            int channelBase = nLevels * channelOffset;
-            System.arraycopy(levelInitializer, offset, levels, channelBase, nLevels);
-            for (int from = 0, to = channelBase; from < nLevels; from++, to++) {
-                values[to] = data[dataIdx][from] & 0xFFFF;
-            }
-        }
-    }
-
-    // TODO remove when this method is used
-    /**
-     * Ipp filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @param imageType
-     *            the image type.
-     * @param skipAlpha
-     *            the skip alpha.
-     * @return the int.
-     */
-    @SuppressWarnings("unused")
-    private final int ippFilter(Raster src, WritableRaster dst, int imageType, boolean skipAlpha) {
-        int res;
-
-        int srcStride, dstStride;
-        int channels;
-        int offsets[] = null;
-        int channelsOrder[] = null;
-
-        switch (imageType) {
-            case BufferedImage.TYPE_INT_ARGB:
-            case BufferedImage.TYPE_INT_ARGB_PRE:
-            case BufferedImage.TYPE_INT_RGB: {
-                channels = 4;
-                srcStride = src.getWidth() * 4;
-                dstStride = dst.getWidth() * 4;
-                channelsOrder = new int[] {
-                        2, 1, 0, 3
-                };
-                break;
-            }
-
-            case BufferedImage.TYPE_4BYTE_ABGR:
-            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
-            case BufferedImage.TYPE_INT_BGR: {
-                channels = 4;
-                srcStride = src.getWidth() * 4;
-                dstStride = dst.getWidth() * 4;
-                break;
-            }
-
-            case BufferedImage.TYPE_BYTE_GRAY: {
-                channels = 1;
-                srcStride = src.getWidth();
-                dstStride = dst.getWidth();
-                break;
-            }
-
-            case BufferedImage.TYPE_3BYTE_BGR: {
-                channels = 3;
-                srcStride = src.getWidth() * 3;
-                dstStride = dst.getWidth() * 3;
-                channelsOrder = new int[] {
-                        2, 1, 0
-                };
-                break;
-            }
-
-            case BufferedImage.TYPE_USHORT_GRAY:
-            case BufferedImage.TYPE_USHORT_565_RGB:
-            case BufferedImage.TYPE_USHORT_555_RGB:
-            case BufferedImage.TYPE_BYTE_BINARY: {
-                return slowFilter(src, dst, skipAlpha);
-            }
-
-            default: {
-                SampleModel srcSM = src.getSampleModel();
-                SampleModel dstSM = dst.getSampleModel();
-
-                if (srcSM instanceof PixelInterleavedSampleModel
-                        && dstSM instanceof PixelInterleavedSampleModel) {
-                    // Check PixelInterleavedSampleModel
-                    if (srcSM.getDataType() != DataBuffer.TYPE_BYTE
-                            || dstSM.getDataType() != DataBuffer.TYPE_BYTE) {
-                        return slowFilter(src, dst, skipAlpha);
-                    }
-
-                    // Have IPP functions for 1, 3 and 4 channels
-                    channels = srcSM.getNumBands();
-                    if (!(channels == 1 || channels == 3 || channels == 4)) {
-                        return slowFilter(src, dst, skipAlpha);
-                    }
-
-                    srcStride = ((ComponentSampleModel)srcSM).getScanlineStride();
-                    dstStride = ((ComponentSampleModel)dstSM).getScanlineStride();
-
-                    channelsOrder = ((ComponentSampleModel)srcSM).getBandOffsets();
-                } else if (srcSM instanceof SinglePixelPackedSampleModel
-                        && dstSM instanceof SinglePixelPackedSampleModel) {
-                    // Check SinglePixelPackedSampleModel
-                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)srcSM;
-                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel)dstSM;
-
-                    channels = sppsm1.getNumBands();
-
-                    // TYPE_INT_RGB, TYPE_INT_ARGB...
-                    if (sppsm1.getDataType() != DataBuffer.TYPE_INT
-                            || sppsm2.getDataType() != DataBuffer.TYPE_INT
-                            || !(channels == 3 || channels == 4)) {
-                        return slowFilter(src, dst, skipAlpha);
-                    }
-
-                    // Check compatibility of sample models
-                    if (!Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets())
-                            || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) {
-                        return slowFilter(src, dst, skipAlpha);
-                    }
-
-                    for (int i = 0; i < channels; i++) {
-                        if (sppsm1.getSampleSize(i) != 8) {
-                            return slowFilter(src, dst, skipAlpha);
-                        }
-                    }
-
-                    channelsOrder = new int[channels];
-                    int bitOffsets[] = sppsm1.getBitOffsets();
-                    for (int i = 0; i < channels; i++) {
-                        channelsOrder[i] = bitOffsets[i] / 8;
-                    }
-
-                    if (channels == 3) { // Don't skip channel now, could be
-                        // optimized
-                        channels = 4;
-                    }
-
-                    srcStride = sppsm1.getScanlineStride() * 4;
-                    dstStride = sppsm2.getScanlineStride() * 4;
-                } else {
-                    return slowFilter(src, dst, skipAlpha);
-                }
-
-                // Fill offsets if there's a child raster
-                if (src.getParent() != null || dst.getParent() != null) {
-                    if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
-                            || dst.getSampleModelTranslateX() != 0
-                            || dst.getSampleModelTranslateY() != 0) {
-                        offsets = new int[4];
-                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
-                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
-                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
-                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
-                    }
-                }
-            }
-        }
-
-        int levels[] = null, values[] = null;
-        int channelMultiplier = skipAlpha ? -1 : 1;
-        if (channelMultiplier * channels == validForChannels) { // use existing
-            // levels/values
-            levels = cachedLevels;
-            values = cachedValues;
-        } else { // create new levels/values
-            if (lut instanceof ByteLookupTable) {
-                byte data[][] = ((ByteLookupTable)lut).getTable();
-                levels = new int[channels * data[0].length];
-                values = new int[channels * data[0].length];
-                createByteLevels(channels, skipAlpha, levels, values, channelsOrder);
-            } else if (lut instanceof ShortLookupTable) {
-                short data[][] = ((ShortLookupTable)lut).getTable();
-                levels = new int[channels * data[0].length];
-                values = new int[channels * data[0].length];
-                createShortLevels(channels, skipAlpha, levels, values, channelsOrder);
-            }
-
-            // cache levels/values
-            validForChannels = channelMultiplier * channels;
-            cachedLevels = levels;
-            cachedValues = values;
-        }
-
-        Object srcData, dstData;
-        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
-        try {
-            srcData = dbAccess.getData(src.getDataBuffer());
-            dstData = dbAccess.getData(dst.getDataBuffer());
-        } catch (IllegalArgumentException e) {
-            return -1; // Unknown data buffer type
-        }
-
-        res = ippLUT(srcData, src.getWidth(), src.getHeight(), srcStride, dstData, dst.getWidth(),
-                dst.getHeight(), dstStride, levels, values, channels, offsets, false);
-
-        return res;
-    }
-
-    /**
-     * Ipp lut.
-     * 
-     * @param src
-     *            the src.
-     * @param srcWidth
-     *            the src width.
-     * @param srcHeight
-     *            the src height.
-     * @param srcStride
-     *            the src stride.
-     * @param dst
-     *            the dst.
-     * @param dstWidth
-     *            the dst width.
-     * @param dstHeight
-     *            the dst height.
-     * @param dstStride
-     *            the dst stride.
-     * @param levels
-     *            the levels.
-     * @param values
-     *            the values.
-     * @param channels
-     *            the channels.
-     * @param offsets
-     *            the offsets.
-     * @param linear
-     *            the linear.
-     * @return the int.
-     */
-    final static native int ippLUT(Object src, int srcWidth, int srcHeight, int srcStride,
-            Object dst, int dstWidth, int dstHeight, int dstStride, int levels[], int values[],
-            int channels, int offsets[], boolean linear);
-}
diff --git a/awt/java/awt/image/LookupTable.java b/awt/java/awt/image/LookupTable.java
deleted file mode 100644
index e465a54..0000000
--- a/awt/java/awt/image/LookupTable.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Oct 14, 2005
- */
-
-package java.awt.image;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * This abstract LookupTable class represents lookup table which is defined with
- * the number of components and offset value. ByteLookupTable and
- * ShortLookupTable classes are subclasses of LookupTable which contains byte
- * and short data tables as an input arrays for bands or components of image.
- * 
- * @since Android 1.0
- */
-public abstract class LookupTable {
-
-    /**
-     * The offset.
-     */
-    private int offset;
-
-    /**
-     * The num components.
-     */
-    private int numComponents;
-
-    /**
-     * Instantiates a new LookupTable with the specified offset value and number
-     * of components.
-     * 
-     * @param offset
-     *            the offset value.
-     * @param numComponents
-     *            the number of components.
-     */
-    protected LookupTable(int offset, int numComponents) {
-        if (offset < 0) {
-            // awt.232=Offset should be not less than zero
-            throw new IllegalArgumentException(Messages.getString("awt.232")); //$NON-NLS-1$
-        }
-        if (numComponents < 1) {
-            // awt.233=Number of components should be positive
-            throw new IllegalArgumentException(Messages.getString("awt.233")); //$NON-NLS-1$
-        }
-
-        this.offset = offset;
-        this.numComponents = numComponents;
-    }
-
-    /**
-     * Gets the offset value of this Lookup table.
-     * 
-     * @return the offset value of this Lookup table.
-     */
-    public int getOffset() {
-        return offset;
-    }
-
-    /**
-     * Gets the number of components of this Lookup table.
-     * 
-     * @return the number components of this Lookup table.
-     */
-    public int getNumComponents() {
-        return numComponents;
-    }
-
-    /**
-     * Returns an integer array which contains samples of the specified pixel which
-     * is translated with the lookup table of this LookupTable. The resulted
-     * array is stored to the dst array.
-     * 
-     * @param src
-     *            the source array.
-     * @param dst
-     *            the destination array where the result can be stored.
-     * @return the integer array of translated samples of a pixel.
-     */
-    public abstract int[] lookupPixel(int[] src, int[] dst);
-}
diff --git a/awt/java/awt/image/MemoryImageSource.java b/awt/java/awt/image/MemoryImageSource.java
deleted file mode 100644
index 644fd40..0000000
--- a/awt/java/awt/image/MemoryImageSource.java
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.util.Hashtable;
-import java.util.Vector;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The MemoryImageSource class is used to produces pixels of an image from an
- * array. This class can manage a memory image which contains an animation or
- * custom rendering.
- * 
- * @since Android 1.0
- */
-public class MemoryImageSource implements ImageProducer {
-
-    /**
-     * The width.
-     */
-    int width;
-
-    /**
-     * The height.
-     */
-    int height;
-
-    /**
-     * The cm.
-     */
-    ColorModel cm;
-
-    /**
-     * The b data.
-     */
-    byte bData[];
-
-    /**
-     * The i data.
-     */
-    int iData[];
-
-    /**
-     * The offset.
-     */
-    int offset;
-
-    /**
-     * The scanline.
-     */
-    int scanline;
-
-    /**
-     * The properties.
-     */
-    Hashtable<?, ?> properties;
-
-    /**
-     * The consumers.
-     */
-    Vector<ImageConsumer> consumers;
-
-    /**
-     * The animated.
-     */
-    boolean animated;
-
-    /**
-     * The fullbuffers.
-     */
-    boolean fullbuffers;
-
-    /**
-     * The data type.
-     */
-    int dataType;
-
-    /**
-     * The Constant DATA_TYPE_BYTE.
-     */
-    static final int DATA_TYPE_BYTE = 0;
-
-    /**
-     * The Constant DATA_TYPE_INT.
-     */
-    static final int DATA_TYPE_INT = 1;
-
-    /**
-     * Instantiates a new MemoryImageSource with the specified parameters.
-     * 
-     * @param w
-     *            the width of the rectangular area of pixels.
-     * @param h
-     *            the height of the rectangular area of pixels.
-     * @param cm
-     *            the specified ColorModel.
-     * @param pix
-     *            the pixel array.
-     * @param off
-     *            the offset in the pixel array.
-     * @param scan
-     *            the distance from one pixel's row to the next in the pixel
-     *            array.
-     * @param props
-     *            the set of properties to be used for image processing.
-     */
-    public MemoryImageSource(int w, int h, ColorModel cm, int pix[], int off, int scan,
-            Hashtable<?, ?> props) {
-        init(w, h, cm, pix, off, scan, props);
-    }
-
-    /**
-     * Instantiates a new MemoryImageSource with the specified parameters.
-     * 
-     * @param w
-     *            the width of the rectangular area of pixels.
-     * @param h
-     *            the height of the rectangular area of pixels.
-     * @param cm
-     *            the specified ColorModel.
-     * @param pix
-     *            the pixel array.
-     * @param off
-     *            the offset in the pixel array.
-     * @param scan
-     *            the distance from one pixel's row to the next in the pixel
-     *            array.
-     * @param props
-     *            the set of properties to be used for image processing.
-     */
-    public MemoryImageSource(int w, int h, ColorModel cm, byte pix[], int off, int scan,
-            Hashtable<?, ?> props) {
-        init(w, h, cm, pix, off, scan, props);
-    }
-
-    /**
-     * Instantiates a new MemoryImageSource with the specified parameters and
-     * default RGB ColorModel.
-     * 
-     * @param w
-     *            the width of the rectangular area of pixels.
-     * @param h
-     *            the height of the rectangular area of pixels.
-     * @param pix
-     *            the pixel array.
-     * @param off
-     *            the offset in the pixel array.
-     * @param scan
-     *            the distance from one pixel's row to the next in the pixel
-     *            array.
-     * @param props
-     *            the set of properties to be used for image processing.
-     */
-    public MemoryImageSource(int w, int h, int pix[], int off, int scan, Hashtable<?, ?> props) {
-        init(w, h, ColorModel.getRGBdefault(), pix, off, scan, props);
-    }
-
-    /**
-     * Instantiates a new MemoryImageSource with the specified parameters.
-     * 
-     * @param w
-     *            the width of the rectangular area of pixels.
-     * @param h
-     *            the height of the rectangular area of pixels.
-     * @param cm
-     *            the specified ColorModel.
-     * @param pix
-     *            the pixel array.
-     * @param off
-     *            the offset in the pixel array.
-     * @param scan
-     *            the distance from one pixel's row to the next in the pixel
-     *            array.
-     */
-    public MemoryImageSource(int w, int h, ColorModel cm, int pix[], int off, int scan) {
-        init(w, h, cm, pix, off, scan, null);
-    }
-
-    /**
-     * Instantiates a new MemoryImageSource with the specified parameters.
-     * 
-     * @param w
-     *            the width of the rectangular area of pixels.
-     * @param h
-     *            the height of the rectangular area of pixels.
-     * @param cm
-     *            the specified ColorModel.
-     * @param pix
-     *            the pixel array.
-     * @param off
-     *            the offset in the pixel array.
-     * @param scan
-     *            the distance from one pixel's row to the next in the pixel
-     *            array.
-     */
-    public MemoryImageSource(int w, int h, ColorModel cm, byte pix[], int off, int scan) {
-        init(w, h, cm, pix, off, scan, null);
-    }
-
-    /**
-     * Instantiates a new MemoryImageSource with the specified parameters and
-     * default RGB ColorModel.
-     * 
-     * @param w
-     *            the width of the rectangular area of pixels.
-     * @param h
-     *            the height of the rectangular area of pixels.
-     * @param pix
-     *            the pixels array.
-     * @param off
-     *            the offset in the pixel array.
-     * @param scan
-     *            the distance from one pixel's row to the next in the pixel
-     *            array.
-     */
-    public MemoryImageSource(int w, int h, int pix[], int off, int scan) {
-        init(w, h, ColorModel.getRGBdefault(), pix, off, scan, null);
-    }
-
-    public synchronized boolean isConsumer(ImageConsumer ic) {
-        return consumers.contains(ic);
-    }
-
-    public void startProduction(ImageConsumer ic) {
-        if (!isConsumer(ic) && ic != null) {
-            consumers.addElement(ic);
-        }
-        try {
-            setHeader(ic);
-            setPixels(ic, 0, 0, width, height);
-            if (animated) {
-                ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
-            } else {
-                ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
-                if (isConsumer(ic)) {
-                    removeConsumer(ic);
-                }
-            }
-        } catch (Exception e) {
-            if (isConsumer(ic)) {
-                ic.imageComplete(ImageConsumer.IMAGEERROR);
-            }
-            if (isConsumer(ic)) {
-                removeConsumer(ic);
-            }
-        }
-    }
-
-    public void requestTopDownLeftRightResend(ImageConsumer ic) {
-    }
-
-    public synchronized void removeConsumer(ImageConsumer ic) {
-        consumers.removeElement(ic);
-    }
-
-    public synchronized void addConsumer(ImageConsumer ic) {
-        if (ic == null || consumers.contains(ic)) {
-            return;
-        }
-        consumers.addElement(ic);
-    }
-
-    /**
-     * Replaces the pixel data with a new pixel array for holding the pixels for
-     * this image. If an animation flag is set to true value by the
-     * setAnimated() method, the new pixels will be immediately delivered to the
-     * ImageConsumers.
-     * 
-     * @param newpix
-     *            the new pixel array.
-     * @param newmodel
-     *            the new ColorModel.
-     * @param offset
-     *            the offset in the array.
-     * @param scansize
-     *            the distance from one row of pixels to the next row in the
-     *            pixel array.
-     */
-    public synchronized void newPixels(int newpix[], ColorModel newmodel, int offset, int scansize) {
-        this.dataType = DATA_TYPE_INT;
-        this.iData = newpix;
-        this.cm = newmodel;
-        this.offset = offset;
-        this.scanline = scansize;
-        newPixels();
-    }
-
-    /**
-     * Replaces the pixel data with a new pixel array for holding the pixels for
-     * this image. If an animation flag is set to true value by the
-     * setAnimated() method, the new pixels will be immediately delivered to the
-     * ImageConsumers.
-     * 
-     * @param newpix
-     *            the new pixel array.
-     * @param newmodel
-     *            the new ColorModel.
-     * @param offset
-     *            the offset in the array.
-     * @param scansize
-     *            the distance from one row of pixels to the next row in the
-     *            pixel array.
-     */
-    public synchronized void newPixels(byte newpix[], ColorModel newmodel, int offset, int scansize) {
-        this.dataType = DATA_TYPE_BYTE;
-        this.bData = newpix;
-        this.cm = newmodel;
-        this.offset = offset;
-        this.scanline = scansize;
-        newPixels();
-    }
-
-    /**
-     * Sets the full buffer updates flag to true. If this is an animated image,
-     * the image consumers hints are updated accordingly.
-     * 
-     * @param fullbuffers
-     *            the true if the pixel buffer should be sent always.
-     */
-    public synchronized void setFullBufferUpdates(boolean fullbuffers) {
-        if (this.fullbuffers == fullbuffers) {
-            return;
-        }
-        this.fullbuffers = fullbuffers;
-        if (animated) {
-            Object consAr[] = consumers.toArray();
-            for (Object element : consAr) {
-                ImageConsumer con = (ImageConsumer)element;
-                try {
-                    if (fullbuffers) {
-                        con.setHints(ImageConsumer.TOPDOWNLEFTRIGHT
-                                | ImageConsumer.COMPLETESCANLINES);
-                    } else {
-                        con.setHints(ImageConsumer.RANDOMPIXELORDER);
-                    }
-                } catch (Exception e) {
-                    if (isConsumer(con)) {
-                        con.imageComplete(ImageConsumer.IMAGEERROR);
-                    }
-                    if (isConsumer(con)) {
-                        removeConsumer(con);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Sets the flag that tells whether this memory image has more than one
-     * frame (for animation): true for multiple frames, false if this class
-     * represents a single frame image.
-     * 
-     * @param animated
-     *            whether this image represents an animation.
-     */
-    public synchronized void setAnimated(boolean animated) {
-        if (this.animated == animated) {
-            return;
-        }
-        Object consAr[] = consumers.toArray();
-        for (Object element : consAr) {
-            ImageConsumer con = (ImageConsumer)element;
-            try {
-                con.imageComplete(ImageConsumer.STATICIMAGEDONE);
-            } catch (Exception e) {
-                if (isConsumer(con)) {
-                    con.imageComplete(ImageConsumer.IMAGEERROR);
-                }
-            }
-            if (isConsumer(con)) {
-                removeConsumer(con);
-            }
-        }
-        this.animated = animated;
-    }
-
-    /**
-     * Sends the specified rectangular area of the buffer to ImageConsumers and
-     * notifies them that an animation frame is completed only if the {@code
-     * framenotify} parameter is true. That works only if the animated flag has
-     * been set to true by the setAnimated() method. If the full buffer update
-     * flag has been set to true by the setFullBufferUpdates() method, then the
-     * entire buffer will always be sent ignoring parameters.
-     * 
-     * @param x
-     *            the X coordinate of the rectangular area.
-     * @param y
-     *            the Y coordinate of the rectangular area.
-     * @param w
-     *            the width of the rectangular area.
-     * @param h
-     *            the height of the rectangular area.
-     * @param framenotify
-     *            true if a SINGLEFRAMEDONE notification should be sent to the
-     *            registered consumers, false otherwise.
-     */
-    public synchronized void newPixels(int x, int y, int w, int h, boolean framenotify) {
-        if (animated) {
-            if (fullbuffers) {
-                x = 0;
-                y = 0;
-                w = width;
-                h = height;
-            } else {
-                if (x < 0) {
-                    w += x;
-                    x = 0;
-                }
-                if (w > width) {
-                    w = width - x;
-                }
-                if (y < 0) {
-                    h += y;
-                    y = 0;
-                }
-            }
-            if (h > height) {
-                h = height - y;
-            }
-            Object consAr[] = consumers.toArray();
-            for (Object element : consAr) {
-                ImageConsumer con = (ImageConsumer)element;
-                try {
-                    if (w > 0 && h > 0) {
-                        setPixels(con, x, y, w, h);
-                    }
-                    if (framenotify) {
-                        con.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
-                    }
-                } catch (Exception ex) {
-                    if (isConsumer(con)) {
-                        con.imageComplete(ImageConsumer.IMAGEERROR);
-                    }
-                    if (isConsumer(con)) {
-                        removeConsumer(con);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Sends the specified rectangular area of the buffer to the ImageConsumers
-     * and notifies them that an animation frame is completed if the animated
-     * flag has been set to true by the setAnimated() method. If the full buffer
-     * update flag has been set to true by the setFullBufferUpdates() method,
-     * then the entire buffer will always be sent ignoring parameters.
-     * 
-     * @param x
-     *            the X coordinate of the rectangular area.
-     * @param y
-     *            the Y coordinate of the rectangular area.
-     * @param w
-     *            the width of the rectangular area.
-     * @param h
-     *            the height of the rectangular area.
-     */
-    public synchronized void newPixels(int x, int y, int w, int h) {
-        newPixels(x, y, w, h, true);
-    }
-
-    /**
-     * Sends a new buffer of pixels to the ImageConsumers and notifies them that
-     * an animation frame is completed if the animated flag has been set to true
-     * by the setAnimated() method.
-     */
-    public void newPixels() {
-        newPixels(0, 0, width, height, true);
-    }
-
-    /**
-     * Inits the.
-     * 
-     * @param width
-     *            the width.
-     * @param height
-     *            the height.
-     * @param model
-     *            the model.
-     * @param pixels
-     *            the pixels.
-     * @param off
-     *            the off.
-     * @param scan
-     *            the scan.
-     * @param prop
-     *            the prop.
-     */
-    private void init(int width, int height, ColorModel model, byte pixels[], int off, int scan,
-            Hashtable<?, ?> prop) {
-
-        this.width = width;
-        this.height = height;
-        this.cm = model;
-        this.bData = pixels;
-        this.offset = off;
-        this.scanline = scan;
-        this.properties = prop;
-        this.dataType = DATA_TYPE_BYTE;
-        this.consumers = new Vector<ImageConsumer>();
-
-    }
-
-    /**
-     * Inits the.
-     * 
-     * @param width
-     *            the width.
-     * @param height
-     *            the height.
-     * @param model
-     *            the model.
-     * @param pixels
-     *            the pixels.
-     * @param off
-     *            the off.
-     * @param scan
-     *            the scan.
-     * @param prop
-     *            the prop.
-     */
-    private void init(int width, int height, ColorModel model, int pixels[], int off, int scan,
-            Hashtable<?, ?> prop) {
-
-        this.width = width;
-        this.height = height;
-        this.cm = model;
-        this.iData = pixels;
-        this.offset = off;
-        this.scanline = scan;
-        this.properties = prop;
-        this.dataType = DATA_TYPE_INT;
-        this.consumers = new Vector<ImageConsumer>();
-    }
-
-    /**
-     * Sets the pixels.
-     * 
-     * @param con
-     *            the con.
-     * @param x
-     *            the x.
-     * @param y
-     *            the y.
-     * @param w
-     *            the w.
-     * @param h
-     *            the h.
-     */
-    private void setPixels(ImageConsumer con, int x, int y, int w, int h) {
-        int pixelOff = scanline * y + offset + x;
-
-        switch (dataType) {
-            case DATA_TYPE_BYTE:
-                con.setPixels(x, y, w, h, cm, bData, pixelOff, scanline);
-                break;
-            case DATA_TYPE_INT:
-                con.setPixels(x, y, w, h, cm, iData, pixelOff, scanline);
-                break;
-            default:
-                // awt.22A=Wrong type of pixels array
-                throw new IllegalArgumentException(Messages.getString("awt.22A")); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Sets the header.
-     * 
-     * @param con
-     *            the new header.
-     */
-    private synchronized void setHeader(ImageConsumer con) {
-        con.setDimensions(width, height);
-        con.setProperties(properties);
-        con.setColorModel(cm);
-        con
-                .setHints(animated ? (fullbuffers ? (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES)
-                        : ImageConsumer.RANDOMPIXELORDER)
-                        : (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES
-                                | ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME));
-    }
-
-}
diff --git a/awt/java/awt/image/MultiPixelPackedSampleModel.java b/awt/java/awt/image/MultiPixelPackedSampleModel.java
deleted file mode 100644
index 3dc13d8..0000000
--- a/awt/java/awt/image/MultiPixelPackedSampleModel.java
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The MultiPixelPackedSampleModel class represents image data with one band.
- * This class packs multiple pixels with one sample in one data element and
- * supports the following data types: DataBuffer.TYPE_BYTE,
- * DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT.
- * 
- * @since Android 1.0
- */
-public class MultiPixelPackedSampleModel extends SampleModel {
-
-    /**
-     * The pixel bit stride.
-     */
-    private int pixelBitStride;
-
-    /**
-     * The scanline stride.
-     */
-    private int scanlineStride;
-
-    /**
-     * The data bit offset.
-     */
-    private int dataBitOffset;
-
-    /**
-     * The bit mask.
-     */
-    private int bitMask;
-
-    /**
-     * The data element size.
-     */
-    private int dataElementSize;
-
-    /**
-     * The pixels per data element.
-     */
-    private int pixelsPerDataElement;
-
-    /**
-     * Instantiates a new MultiPixelPackedSampleModel with the specified
-     * parameters.
-     * 
-     * @param dataType
-     *            the data type of the samples.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param numberOfBits
-     *            the number of bits per pixel.
-     * @param scanlineStride
-     *            the scanline stride of the of the image data.
-     * @param dataBitOffset
-     *            the array of the band offsets.
-     */
-    public MultiPixelPackedSampleModel(int dataType, int w, int h, int numberOfBits,
-            int scanlineStride, int dataBitOffset) {
-
-        super(dataType, w, h, 1);
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
-                && dataType != DataBuffer.TYPE_INT) {
-            // awt.61=Unsupported data type: {0}
-            throw new IllegalArgumentException(Messages.getString("awt.61", //$NON-NLS-1$
-                    dataType));
-        }
-
-        this.scanlineStride = scanlineStride;
-        if (numberOfBits == 0) {
-            // awt.20C=Number of Bits equals to zero
-            throw new RasterFormatException(Messages.getString("awt.20C")); //$NON-NLS-1$
-        }
-        this.pixelBitStride = numberOfBits;
-        this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
-        if (dataElementSize % pixelBitStride != 0) {
-            // awt.20D=The number of bits per pixel is not a power of 2 or
-            // pixels span data element boundaries
-            throw new RasterFormatException(Messages.getString("awt.20D")); //$NON-NLS-1$
-        }
-
-        if (dataBitOffset % numberOfBits != 0) {
-            // awt.20E=Data Bit offset is not a multiple of pixel bit stride
-            throw new RasterFormatException(Messages.getString("awt.20E")); //$NON-NLS-1$
-        }
-        this.dataBitOffset = dataBitOffset;
-
-        this.pixelsPerDataElement = dataElementSize / pixelBitStride;
-        this.bitMask = (1 << numberOfBits) - 1;
-    }
-
-    /**
-     * Instantiates a new MultiPixelPackedSampleModel with the specified
-     * parameters.
-     * 
-     * @param dataType
-     *            the data type of the samples.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param numberOfBits
-     *            the number of bits per pixel.
-     */
-    public MultiPixelPackedSampleModel(int dataType, int w, int h, int numberOfBits) {
-
-        this(dataType, w, h, numberOfBits,
-                (numberOfBits * w + DataBuffer.getDataTypeSize(dataType) - 1)
-                        / DataBuffer.getDataTypeSize(dataType), 0);
-    }
-
-    @Override
-    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        switch (getTransferType()) {
-            case DataBuffer.TYPE_BYTE:
-                byte bdata[];
-                if (obj == null) {
-                    bdata = new byte[1];
-                } else {
-                    bdata = (byte[])obj;
-                }
-                bdata[0] = (byte)getSample(x, y, 0, data);
-                obj = bdata;
-                break;
-            case DataBuffer.TYPE_USHORT:
-                short sdata[];
-                if (obj == null) {
-                    sdata = new short[1];
-                } else {
-                    sdata = (short[])obj;
-                }
-                sdata[0] = (short)getSample(x, y, 0, data);
-                obj = sdata;
-                break;
-            case DataBuffer.TYPE_INT:
-                int idata[];
-                if (obj == null) {
-                    idata = new int[1];
-                } else {
-                    idata = (int[])obj;
-                }
-                idata[0] = getSample(x, y, 0, data);
-                obj = idata;
-                break;
-        }
-
-        return obj;
-    }
-
-    @Override
-    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
-        setSample(x, y, obj, data, 1, 0);
-    }
-
-    /**
-     * Compares this MultiPixelPackedSampleModel object with the specified
-     * object.
-     * 
-     * @param o
-     *            the Object to be compared.
-     * @return true, if the object is a MultiPixelPackedSampleModel with the
-     *         same data parameter values as this MultiPixelPackedSampleModel,
-     *         false otherwise.
-     */
-    @Override
-    public boolean equals(Object o) {
-        if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
-            return false;
-        }
-
-        MultiPixelPackedSampleModel model = (MultiPixelPackedSampleModel)o;
-        return this.width == model.width && this.height == model.height
-                && this.numBands == model.numBands && this.dataType == model.dataType
-                && this.pixelBitStride == model.pixelBitStride && this.bitMask == model.bitMask
-                && this.pixelsPerDataElement == model.pixelsPerDataElement
-                && this.dataElementSize == model.dataElementSize
-                && this.dataBitOffset == model.dataBitOffset
-                && this.scanlineStride == model.scanlineStride;
-    }
-
-    @Override
-    public SampleModel createSubsetSampleModel(int bands[]) {
-        if (bands != null && bands.length != 1) {
-            // awt.20F=Number of bands must be only 1
-            throw new RasterFormatException(Messages.getString("awt.20F")); //$NON-NLS-1$
-        }
-        return createCompatibleSampleModel(width, height);
-    }
-
-    @Override
-    public SampleModel createCompatibleSampleModel(int w, int h) {
-        return new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
-    }
-
-    @Override
-    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int pixel[];
-        if (iArray == null) {
-            pixel = new int[numBands];
-        } else {
-            pixel = iArray;
-        }
-
-        pixel[0] = getSample(x, y, 0, data);
-        return pixel;
-    }
-
-    @Override
-    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
-        setSample(x, y, iArray, data, 2, 0);
-    }
-
-    @Override
-    public int getSample(int x, int y, int b, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height || b != 0) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        int bitnum = dataBitOffset + x * pixelBitStride;
-        int elem = data.getElem(y * scanlineStride + bitnum / dataElementSize);
-        int shift = dataElementSize - (bitnum & (dataElementSize - 1)) - pixelBitStride;
-
-        return (elem >> shift) & bitMask;
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, int s, DataBuffer data) {
-        if (b != 0) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        setSample(x, y, null, data, 3, s);
-    }
-
-    @Override
-    public DataBuffer createDataBuffer() {
-        DataBuffer dataBuffer = null;
-        int size = scanlineStride * height;
-
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE:
-                dataBuffer = new DataBufferByte(size + (dataBitOffset + 7) / 8);
-                break;
-            case DataBuffer.TYPE_USHORT:
-                dataBuffer = new DataBufferUShort(size + (dataBitOffset + 15) / 16);
-                break;
-            case DataBuffer.TYPE_INT:
-                dataBuffer = new DataBufferInt(size + (dataBitOffset + 31) / 32);
-                break;
-        }
-        return dataBuffer;
-    }
-
-    /**
-     * Gets the offset of the specified pixel in the data array.
-     * 
-     * @param x
-     *            the X coordinate of the specified pixel.
-     * @param y
-     *            the Y coordinate of the specified pixel.
-     * @return the offset of the specified pixel.
-     */
-    public int getOffset(int x, int y) {
-        return y * scanlineStride + (x * pixelBitStride + dataBitOffset) / dataElementSize;
-    }
-
-    @Override
-    public int getSampleSize(int band) {
-        return pixelBitStride;
-    }
-
-    /**
-     * Gets the bit offset in the data element which is stored for the specified
-     * pixel of a scanline.
-     * 
-     * @param x
-     *            the pixel.
-     * @return the bit offset of the pixel in the data element.
-     */
-    public int getBitOffset(int x) {
-        return (x * pixelBitStride + dataBitOffset) % dataElementSize;
-    }
-
-    @Override
-    public int[] getSampleSize() {
-        int sampleSizes[] = {
-            pixelBitStride
-        };
-        return sampleSizes;
-    }
-
-    /**
-     * Returns a hash code of this MultiPixelPackedSampleModel class.
-     * 
-     * @return the hash code of this MultiPixelPackedSampleModel class.
-     */
-    @Override
-    public int hashCode() {
-        int hash = 0;
-        int tmp = 0;
-
-        hash = width;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= height;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= numBands;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= dataType;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= scanlineStride;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= pixelBitStride;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= dataBitOffset;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= bitMask;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= dataElementSize;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= pixelsPerDataElement;
-        return hash;
-    }
-
-    @Override
-    public int getTransferType() {
-        if (pixelBitStride > 16) {
-            return DataBuffer.TYPE_INT;
-        } else if (pixelBitStride > 8) {
-            return DataBuffer.TYPE_USHORT;
-        } else {
-            return DataBuffer.TYPE_BYTE;
-        }
-    }
-
-    /**
-     * Gets the scanline stride of this MultiPixelPackedSampleModel.
-     * 
-     * @return the scanline stride of this MultiPixelPackedSampleModel.
-     */
-    public int getScanlineStride() {
-        return scanlineStride;
-    }
-
-    /**
-     * Gets the pixel bit stride of this MultiPixelPackedSampleModel.
-     * 
-     * @return the pixel bit stride of this MultiPixelPackedSampleModel.
-     */
-    public int getPixelBitStride() {
-        return pixelBitStride;
-    }
-
-    @Override
-    public int getNumDataElements() {
-        return 1;
-    }
-
-    /**
-     * Gets the data bit offset.
-     * 
-     * @return the data bit offset.
-     */
-    public int getDataBitOffset() {
-        return dataBitOffset;
-    }
-
-    /**
-     * This method is used by other methods of this class. The behavior of this
-     * method depends on the method which has been invoke this one. The argument
-     * methodId is used to choose valid behavior in a particular case. If
-     * methodId is equal to 1 it means that this method has been invoked by the
-     * setDataElements() method, 2 - means setPixel(), and setSample() in any
-     * other cases.
-     * 
-     * @param x
-     *            the x.
-     * @param y
-     *            the y.
-     * @param obj
-     *            the obj.
-     * @param data
-     *            the data.
-     * @param methodId
-     *            the method id.
-     * @param s
-     *            the s.
-     */
-    private void setSample(final int x, final int y, final Object obj, final DataBuffer data,
-            final int methodId, int s) {
-        if ((x < 0) || (y < 0) || (x >= this.width) || (y >= this.height)) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        final int bitnum = dataBitOffset + x * pixelBitStride;
-        final int idx = y * scanlineStride + bitnum / dataElementSize;
-        final int shift = dataElementSize - (bitnum & (dataElementSize - 1)) - pixelBitStride;
-        final int mask = ~(bitMask << shift);
-        int elem = data.getElem(idx);
-
-        switch (methodId) {
-            case 1: { // Invoked from setDataElements()
-                switch (getTransferType()) {
-                    case DataBuffer.TYPE_BYTE:
-                        s = ((byte[])obj)[0] & 0xff;
-                        break;
-                    case DataBuffer.TYPE_USHORT:
-                        s = ((short[])obj)[0] & 0xffff;
-                        break;
-                    case DataBuffer.TYPE_INT:
-                        s = ((int[])obj)[0];
-                        break;
-                }
-                break;
-            }
-            case 2: { // Invoked from setPixel()
-                s = ((int[])obj)[0];
-                break;
-            }
-        }
-
-        elem &= mask;
-        elem |= (s & bitMask) << shift;
-        data.setElem(idx, elem);
-    }
-}
diff --git a/awt/java/awt/image/PackedColorModel.java b/awt/java/awt/image/PackedColorModel.java
deleted file mode 100644
index 4d1c2e5..0000000
--- a/awt/java/awt/image/PackedColorModel.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
-import java.util.Arrays;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The class PackedColorModel represents a color model where the components are
- * just the red, green, and blue bands, plus an alpha band if alpha is
- * supported.
- * 
- * @since Android 1.0
- */
-public abstract class PackedColorModel extends ColorModel {
-
-    /**
-     * The component masks.
-     */
-    int componentMasks[];
-
-    /**
-     * The offsets.
-     */
-    int offsets[];
-
-    /**
-     * The scales.
-     */
-    float scales[];
-
-    /**
-     * Instantiates a new packed color model.
-     * 
-     * @param space
-     *            the color space.
-     * @param bits
-     *            the array of component masks.
-     * @param colorMaskArray
-     *            the array that gives the bitmask corresponding to each color
-     *            band (red, green, and blue).
-     * @param alphaMask
-     *            the bitmask corresponding to the alpha band.
-     * @param isAlphaPremultiplied
-     *            whether the alpha is pre-multiplied in this color model.
-     * @param trans
-     *            the transparency strategy, @see java.awt.Transparency.
-     * @param transferType
-     *            the transfer type (primitive java type to use for the
-     *            components).
-     * @throws IllegalArgumentException
-     *             if the number of bits in the combined bitmasks for the color
-     *             bands is less than one or greater than 32.
-     */
-    public PackedColorModel(ColorSpace space, int bits, int colorMaskArray[], int alphaMask,
-            boolean isAlphaPremultiplied, int trans, int transferType) {
-
-        super(bits, createBits(colorMaskArray, alphaMask), space, (alphaMask == 0 ? false : true),
-                isAlphaPremultiplied, trans, validateTransferType(transferType));
-
-        if (pixel_bits < 1 || pixel_bits > 32) {
-            // awt.236=The bits is less than 1 or greater than 32
-            throw new IllegalArgumentException(Messages.getString("awt.236")); //$NON-NLS-1$
-        }
-
-        componentMasks = new int[numComponents];
-        for (int i = 0; i < numColorComponents; i++) {
-            componentMasks[i] = colorMaskArray[i];
-        }
-
-        if (hasAlpha) {
-            componentMasks[numColorComponents] = alphaMask;
-            if (this.bits[numColorComponents] == 1) {
-                transparency = Transparency.BITMASK;
-            }
-        }
-
-        parseComponents();
-    }
-
-    /**
-     * Instantiates a new packed color model.
-     * 
-     * @param space
-     *            the color space.
-     * @param bits
-     *            the array of component masks.
-     * @param rmask
-     *            the bitmask corresponding to the red band.
-     * @param gmask
-     *            the bitmask corresponding to the green band.
-     * @param bmask
-     *            the bitmask corresponding to the blue band.
-     * @param amask
-     *            the bitmask corresponding to the alpha band.
-     * @param isAlphaPremultiplied
-     *            whether the alpha is pre-multiplied in this color model.
-     * @param trans
-     *            the transparency strategy, @see java.awt.Transparency.
-     * @param transferType
-     *            the transfer type (primitive java type to use for the
-     *            components).
-     * @throws IllegalArgumentException
-     *             if the number of bits in the combined bitmasks for the color
-     *             bands is less than one or greater than 32.
-     */
-    public PackedColorModel(ColorSpace space, int bits, int rmask, int gmask, int bmask, int amask,
-            boolean isAlphaPremultiplied, int trans, int transferType) {
-
-        super(bits, createBits(rmask, gmask, bmask, amask), space, (amask == 0 ? false : true),
-                isAlphaPremultiplied, trans, validateTransferType(transferType));
-
-        if (pixel_bits < 1 || pixel_bits > 32) {
-            // awt.236=The bits is less than 1 or greater than 32
-            throw new IllegalArgumentException(Messages.getString("awt.236")); //$NON-NLS-1$
-        }
-
-        if (cs.getType() != ColorSpace.TYPE_RGB) {
-            // awt.239=The space is not a TYPE_RGB space
-            throw new IllegalArgumentException(Messages.getString("awt.239")); //$NON-NLS-1$
-        }
-
-        for (int i = 0; i < numColorComponents; i++) {
-            if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
-                // awt.23A=The min/max normalized component values are not
-                // 0.0/1.0
-                throw new IllegalArgumentException(Messages.getString("awt.23A")); //$NON-NLS-1$
-            }
-        }
-        componentMasks = new int[numComponents];
-        componentMasks[0] = rmask;
-        componentMasks[1] = gmask;
-        componentMasks[2] = bmask;
-
-        if (hasAlpha) {
-            componentMasks[3] = amask;
-            if (this.bits[3] == 1) {
-                transparency = Transparency.BITMASK;
-            }
-        }
-
-        parseComponents();
-    }
-
-    @Override
-    public WritableRaster getAlphaRaster(WritableRaster raster) {
-        if (!hasAlpha) {
-            return null;
-        }
-
-        int x = raster.getMinX();
-        int y = raster.getMinY();
-        int w = raster.getWidth();
-        int h = raster.getHeight();
-        int band[] = new int[1];
-        band[0] = raster.getNumBands() - 1;
-        return raster.createWritableChild(x, y, w, h, x, y, band);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (!(obj instanceof PackedColorModel)) {
-            return false;
-        }
-        PackedColorModel cm = (PackedColorModel)obj;
-
-        return (pixel_bits == cm.getPixelSize() && transferType == cm.getTransferType()
-                && cs.getType() == cm.getColorSpace().getType() && hasAlpha == cm.hasAlpha()
-                && isAlphaPremultiplied == cm.isAlphaPremultiplied()
-                && transparency == cm.getTransparency()
-                && numColorComponents == cm.getNumColorComponents()
-                && numComponents == cm.getNumComponents()
-                && Arrays.equals(bits, cm.getComponentSize()) && Arrays.equals(componentMasks, cm
-                .getMasks()));
-    }
-
-    @Override
-    public boolean isCompatibleSampleModel(SampleModel sm) {
-        if (sm == null) {
-            return false;
-        }
-        if (!(sm instanceof SinglePixelPackedSampleModel)) {
-            return false;
-        }
-        SinglePixelPackedSampleModel esm = (SinglePixelPackedSampleModel)sm;
-
-        return ((esm.getNumBands() == numComponents) && (esm.getTransferType() == transferType) && Arrays
-                .equals(esm.getBitMasks(), componentMasks));
-    }
-
-    @Override
-    public SampleModel createCompatibleSampleModel(int w, int h) {
-        return new SinglePixelPackedSampleModel(transferType, w, h, componentMasks);
-    }
-
-    /**
-     * Gets the bitmask corresponding to the specified color component.
-     * 
-     * @param index
-     *            the index of the desired color.
-     * @return the mask.
-     */
-    public final int getMask(int index) {
-        return componentMasks[index];
-    }
-
-    /**
-     * Gets the bitmasks of the components.
-     * 
-     * @return the masks.
-     */
-    public final int[] getMasks() {
-        return (componentMasks.clone());
-    }
-
-    /**
-     * Creates the bits.
-     * 
-     * @param colorMaskArray
-     *            the color mask array.
-     * @param alphaMask
-     *            the alpha mask.
-     * @return the int[].
-     */
-    private static int[] createBits(int colorMaskArray[], int alphaMask) {
-        int bits[];
-        int numComp;
-        if (alphaMask == 0) {
-            numComp = colorMaskArray.length;
-        } else {
-            numComp = colorMaskArray.length + 1;
-        }
-
-        bits = new int[numComp];
-        int i = 0;
-        for (; i < colorMaskArray.length; i++) {
-            bits[i] = countCompBits(colorMaskArray[i]);
-            if (bits[i] < 0) {
-                // awt.23B=The mask of the {0} component is not contiguous
-                throw new IllegalArgumentException(Messages.getString("awt.23B", i)); //$NON-NLS-1$
-            }
-        }
-
-        if (i < numComp) {
-            bits[i] = countCompBits(alphaMask);
-
-            if (bits[i] < 0) {
-                // awt.23C=The mask of the alpha component is not contiguous
-                throw new IllegalArgumentException(Messages.getString("awt.23C")); //$NON-NLS-1$
-            }
-        }
-
-        return bits;
-    }
-
-    /**
-     * Creates the bits.
-     * 
-     * @param rmask
-     *            the rmask.
-     * @param gmask
-     *            the gmask.
-     * @param bmask
-     *            the bmask.
-     * @param amask
-     *            the amask.
-     * @return the int[].
-     */
-    private static int[] createBits(int rmask, int gmask, int bmask, int amask) {
-
-        int numComp;
-        if (amask == 0) {
-            numComp = 3;
-        } else {
-            numComp = 4;
-        }
-        int bits[] = new int[numComp];
-
-        bits[0] = countCompBits(rmask);
-        if (bits[0] < 0) {
-            // awt.23D=The mask of the red component is not contiguous
-            throw new IllegalArgumentException(Messages.getString("awt.23D")); //$NON-NLS-1$
-        }
-
-        bits[1] = countCompBits(gmask);
-        if (bits[1] < 0) {
-            // awt.23E=The mask of the green component is not contiguous
-            throw new IllegalArgumentException(Messages.getString("awt.23E")); //$NON-NLS-1$
-        }
-
-        bits[2] = countCompBits(bmask);
-        if (bits[2] < 0) {
-            // awt.23F=The mask of the blue component is not contiguous
-            throw new IllegalArgumentException(Messages.getString("awt.23F")); //$NON-NLS-1$
-        }
-
-        if (amask != 0) {
-            bits[3] = countCompBits(amask);
-            if (bits[3] < 0) {
-                // awt.23C=The mask of the alpha component is not contiguous
-                throw new IllegalArgumentException(Messages.getString("awt.23C")); //$NON-NLS-1$
-            }
-        }
-
-        return bits;
-    }
-
-    /**
-     * Count comp bits.
-     * 
-     * @param compMask
-     *            the comp mask.
-     * @return the int.
-     */
-    private static int countCompBits(int compMask) {
-        int bits = 0;
-        if (compMask != 0) {
-            // Deleting final zeros
-            while ((compMask & 1) == 0) {
-                compMask >>>= 1;
-            }
-            // Counting component bits
-            while ((compMask & 1) == 1) {
-                compMask >>>= 1;
-                bits++;
-            }
-        }
-
-        if (compMask != 0) {
-            return -1;
-        }
-
-        return bits;
-    }
-
-    /**
-     * Validate transfer type.
-     * 
-     * @param transferType
-     *            the transfer type.
-     * @return the int.
-     */
-    private static int validateTransferType(int transferType) {
-        if (transferType != DataBuffer.TYPE_BYTE && transferType != DataBuffer.TYPE_USHORT
-                && transferType != DataBuffer.TYPE_INT) {
-            // awt.240=The transferType not is one of DataBuffer.TYPE_BYTE,
-            // DataBuffer.TYPE_USHORT or DataBuffer.TYPE_INT
-            throw new IllegalArgumentException(Messages.getString("awt.240")); //$NON-NLS-1$
-        }
-        return transferType;
-    }
-
-    /**
-     * Parses the components.
-     */
-    private void parseComponents() {
-        offsets = new int[numComponents];
-        scales = new float[numComponents];
-        for (int i = 0; i < numComponents; i++) {
-            int off = 0;
-            int mask = componentMasks[i];
-            while ((mask & 1) == 0) {
-                mask >>>= 1;
-                off++;
-            }
-            offsets[i] = off;
-            if (bits[i] == 0) {
-                scales[i] = 256.0f; // May be any value different from zero,
-                // because will dividing by zero
-            } else {
-                scales[i] = 255.0f / maxValues[i];
-            }
-        }
-
-    }
-
-}
diff --git a/awt/java/awt/image/PixelGrabber.java b/awt/java/awt/image/PixelGrabber.java
deleted file mode 100644
index cecd5c8..0000000
--- a/awt/java/awt/image/PixelGrabber.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-package java.awt.image;
-
-import java.awt.Image;
-import java.util.Hashtable;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-public class PixelGrabber implements ImageConsumer {
-
-    int width;
-    int height;
-    int X;
-    int Y;
-    int offset;
-    int scanline;
-    ImageProducer producer;
-
-    byte bData[];
-    int iData[];
-    ColorModel cm;
-
-    private int grabberStatus;
-    private int dataType;
-    private boolean isGrabbing;
-    private boolean isRGB;
-
-
-    private static final int DATA_TYPE_BYTE = 0;
-    private static final int DATA_TYPE_INT = 1;
-    private static final int DATA_TYPE_UNDEFINED = 2;
-
-    private static final int ALL_BITS = (ImageObserver.FRAMEBITS |
-            ImageObserver.ALLBITS);
-
-    private static final int GRABBING_STOP = ALL_BITS | ImageObserver.ERROR;
-
-
-
-    public PixelGrabber(ImageProducer ip, int x, int y, int w, int h, int[] pix,
-            int off, int scansize) {
-        initialize(ip, x, y, w, h, pix, off, scansize, true);
-    }
-
-    public PixelGrabber(Image img, int x, int y, int w, int h, int[] pix,
-            int off, int scansize) {
-        initialize(img.getSource(), x, y, w, h, pix, off, scansize, true);
-    }
-
-    public PixelGrabber(Image img, int x, int y, int w, int h, boolean forceRGB) {
-        initialize(img.getSource(), x, y, w, h, null, 0, 0, forceRGB);
-    }
-
-    public void setProperties(Hashtable<?, ?> props) {
-        return;
-    }
-
-    public synchronized Object getPixels() {
-        switch(dataType){
-        case DATA_TYPE_BYTE:
-            return bData;
-        case DATA_TYPE_INT:
-            return iData;
-        default:
-            return null;
-        }
-    }
-
-    public void setColorModel(ColorModel model) {
-        return;
-    }
-
-    public void setPixels(int srcX, int srcY, int srcW, int srcH,
-            ColorModel model, byte[] pixels, int srcOff, int srcScan) {
-        if(srcY < Y){
-            int delta = Y - srcY;
-            if(delta >= height) {
-                return;
-            }
-            srcY += delta;
-            srcH -= delta;
-            srcOff += srcScan * delta;
-        }
-
-        if(srcY + srcH > Y + height){
-            srcH = Y + height - srcY;
-            if(srcH <= 0) {
-                return;
-            }
-        }
-
-        if(srcX < X){
-            int delta = X - srcX;
-            if(delta >= width) {
-                return;
-            }
-            srcW -= delta;
-            srcX += delta;
-            srcOff += delta;
-        }
-
-        if(srcX + srcW > X + width){
-            srcW = X + width - srcX;
-            if(srcW <= 0) {
-                return;
-            }
-        }
-        if(scanline == 0) {
-            scanline = width;
-        }
-        int realOff = offset + (srcY - Y) * scanline + (srcX - X);
-        switch(dataType){
-        case DATA_TYPE_UNDEFINED:
-            cm = model;
-            if(model != ColorModel.getRGBdefault()){
-                bData = new byte[width * height];
-                isRGB = false;
-                dataType = DATA_TYPE_BYTE;
-            }else{
-                iData = new int[width * height];
-                isRGB = true;
-                dataType = DATA_TYPE_INT;
-            }
-        case DATA_TYPE_BYTE:
-            if(!isRGB && cm == model){
-                for(int y = 0; y < srcH; y++){
-                    System.arraycopy(pixels, srcOff, bData, realOff, srcW);
-                    srcOff += srcScan;
-                    realOff += scanline;
-                }
-                break;
-            }
-            forceToRGB();
-        case DATA_TYPE_INT:
-            for(int y = 0; y < srcH; y++){
-                for(int x = 0; x < srcW; x++){
-                    iData[realOff + x] = cm.getRGB(pixels[srcOff + x] & 0xff);                    
-                }
-                srcOff += srcScan;
-                realOff += scanline;
-            }
-        }
-
-        return;
-    }
-
-    public void setPixels(int srcX, int srcY, int srcW, int srcH,
-            ColorModel model, int[] pixels, int srcOff, int srcScan) {
-
-        if(srcY < Y){
-            int delta = Y - srcY;
-            if(delta >= height) {
-                return;
-            }
-            srcY += delta;
-            srcH -= delta;
-            srcOff += srcScan * delta;
-        }
-
-        if(srcY + srcH > Y + height){
-            srcH = Y + height - srcY;
-            if(srcH <= 0) {
-                return;
-            }
-        }
-
-        if(srcX < X){
-            int delta = X - srcX;
-            if(delta >= width) {
-                return;
-            }
-            srcW -= delta;
-            srcX += delta;
-            srcOff += delta;
-        }
-
-        if(srcX + srcW > X + width){
-            srcW = X + width - srcX;
-            if(srcW <= 0) {
-                return;
-            }
-        }
-        if(scanline == 0) {
-            scanline = width;
-        }
-        int realOff = offset + (srcY - Y) * scanline + (srcX - X);
-
-        int mask = 0xFF;
-
-        switch(dataType){
-        case DATA_TYPE_UNDEFINED:
-            cm = model;
-            iData = new int[width * height];
-            dataType = DATA_TYPE_INT;
-            isRGB = (cm == ColorModel.getRGBdefault());
-
-        case DATA_TYPE_INT:
-            if(cm == model){
-                for(int y = 0; y < srcH; y++){
-                    System.arraycopy(pixels, srcOff, iData, realOff, srcW);
-                    srcOff += srcScan;
-                    realOff += scanline;
-                }
-                break;
-            }
-            mask = 0xFFFFFFFF;
-
-        case DATA_TYPE_BYTE:
-            forceToRGB();
-            for(int y = 0; y < srcH; y++){
-                for(int x = 0; x < srcW; x++){
-                    iData[realOff+x] = cm.getRGB(pixels[srcOff+x] & mask);
-                }
-                srcOff += srcScan;
-                realOff += scanline;
-            }
-        }
-    }
-
-    public synchronized ColorModel getColorModel() {
-        return cm;
-    }
-
-    public synchronized boolean grabPixels(long ms) 
-    throws InterruptedException {
-        if((grabberStatus & GRABBING_STOP) != 0){
-            return ((grabberStatus & ALL_BITS) != 0);
-        }
-
-        long start = System.currentTimeMillis();
-
-        if(!isGrabbing){
-            isGrabbing = true;
-            grabberStatus &= ~ImageObserver.ABORT;
-            producer.startProduction(this);
-        }
-        while((grabberStatus & GRABBING_STOP) == 0){
-            if(ms != 0){
-                ms = start + ms - System.currentTimeMillis();
-                if(ms <= 0) {
-                    break;
-                }
-            }
-            wait(ms);
-        }
-
-        return ((grabberStatus & ALL_BITS) != 0);
-    }
-
-    public void setDimensions(int w, int h) {
-        if(width < 0) {
-            width = w - X;
-        }
-        if(height < 0) {
-            height = h - Y;
-        }
-
-        grabberStatus |= ImageObserver.WIDTH | ImageObserver.HEIGHT;
-
-        if(width <=0 || height <=0){
-            imageComplete(STATICIMAGEDONE);
-            return;
-        }
-
-        if(isRGB && dataType == DATA_TYPE_UNDEFINED){
-            iData = new int[width * height];
-            dataType = DATA_TYPE_INT;
-            scanline = width;
-        }
-    }
-
-    public void setHints(int hints) {
-        return;
-    }
-
-    public synchronized void imageComplete(int status) {
-        switch(status){
-        case IMAGEABORTED:
-            grabberStatus |= ImageObserver.ABORT;
-            break;
-        case IMAGEERROR:
-            grabberStatus |= ImageObserver.ERROR | ImageObserver.ABORT;
-            break;
-        case SINGLEFRAMEDONE:
-            grabberStatus |= ImageObserver.FRAMEBITS;
-            break;
-        case STATICIMAGEDONE:
-            grabberStatus |= ImageObserver.ALLBITS;
-            break;
-        default:
-            // awt.26A=Incorrect ImageConsumer completion status
-            throw new IllegalArgumentException(Messages.getString("awt.26A")); //$NON-NLS-1$
-        }
-        isGrabbing = false;
-        producer.removeConsumer(this);
-        notifyAll();
-    }
-
-    public boolean grabPixels() throws InterruptedException {
-        return grabPixels(0);
-    }
-
-    public synchronized void startGrabbing() {
-        if((grabberStatus & GRABBING_STOP) != 0){
-            return;
-        }
-        if(!isGrabbing){
-            isGrabbing = true;
-            grabberStatus &= ~ImageObserver.ABORT;
-            producer.startProduction(this);
-        }
-    }
-
-    public synchronized void abortGrabbing() {
-        imageComplete(IMAGEABORTED);
-    }
-
-    public synchronized int status() {
-        return grabberStatus;
-    }
-
-    public synchronized int getWidth() {
-        if(width < 0) {
-            return -1;
-        }
-        return width;
-    }
-
-    public synchronized int getStatus() {
-        return grabberStatus;
-    }
-
-    public synchronized int getHeight() {
-        if(height < 0) {
-            return -1;
-        }
-        return height;
-    }
-
-    private void initialize(ImageProducer ip, int x, int y, int w, int h,
-            int pixels[], int off, int scansize, boolean forceRGB){
-
-        producer = ip;
-        X = x;
-        Y = y;
-        width = w;
-        height = h;
-        iData = pixels;
-        dataType = (pixels == null) ? DATA_TYPE_UNDEFINED : DATA_TYPE_INT;
-        offset = off;
-        scanline = scansize;
-        if(forceRGB){
-            cm = ColorModel.getRGBdefault();
-            isRGB = true;
-        }
-    }
-
-    /**
-     * Force pixels to INT RGB mode
-     */
-    private void forceToRGB(){
-        if (isRGB)
-            return;
-    
-        switch(dataType){
-        case DATA_TYPE_BYTE:
-            iData = new int[width * height];
-            for(int i = 0; i < iData.length; i++){
-                iData[i] = cm.getRGB(bData[i] & 0xff);
-            }
-            dataType = DATA_TYPE_INT;
-            bData = null;
-            break;
-
-        case DATA_TYPE_INT:
-            int buff[] = new int[width * height];
-            for(int i = 0; i < iData.length; i++){
-                buff[i] = cm.getRGB(iData[i]);
-            }
-            iData = buff;
-            break;
-        }
-        offset = 0;
-        scanline = width;
-        cm = ColorModel.getRGBdefault();
-        isRGB = true;
-    }
-
-}
diff --git a/awt/java/awt/image/PixelInterleavedSampleModel.java b/awt/java/awt/image/PixelInterleavedSampleModel.java
deleted file mode 100644
index 8e646f8..0000000
--- a/awt/java/awt/image/PixelInterleavedSampleModel.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The PixelInterleavedSampleModel class represents image data as represented as
- * interleaved pixels and for which each sample of a pixel takes one data
- * element of the DataBuffer.
- * 
- * @since Android 1.0
- */
-public class PixelInterleavedSampleModel extends ComponentSampleModel {
-
-    /**
-     * Instantiates a new PixelInterleavedSampleModel with the specified
-     * parameters.
-     * 
-     * @param dataType
-     *            the data type of the samples.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param pixelStride
-     *            the pixel stride of the image data.
-     * @param scanlineStride
-     *            the scanline stride of the of the image data.
-     * @param bandOffsets
-     *            the array of the band offsets.
-     */
-    public PixelInterleavedSampleModel(int dataType, int w, int h, int pixelStride,
-            int scanlineStride, int bandOffsets[]) {
-
-        super(dataType, w, h, pixelStride, scanlineStride, bandOffsets);
-
-        int maxOffset = bandOffsets[0];
-        int minOffset = bandOffsets[0];
-        for (int i = 1; i < bandOffsets.length; i++) {
-            if (bandOffsets[i] > maxOffset) {
-                maxOffset = bandOffsets[i];
-            }
-            if (bandOffsets[i] < minOffset) {
-                minOffset = bandOffsets[i];
-            }
-        }
-
-        maxOffset -= minOffset;
-
-        if (maxOffset > scanlineStride) {
-            // awt.241=Any offset between bands is greater than the Scanline
-            // stride
-            throw new IllegalArgumentException(Messages.getString("awt.241")); //$NON-NLS-1$
-        }
-
-        if (maxOffset > pixelStride) {
-            // awt.242=Pixel stride is less than any offset between bands
-            throw new IllegalArgumentException(Messages.getString("awt.242")); //$NON-NLS-1$
-        }
-
-        if (pixelStride * w > scanlineStride) {
-            // awt.243=Product of Pixel stride and w is greater than Scanline
-            // stride
-            throw new IllegalArgumentException(Messages.getString("awt.243")); //$NON-NLS-1$
-        }
-
-    }
-
-    @Override
-    public SampleModel createSubsetSampleModel(int bands[]) {
-        int newOffsets[] = new int[bands.length];
-        for (int i = 0; i < bands.length; i++) {
-            newOffsets[i] = bandOffsets[bands[i]];
-        }
-
-        return new PixelInterleavedSampleModel(dataType, width, height, pixelStride,
-                scanlineStride, newOffsets);
-    }
-
-    @Override
-    public SampleModel createCompatibleSampleModel(int w, int h) {
-        int newOffsets[];
-        int minOffset = bandOffsets[0];
-
-        for (int i = 1; i < numBands; i++) {
-            if (bandOffsets[i] < minOffset) {
-                minOffset = bandOffsets[i];
-            }
-        }
-
-        if (minOffset > 0) {
-            newOffsets = new int[numBands];
-            for (int i = 0; i < numBands; i++) {
-                newOffsets[i] = bandOffsets[i] - minOffset;
-            }
-        } else {
-            newOffsets = bandOffsets;
-        }
-
-        return new PixelInterleavedSampleModel(dataType, w, h, pixelStride, pixelStride * w,
-                newOffsets);
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = super.hashCode();
-        int tmp = hash >>> 8;
-        hash <<= 8;
-        hash |= tmp;
-
-        return hash ^ 0x66;
-    }
-
-}
diff --git a/awt/java/awt/image/RGBImageFilter.java b/awt/java/awt/image/RGBImageFilter.java
deleted file mode 100644
index f5fe5d9..0000000
--- a/awt/java/awt/image/RGBImageFilter.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-/**
- * The RGBImageFilter class represents a filter which modifies pixels of an
- * image in the default RGB ColorModel.
- * 
- * @since Android 1.0
- */
-public abstract class RGBImageFilter extends ImageFilter {
-
-    /**
-     * The original model is the ColorModel to be replaced by the new model when
-     * substituteColorModel is called.
-     */
-    protected ColorModel origmodel;
-
-    /**
-     * The new model is the ColorModel with which to replace the original model
-     * when substituteColorModel is called.
-     */
-    protected ColorModel newmodel;
-
-    /**
-     * The canFilterIndexColorModel indicates if it is acceptable to apply the
-     * color filtering of the filterRGB method to the color table entries of an
-     * IndexColorModel object.
-     */
-    protected boolean canFilterIndexColorModel;
-
-    /**
-     * Instantiates a new RGBImageFilter.
-     */
-    public RGBImageFilter() {
-    }
-
-    /**
-     * Filters an IndexColorModel object by calling filterRGB function for each
-     * entry of IndexColorModel.
-     * 
-     * @param icm
-     *            the IndexColorModel to be filtered.
-     * @return the IndexColorModel.
-     */
-    public IndexColorModel filterIndexColorModel(IndexColorModel icm) {
-        int transferType = icm.getTransferType();
-        int bits = icm.getPixelSize();
-        int mapSize = icm.getMapSize();
-        int colorMap[] = new int[mapSize];
-        int filteredColorMap[] = new int[mapSize];
-        icm.getRGBs(colorMap);
-        int trans = -1;
-        boolean hasAlpha = false;
-        for (int i = 0; i < mapSize; i++) {
-            filteredColorMap[i] = filterRGB(-1, -1, colorMap[i]);
-            int alpha = filteredColorMap[i] >>> 24;
-            if (alpha != 0xff) {
-                if (!hasAlpha) {
-                    hasAlpha = true;
-                }
-                if (alpha == 0 && trans < 0) {
-                    trans = i;
-                }
-            }
-        }
-
-        return new IndexColorModel(bits, mapSize, filteredColorMap, 0, hasAlpha, trans,
-                transferType);
-    }
-
-    /**
-     * Replaces the original color model and the new one.
-     * 
-     * @param oldcm
-     *            the old ColorModel.
-     * @param newcm
-     *            the new ColorModel.
-     */
-    public void substituteColorModel(ColorModel oldcm, ColorModel newcm) {
-        origmodel = oldcm;
-        newmodel = newcm;
-    }
-
-    @Override
-    public void setColorModel(ColorModel model) {
-        if (model instanceof IndexColorModel && canFilterIndexColorModel) {
-            IndexColorModel icm = (IndexColorModel)model;
-            ColorModel filteredModel = filterIndexColorModel(icm);
-            substituteColorModel(model, filteredModel);
-            consumer.setColorModel(filteredModel);
-        } else {
-            consumer.setColorModel(ColorModel.getRGBdefault());
-        }
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
-            int scansize) {
-
-        if (model == null || model == origmodel) {
-            consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
-        } else {
-            int rgbPixels[] = new int[w];
-            for (int sy = y, pixelsOff = off; sy < y + h; sy++, pixelsOff += scansize) {
-
-                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
-                    rgbPixels[idx] = model.getRGB(pixels[pixelsOff + idx]);
-                }
-                filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w);
-            }
-        }
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
-            int scansize) {
-
-        if (model == null || model == origmodel) {
-            consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
-        } else {
-            int rgbPixels[] = new int[w];
-            for (int sy = y, pixelsOff = off; sy < y + h; sy++, pixelsOff += scansize) {
-
-                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
-                    rgbPixels[idx] = model.getRGB(pixels[pixelsOff + idx] & 0xff);
-                }
-                filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w);
-            }
-        }
-    }
-
-    /**
-     * Filters a region of pixels in the default RGB ColorModel by calling the
-     * filterRGB method for them.
-     * 
-     * @param x
-     *            the X coordinate of region.
-     * @param y
-     *            the Y coordinate of region.
-     * @param w
-     *            the width of region.
-     * @param h
-     *            the height of region.
-     * @param pixels
-     *            the pixels array.
-     * @param off
-     *            the offset of array.
-     * @param scansize
-     *            the distance between rows of pixels in the array.
-     */
-    public void filterRGBPixels(int x, int y, int w, int h, int[] pixels, int off, int scansize) {
-
-        for (int sy = y, lineOff = off; sy < y + h; sy++, lineOff += scansize) {
-            for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
-                pixels[lineOff + idx] = filterRGB(sx, sy, pixels[lineOff + idx]);
-            }
-        }
-        consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, off, scansize);
-    }
-
-    /**
-     * Converts a single input pixel in the default RGB ColorModel to a single
-     * output pixel.
-     * 
-     * @param x
-     *            the X pixel's coordinate.
-     * @param y
-     *            the Y pixel's coordinate.
-     * @param rgb
-     *            a pixel in the default RGB color model.
-     * @return a filtered pixel in the default RGB color model.
-     */
-    public abstract int filterRGB(int x, int y, int rgb);
-
-}
diff --git a/awt/java/awt/image/Raster.java b/awt/java/awt/image/Raster.java
deleted file mode 100644
index 6749fde..0000000
--- a/awt/java/awt/image/Raster.java
+++ /dev/null
@@ -1,1515 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-
-import org.apache.harmony.awt.gl.image.OrdinaryWritableRaster;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Raster class represents a rectangular area of pixels. This class is
- * defined by DataBuffer and SampleModel objects. The DataBuffer object stores
- * sample values and DSampleModel defines the location of sample in this
- * DataBuffer.
- * 
- * @since Android 1.0
- */
-public class Raster {
-
-    /**
-     * The DataBuffer of this Raster.
-     */
-    protected DataBuffer dataBuffer;
-
-    /**
-     * The height of this Raster.
-     */
-    protected int height;
-
-    /**
-     * The X coordinate of the upper left pixel in this Raster.
-     */
-    protected int minX;
-
-    /**
-     * The Y coordinate of the upper left pixel in this Raster.
-     */
-    protected int minY;
-
-    /**
-     * The number of bands in this Raster.
-     */
-    protected int numBands;
-
-    /**
-     * The number of data elements.
-     */
-    protected int numDataElements;
-
-    /**
-     * The parent of this Raster.
-     */
-    protected Raster parent;
-
-    /**
-     * The SampleModel of this Raster.
-     */
-    protected SampleModel sampleModel;
-
-    /**
-     * The X translation from the coordinate space of the SampleModel of this
-     * Raster.
-     */
-    protected int sampleModelTranslateX;
-
-    /**
-     * The Y translation from the coordinate space of the SampleModel of this
-     * Raster.
-     */
-    protected int sampleModelTranslateY;
-
-    /**
-     * The width of this Raster.
-     */
-    protected int width;
-
-    /**
-     * Creates a Raster object with a BandedSampleModel and the specified
-     * DataBuffer. The number of bands is defined by the length of bandOffsets
-     * or bankIndices arrays.
-     * 
-     * @param dataBuffer
-     *            the specified DataBuffer.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param scanlineStride
-     *            the scanline stride of the image data.
-     * @param bankIndices
-     *            the bank indices of bands.
-     * @param bandOffsets
-     *            the band offsets of bands.
-     * @param location
-     *            the location which defines the upper left corner of Raster.
-     * @return the WritableRaster object.
-     */
-    public static WritableRaster createBandedRaster(DataBuffer dataBuffer, int w, int h,
-            int scanlineStride, int bankIndices[], int bandOffsets[], Point location) {
-
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
-            // awt.276=location.x + w or location.y + h results in integer
-            // overflow
-            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
-        }
-
-        if (bankIndices == null || bandOffsets == null) {
-            // awt.277=bankIndices or bandOffsets is null
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.277")); //$NON-NLS-1$
-        }
-
-        if (dataBuffer == null) {
-            // awt.278=dataBuffer is null
-            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
-        }
-
-        int dataType = dataBuffer.getDataType();
-
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
-                && dataType != DataBuffer.TYPE_INT) {
-            // awt.230=dataType is not one of the supported data types
-            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
-        }
-
-        BandedSampleModel sampleModel = new BandedSampleModel(dataType, w, h, scanlineStride,
-                bankIndices, bandOffsets);
-
-        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
-    }
-
-    /**
-     * Creates a Raster object with a BandedSampleModel and the specified data
-     * type. The Data type can be one of the following values: TYPE_BYTE,
-     * TYPE_USHORT, or TYPE_INT.
-     * 
-     * @param dataType
-     *            the data type of the samples: TYPE_BYTE, TYPE_USHORT, or
-     *            TYPE_INT.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param scanlineStride
-     *            the scanline stride of the image data.
-     * @param bankIndices
-     *            the bank indices of bands.
-     * @param bandOffsets
-     *            the band offsets of bands.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster object.
-     */
-    public static WritableRaster createBandedRaster(int dataType, int w, int h, int scanlineStride,
-            int bankIndices[], int bandOffsets[], Point location) {
-
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
-            // awt.276=location.x + w or location.y + h results in integer
-            // overflow
-            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
-        }
-
-        if (bankIndices == null || bandOffsets == null) {
-            // awt.277=bankIndices or bandOffsets is null
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.277")); //$NON-NLS-1$
-        }
-
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
-                && dataType != DataBuffer.TYPE_INT) {
-            // awt.230=dataType is not one of the supported data types
-            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
-        }
-
-        int maxOffset = bandOffsets[0];
-        int maxBank = bankIndices[0];
-
-        for (int i = 0; i < bankIndices.length; i++) {
-            if (bandOffsets[i] > maxOffset) {
-                maxOffset = bandOffsets[i];
-            }
-            if (bankIndices[i] > maxBank) {
-                maxBank = bankIndices[i];
-            }
-        }
-
-        int numBanks = maxBank + 1;
-        int dataSize = scanlineStride * (h - 1) + w + maxOffset;
-
-        DataBuffer data = null;
-
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE:
-                data = new DataBufferByte(dataSize, numBanks);
-                break;
-            case DataBuffer.TYPE_USHORT:
-                data = new DataBufferUShort(dataSize, numBanks);
-                break;
-            case DataBuffer.TYPE_INT:
-                data = new DataBufferInt(dataSize, numBanks);
-                break;
-        }
-        return createBandedRaster(data, w, h, scanlineStride, bankIndices, bandOffsets, location);
-    }
-
-    /**
-     * Creates a Raster object with a BandedSampleModel and the specified data
-     * type. The Data type can be one of the following values: TYPE_BYTE,
-     * TYPE_USHORT, or TYPE_INT.
-     * 
-     * @param dataType
-     *            the data type of the samples: TYPE_BYTE, TYPE_USHORT, or
-     *            TYPE_INT.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param bands
-     *            the number of bands.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster object.
-     */
-    public static WritableRaster createBandedRaster(int dataType, int w, int h, int bands,
-            Point location) {
-
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
-            // awt.276=location.x + w or location.y + h results in integer
-            // overflow
-            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
-        }
-
-        if (bands < 1) {
-            // awt.279=bands is less than 1
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.279")); //$NON-NLS-1$
-        }
-
-        int bandOffsets[] = new int[bands];
-        int bankIndices[] = new int[bands];
-
-        for (int i = 0; i < bands; i++) {
-            bandOffsets[i] = 0;
-            bankIndices[i] = i;
-        }
-        return createBandedRaster(dataType, w, h, w, bankIndices, bandOffsets, location);
-    }
-
-    /**
-     * Creates a Raster object with a PixelInterleavedSampleModel and the
-     * specified DataBuffer.
-     * 
-     * @param dataBuffer
-     *            the DataBuffer.
-     * @param w
-     *            the width of image data.
-     * @param h
-     *            the height of image data.
-     * @param scanlineStride
-     *            the scanline stride of the image data.
-     * @param pixelStride
-     *            the pixel stride of image data.
-     * @param bandOffsets
-     *            the band offsets of bands.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster object.
-     */
-    public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer, int w, int h,
-            int scanlineStride, int pixelStride, int bandOffsets[], Point location) {
-
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
-            // awt.276=location.x + w or location.y + h results in integer
-            // overflow
-            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
-        }
-
-        if (dataBuffer == null) {
-            // awt.278=dataBuffer is null
-            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
-        }
-
-        int dataType = dataBuffer.getDataType();
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT) {
-            // awt.230=dataType is not one of the supported data types
-            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
-        }
-
-        if (dataBuffer.getNumBanks() > 1) {
-            // awt.27A=dataBuffer has more than one bank
-            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
-        }
-
-        if (bandOffsets == null) {
-            // awt.27B=bandOffsets is null
-            throw new NullPointerException(Messages.getString("awt.27B")); //$NON-NLS-1$
-        }
-
-        PixelInterleavedSampleModel sampleModel = new PixelInterleavedSampleModel(dataType, w, h,
-                pixelStride, scanlineStride, bandOffsets);
-
-        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
-
-    }
-
-    /**
-     * Creates a Raster object with a PixelInterleavedSampleModel and the
-     * specified data type. The Data type can be one of the following values:
-     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT.
-     * 
-     * @param dataType
-     *            the data type of the samples: TYPE_BYTE, TYPE_USHORT, or
-     *            TYPE_INT.
-     * @param w
-     *            the width of image data.
-     * @param h
-     *            the height of image data.
-     * @param scanlineStride
-     *            the scanline stride of the image data.
-     * @param pixelStride
-     *            the pixel stride of image data.
-     * @param bandOffsets
-     *            the band offsets of bands.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster object.
-     */
-    public static WritableRaster createInterleavedRaster(int dataType, int w, int h,
-            int scanlineStride, int pixelStride, int bandOffsets[], Point location) {
-
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
-            // awt.276=location.x + w or location.y + h results in integer
-            // overflow
-            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
-        }
-
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT) {
-            // awt.230=dataType is not one of the supported data types
-            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
-        }
-
-        if (bandOffsets == null) {
-            // awt.27B=bandOffsets is null
-            throw new NullPointerException(Messages.getString("awt.27B")); //$NON-NLS-1$
-        }
-
-        int minOffset = bandOffsets[0];
-        for (int i = 1; i < bandOffsets.length; i++) {
-            if (bandOffsets[i] < minOffset) {
-                minOffset = bandOffsets[i];
-            }
-        }
-        int size = (h - 1) * scanlineStride + w * pixelStride + minOffset;
-        DataBuffer data = null;
-
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE:
-                data = new DataBufferByte(size);
-                break;
-            case DataBuffer.TYPE_USHORT:
-                data = new DataBufferUShort(size);
-                break;
-        }
-
-        return createInterleavedRaster(data, w, h, scanlineStride, pixelStride, bandOffsets,
-                location);
-    }
-
-    /**
-     * Creates a Raster object with a PixelInterleavedSampleModel and the
-     * specified data type. The Data type can be one of the following values:
-     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT.
-     * 
-     * @param dataType
-     *            the data type of samples: TYPE_BYTE, TYPE_USHORT, or TYPE_INT.
-     * @param w
-     *            the width of image data.
-     * @param h
-     *            the height of image data.
-     * @param bands
-     *            the number of bands.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster.
-     */
-    public static WritableRaster createInterleavedRaster(int dataType, int w, int h, int bands,
-            Point location) {
-
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
-            // awt.276=location.x + w or location.y + h results in integer
-            // overflow
-            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
-        }
-
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT) {
-            // awt.230=dataType is not one of the supported data types
-            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
-        }
-
-        int bandOffsets[] = new int[bands];
-        for (int i = 0; i < bands; i++) {
-            bandOffsets[i] = i;
-        }
-
-        return createInterleavedRaster(dataType, w, h, w * bands, bands, bandOffsets, location);
-    }
-
-    /**
-     * Creates a Raster object with a SinglePixelPackedSampleModel and the
-     * specified DataBuffer.
-     * 
-     * @param dataBuffer
-     *            the DataBuffer.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param scanlineStride
-     *            the scanline stride of the image data.
-     * @param bandMasks
-     *            the band masks.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster.
-     */
-    public static WritableRaster createPackedRaster(DataBuffer dataBuffer, int w, int h,
-            int scanlineStride, int bandMasks[], Point location) {
-        if (dataBuffer == null) {
-            // awt.278=dataBuffer is null
-            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
-        }
-
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
-            // awt.276=location.x + w or location.y + h results in integer
-            // overflow
-            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
-        }
-
-        if (bandMasks == null) {
-            // awt.27C=bandMasks is null
-            throw new RasterFormatException(Messages.getString("awt.27C")); //$NON-NLS-1$
-        }
-
-        if (dataBuffer.getNumBanks() > 1) {
-            // awt.27A=dataBuffer has more than one bank
-            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
-        }
-
-        int dataType = dataBuffer.getDataType();
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
-                && dataType != DataBuffer.TYPE_INT) {
-            // awt.230=dataType is not one of the supported data types
-            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
-        }
-
-        SinglePixelPackedSampleModel sampleModel = new SinglePixelPackedSampleModel(dataType, w, h,
-                scanlineStride, bandMasks);
-
-        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
-    }
-
-    /**
-     * Creates a Raster object with a MultiPixelPackedSampleModel and the
-     * specified DataBuffer.
-     * 
-     * @param dataBuffer
-     *            the DataBuffer.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param bitsPerPixel
-     *            the number of bits per pixel.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster.
-     */
-    public static WritableRaster createPackedRaster(DataBuffer dataBuffer, int w, int h,
-            int bitsPerPixel, Point location) {
-
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
-            // awt.276=location.x + w or location.y + h results in integer
-            // overflow
-            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
-        }
-
-        if (dataBuffer == null) {
-            // awt.278=dataBuffer is null
-            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
-        }
-
-        if (dataBuffer.getNumBanks() > 1) {
-            // awt.27A=dataBuffer has more than one bank
-            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
-        }
-
-        int dataType = dataBuffer.getDataType();
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
-                && dataType != DataBuffer.TYPE_INT) {
-            // awt.230=dataType is not one of the supported data types
-            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
-        }
-
-        MultiPixelPackedSampleModel sampleModel = new MultiPixelPackedSampleModel(dataType, w, h,
-                bitsPerPixel);
-
-        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
-
-    }
-
-    /**
-     * Creates a Raster object with a MultiPixelPackedSampleModel and the
-     * specified DataBuffer.
-     * 
-     * @param dataType
-     *            the data type of samples: TYPE_BYTE, TYPE_USHORT, or TYPE_INT.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param bands
-     *            the number of bands.
-     * @param bitsPerBand
-     *            the number of bits per band.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster.
-     */
-    public static WritableRaster createPackedRaster(int dataType, int w, int h, int bands,
-            int bitsPerBand, Point location) {
-
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
-            // awt.276=location.x + w or location.y + h results in integer
-            // overflow
-            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
-        }
-
-        if (bands < 1 || bitsPerBand < 1) {
-            // awt.27D=bitsPerBand or bands is not greater than zero
-            throw new IllegalArgumentException(Messages.getString("awt.27D")); //$NON-NLS-1$
-        }
-
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
-                && dataType != DataBuffer.TYPE_INT) {
-            // awt.230=dataType is not one of the supported data types
-            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
-        }
-
-        if (bitsPerBand * bands > DataBuffer.getDataTypeSize(dataType)) {
-            // awt.27E=The product of bitsPerBand and bands is greater than the
-            // number of bits held by dataType
-            throw new IllegalArgumentException(Messages.getString("awt.27E")); //$NON-NLS-1$
-        }
-
-        if (bands > 1) {
-
-            int bandMasks[] = new int[bands];
-            int mask = (1 << bitsPerBand) - 1;
-
-            for (int i = 0; i < bands; i++) {
-                bandMasks[i] = mask << (bitsPerBand * (bands - 1 - i));
-            }
-
-            return createPackedRaster(dataType, w, h, bandMasks, location);
-        }
-        DataBuffer data = null;
-        int size = ((bitsPerBand * w + DataBuffer.getDataTypeSize(dataType) - 1) / DataBuffer
-                .getDataTypeSize(dataType))
-                * h;
-
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE:
-                data = new DataBufferByte(size);
-                break;
-            case DataBuffer.TYPE_USHORT:
-                data = new DataBufferUShort(size);
-                break;
-            case DataBuffer.TYPE_INT:
-                data = new DataBufferInt(size);
-                break;
-        }
-        return createPackedRaster(data, w, h, bitsPerBand, location);
-    }
-
-    /**
-     * Creates a Raster object with a SinglePixelPackedSampleModel and the
-     * specified DataBuffer.
-     * 
-     * @param dataType
-     *            the data type of samples: TYPE_BYTE, TYPE_USHORT, or TYPE_INT.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param bandMasks
-     *            the band masks.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster.
-     */
-    public static WritableRaster createPackedRaster(int dataType, int w, int h, int bandMasks[],
-            Point location) {
-
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
-                && dataType != DataBuffer.TYPE_INT) {
-            // awt.230=dataType is not one of the supported data types
-            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
-        }
-
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
-            // awt.276=location.x + w or location.y + h results in integer
-            // overflow
-            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
-        }
-
-        if (bandMasks == null) {
-            // awt.27C=bandMasks is null
-            throw new NullPointerException(Messages.getString("awt.27C")); //$NON-NLS-1$
-        }
-
-        DataBuffer data = null;
-
-        switch (dataType) {
-            case DataBuffer.TYPE_BYTE:
-                data = new DataBufferByte(w * h);
-                break;
-            case DataBuffer.TYPE_USHORT:
-                data = new DataBufferUShort(w * h);
-                break;
-            case DataBuffer.TYPE_INT:
-                data = new DataBufferInt(w * h);
-                break;
-        }
-
-        return createPackedRaster(data, w, h, w, bandMasks, location);
-    }
-
-    /**
-     * Creates a Raster object with the specified DataBuffer and SampleModel.
-     * 
-     * @param sm
-     *            the specified SampleModel.
-     * @param db
-     *            the specified DataBuffer.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the Raster.
-     */
-    public static Raster createRaster(SampleModel sm, DataBuffer db, Point location) {
-
-        if (sm == null || db == null) {
-            // awt.27F=SampleModel or DataBuffer is null
-            throw new NullPointerException(Messages.getString("awt.27F")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        return new Raster(sm, db, location);
-    }
-
-    /**
-     * Creates a WritableRaster with the specified SampleModel and DataBuffer.
-     * 
-     * @param sm
-     *            the specified SampleModel.
-     * @param db
-     *            the specified DataBuffer.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster.
-     */
-    public static WritableRaster createWritableRaster(SampleModel sm, DataBuffer db, Point location) {
-
-        if (sm == null || db == null) {
-            // awt.27F=SampleModel or DataBuffer is null
-            throw new NullPointerException(Messages.getString("awt.27F")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        return new OrdinaryWritableRaster(sm, db, location);
-    }
-
-    /**
-     * Creates a WritableRaster with the specified SampleModel.
-     * 
-     * @param sm
-     *            the specified SampleModel.
-     * @param location
-     *            the location which defines the upper left corner of the
-     *            Raster.
-     * @return the WritableRaster.
-     */
-    public static WritableRaster createWritableRaster(SampleModel sm, Point location) {
-
-        if (sm == null) {
-            // awt.280=SampleModel is null
-            throw new NullPointerException(Messages.getString("awt.280")); //$NON-NLS-1$
-        }
-
-        if (location == null) {
-            location = new Point(0, 0);
-        }
-
-        return createWritableRaster(sm, sm.createDataBuffer(), location);
-    }
-
-    /**
-     * Instantiates a new Raster object with the specified SampleModel and
-     * DataBuffer.
-     * 
-     * @param sampleModel
-     *            the specified SampleModel.
-     * @param dataBuffer
-     *            the specified DataBuffer.
-     * @param origin
-     *            the specified origin.
-     */
-    protected Raster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin) {
-
-        this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y, sampleModel.getWidth(),
-                sampleModel.getHeight()), origin, null);
-    }
-
-    /**
-     * Instantiates a new Raster object with the specified SampleModel,
-     * DataBuffer, rectangular region and parent Raster.
-     * 
-     * @param sampleModel
-     *            the specified SampleModel.
-     * @param dataBuffer
-     *            the specified DataBuffer.
-     * @param aRegion
-     *            the a rectangular region which defines the new image bounds.
-     * @param sampleModelTranslate
-     *            this point defines the translation point from the SampleModel
-     *            coordinates to the new Raster coordinates.
-     * @param parent
-     *            the parent of this Raster.
-     */
-    protected Raster(SampleModel sampleModel, DataBuffer dataBuffer, Rectangle aRegion,
-            Point sampleModelTranslate, Raster parent) {
-
-        if (sampleModel == null || dataBuffer == null || aRegion == null
-                || sampleModelTranslate == null) {
-            // awt.281=sampleModel, dataBuffer, aRegion or sampleModelTranslate
-            // is null
-            throw new NullPointerException(Messages.getString("awt.281")); //$NON-NLS-1$
-        }
-
-        if (aRegion.width <= 0 || aRegion.height <= 0) {
-            // awt.282=aRegion has width or height less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.282")); //$NON-NLS-1$
-        }
-
-        if ((long)aRegion.x + (long)aRegion.width > Integer.MAX_VALUE) {
-            // awt.283=Overflow X coordinate of Raster
-            throw new RasterFormatException(Messages.getString("awt.283")); //$NON-NLS-1$
-        }
-
-        if ((long)aRegion.y + (long)aRegion.height > Integer.MAX_VALUE) {
-            // awt.284=Overflow Y coordinate of Raster
-            throw new RasterFormatException(Messages.getString("awt.284")); //$NON-NLS-1$
-        }
-
-        if (sampleModel instanceof ComponentSampleModel) {
-            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
-                    ((ComponentSampleModel)sampleModel).getScanlineStride());
-        } else if (sampleModel instanceof MultiPixelPackedSampleModel) {
-            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
-                    ((MultiPixelPackedSampleModel)sampleModel).getScanlineStride());
-        } else if (sampleModel instanceof SinglePixelPackedSampleModel) {
-            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
-                    ((SinglePixelPackedSampleModel)sampleModel).getScanlineStride());
-        }
-
-        this.sampleModel = sampleModel;
-        this.dataBuffer = dataBuffer;
-        this.minX = aRegion.x;
-        this.minY = aRegion.y;
-        this.width = aRegion.width;
-        this.height = aRegion.height;
-        this.sampleModelTranslateX = sampleModelTranslate.x;
-        this.sampleModelTranslateY = sampleModelTranslate.y;
-        this.parent = parent;
-        this.numBands = sampleModel.getNumBands();
-        this.numDataElements = sampleModel.getNumDataElements();
-
-    }
-
-    /**
-     * Instantiates a new Raster with the specified SampleModel.
-     * 
-     * @param sampleModel
-     *            the specified SampleModel.
-     * @param origin
-     *            the origin.
-     */
-    protected Raster(SampleModel sampleModel, Point origin) {
-        this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(origin.x, origin.y,
-                sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
-    }
-
-    /**
-     * Creates the child of this Raster by sharing the specified rectangular
-     * area in this raster. The parentX, parentY, width and height parameters
-     * specify the rectangular area to be shared.
-     * 
-     * @param parentX
-     *            the X coordinate of the upper left corner of this Raster.
-     * @param parentY
-     *            the Y coordinate of the upper left corner of this Raster.
-     * @param width
-     *            the width of the child area.
-     * @param height
-     *            the height of the child area.
-     * @param childMinX
-     *            the X coordinate of child area mapped to the parentX
-     *            coordinate.
-     * @param childMinY
-     *            the Y coordinate of child area mapped to the parentY
-     *            coordinate.
-     * @param bandList
-     *            the array of band indices.
-     * @return the Raster.
-     */
-    public Raster createChild(int parentX, int parentY, int width, int height, int childMinX,
-            int childMinY, int bandList[]) {
-        if (width <= 0 || height <= 0) {
-            // awt.285=Width or Height of child Raster is less than or equal to
-            // zero
-            throw new RasterFormatException(Messages.getString("awt.285")); //$NON-NLS-1$
-        }
-
-        if (parentX < this.minX || parentX + width > this.minX + this.width) {
-            // awt.286=parentX disposes outside Raster
-            throw new RasterFormatException(Messages.getString("awt.286")); //$NON-NLS-1$
-        }
-
-        if (parentY < this.minY || parentY + height > this.minY + this.height) {
-            // awt.287=parentY disposes outside Raster
-            throw new RasterFormatException(Messages.getString("awt.287")); //$NON-NLS-1$
-        }
-
-        if ((long)parentX + width > Integer.MAX_VALUE) {
-            // awt.288=parentX + width results in integer overflow
-            throw new RasterFormatException(Messages.getString("awt.288")); //$NON-NLS-1$
-        }
-
-        if ((long)parentY + height > Integer.MAX_VALUE) {
-            // awt.289=parentY + height results in integer overflow
-            throw new RasterFormatException(Messages.getString("awt.289")); //$NON-NLS-1$
-        }
-
-        if ((long)childMinX + width > Integer.MAX_VALUE) {
-            // awt.28A=childMinX + width results in integer overflow
-            throw new RasterFormatException(Messages.getString("awt.28A")); //$NON-NLS-1$
-        }
-
-        if ((long)childMinY + height > Integer.MAX_VALUE) {
-            // awt.28B=childMinY + height results in integer overflow
-            throw new RasterFormatException(Messages.getString("awt.28B")); //$NON-NLS-1$
-        }
-
-        SampleModel childModel;
-
-        if (bandList == null) {
-            childModel = sampleModel;
-        } else {
-            childModel = sampleModel.createSubsetSampleModel(bandList);
-        }
-
-        int childTranslateX = childMinX - parentX;
-        int childTranslateY = childMinY - parentY;
-
-        return new Raster(childModel, dataBuffer,
-                new Rectangle(childMinX, childMinY, width, height), new Point(childTranslateX
-                        + sampleModelTranslateX, childTranslateY + sampleModelTranslateY), this);
-    }
-
-    /**
-     * Create a compatible WritableRaster with the same parameters as this
-     * Raster.
-     * 
-     * @return the WritableRaster.
-     */
-    public WritableRaster createCompatibleWritableRaster() {
-        return new OrdinaryWritableRaster(sampleModel, new Point(0, 0));
-    }
-
-    /**
-     * Create a compatible WritableRaster with the same parameters as this
-     * Raster and the specified size.
-     * 
-     * @param w
-     *            the width of the new WritableRaster.
-     * @param h
-     *            the height of the new WritableRaster.
-     * @return the WritableRaster.
-     */
-    public WritableRaster createCompatibleWritableRaster(int w, int h) {
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
-
-        return new OrdinaryWritableRaster(sm, new Point(0, 0));
-    }
-
-    /**
-     * Create a compatible WritableRaster with the same parameters as this
-     * Raster and the specified size and location.
-     * 
-     * @param x
-     *            the X coordinate of the new WritableRaster.
-     * @param y
-     *            the Y coordinate of the new WritableRaster.
-     * @param w
-     *            the width of the new WritableRaster.
-     * @param h
-     *            the height of the new WritableRaster.
-     * @return the WritableRaster.
-     */
-    public WritableRaster createCompatibleWritableRaster(int x, int y, int w, int h) {
-
-        WritableRaster raster = createCompatibleWritableRaster(w, h);
-
-        return raster.createWritableChild(0, 0, w, h, x, y, null);
-    }
-
-    /**
-     * Create a compatible WritableRaster with the same parameters as this
-     * Raster and the specified rectangle which determines new WritableRaster's
-     * location and size.
-     * 
-     * @param rect
-     *            the specified Rectangle.
-     * @return the WritableRaster.
-     */
-    public WritableRaster createCompatibleWritableRaster(Rectangle rect) {
-        if (rect == null) {
-            // awt.28C=Rect is null
-            throw new NullPointerException(Messages.getString("awt.28C")); //$NON-NLS-1$
-        }
-
-        return createCompatibleWritableRaster(rect.x, rect.y, rect.width, rect.height);
-    }
-
-    /**
-     * Creates the translated child of this Raster. The New Raster object is a
-     * reference to the this Raster with a different location.
-     * 
-     * @param childMinX
-     *            the X coordinate of the new Raster.
-     * @param childMinY
-     *            the Y coordinate of the new Raster.
-     * @return the Raster.
-     */
-    public Raster createTranslatedChild(int childMinX, int childMinY) {
-        return createChild(minX, minY, width, height, childMinX, childMinY, null);
-    }
-
-    /**
-     * Gets the bounds of this Raster as a rectangle.
-     * 
-     * @return the bounds of this Raster.
-     */
-    public Rectangle getBounds() {
-        return new Rectangle(minX, minY, width, height);
-    }
-
-    /**
-     * Gets the DataBuffer associated with this Raster.
-     * 
-     * @return the DataBuffer associated with this Raster.
-     */
-    public DataBuffer getDataBuffer() {
-        return dataBuffer;
-    }
-
-    /**
-     * Gets the data elements which represent the pixel data of the specified
-     * rectangle area as a primitive array. The following image data types are
-     * supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
-     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
-     * DataBuffer.TYPE_DOUBLE.
-     * 
-     * @param x
-     *            the X coordinate of the area of pixels.
-     * @param y
-     *            the Y coordinate of the area of pixels.
-     * @param w
-     *            the width of the area of pixels.
-     * @param h
-     *            the height of the area of pixels.
-     * @param outData
-     *            the resulting array.
-     * @return the data elements of the specified area of this Raster.
-     */
-    public Object getDataElements(int x, int y, int w, int h, Object outData) {
-        return sampleModel.getDataElements(x - sampleModelTranslateX, y - sampleModelTranslateY, w,
-                h, outData, dataBuffer);
-    }
-
-    /**
-     * Gets the data elements which represent the specified pixel of this Raster
-     * as a primitive array. The following image data types are supported:
-     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
-     * DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param outData
-     *            the resulting data.
-     * @return the data elements of the specified pixel of this Raster.
-     */
-    public Object getDataElements(int x, int y, Object outData) {
-        return sampleModel.getDataElements(x - sampleModelTranslateX, y - sampleModelTranslateY,
-                outData, dataBuffer);
-    }
-
-    /**
-     * Gets the height of this Raster.
-     * 
-     * @return the height of this Raster.
-     */
-    public final int getHeight() {
-        return height;
-    }
-
-    /**
-     * Gets the minimum X coordinate of this Raster.
-     * 
-     * @return the minimum X coordinate of this Raster.
-     */
-    public final int getMinX() {
-        return minX;
-    }
-
-    /**
-     * Gets the minimum Y coordinate of this Raster.
-     * 
-     * @return the minimum Y coordinate of this Raster.
-     */
-    public final int getMinY() {
-        return minY;
-    }
-
-    /**
-     * Gets the number of bands in this Raster.
-     * 
-     * @return the number of bands in this Raster.
-     */
-    public final int getNumBands() {
-        return numBands;
-    }
-
-    /**
-     * Gets the number of data elements for one pixel.
-     * 
-     * @return the number of data elements for one pixel.
-     */
-    public final int getNumDataElements() {
-        return numDataElements;
-    }
-
-    /**
-     * Gets the parent Raster for this Raster object.
-     * 
-     * @return the parent Raster for this Raster object.
-     */
-    public Raster getParent() {
-        return parent;
-    }
-
-    /**
-     * Gets a double array of samples for the specified pixel in this Raster.
-     * 
-     * @param x
-     *            the pixel's X coordinate.
-     * @param y
-     *            the pixel's Y coordinate.
-     * @param dArray
-     *            the double array where result array will be stored.
-     * @return the double array of samples for the specified pixel in this
-     *         Raster.
-     */
-    public double[] getPixel(int x, int y, double dArray[]) {
-        return sampleModel.getPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, dArray,
-                dataBuffer);
-    }
-
-    /**
-     * Gets a float array of samples for the specified pixel in this Raster.
-     * 
-     * @param x
-     *            the pixel's X coordinate.
-     * @param y
-     *            the pixel's Y coordinate.
-     * @param fArray
-     *            the float array where the result array will be stored.
-     * @return the float array of samples for the specified pixel in this
-     *         Raster.
-     */
-    public float[] getPixel(int x, int y, float fArray[]) {
-        return sampleModel.getPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, fArray,
-                dataBuffer);
-    }
-
-    /**
-     * Gets an integer array of samples for the specified pixel in this Raster.
-     * 
-     * @param x
-     *            the pixel's X coordinate.
-     * @param y
-     *            the pixel's Y coordinate.
-     * @param iArray
-     *            the integer array where the result array will be stored.
-     * @return the integer array of samples for the specified pixel in this
-     *         Raster.
-     */
-    public int[] getPixel(int x, int y, int iArray[]) {
-        return sampleModel.getPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, iArray,
-                dataBuffer);
-    }
-
-    /**
-     * Gets an double array of samples for the specified rectangular area of
-     * pixels in this Raster.
-     * 
-     * @param x
-     *            the X coordinate of the area of pixels.
-     * @param y
-     *            the Y coordinate of the area of pixels.
-     * @param w
-     *            the width of the area of pixels.
-     * @param h
-     *            the height of the area of pixels.
-     * @param dArray
-     *            the resulting array.
-     * @return the double array of samples for the specified rectangular area of
-     *         pixels in this Raster.
-     */
-    public double[] getPixels(int x, int y, int w, int h, double dArray[]) {
-        return sampleModel.getPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
-                dArray, dataBuffer);
-    }
-
-    /**
-     * Gets an float array of samples for the specified rectangular area of
-     * pixels in this Raster.
-     * 
-     * @param x
-     *            the X coordinate of the area of pixels.
-     * @param y
-     *            the Y coordinate of the area of pixels.
-     * @param w
-     *            the width of the area of pixels.
-     * @param h
-     *            the height of the area of pixels.
-     * @param fArray
-     *            the resulting array.
-     * @return the float array of samples for the specified rectangular area of
-     *         pixels in this Raster.
-     */
-    public float[] getPixels(int x, int y, int w, int h, float fArray[]) {
-        return sampleModel.getPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
-                fArray, dataBuffer);
-    }
-
-    /**
-     * Gets an integer array of samples for the specified rectangular area of
-     * pixels in this raster.
-     * 
-     * @param x
-     *            the X coordinate of the area of pixels.
-     * @param y
-     *            the Y coordinate of the area of pixels.
-     * @param w
-     *            the width of pixel's the area of pixels.
-     * @param h
-     *            the height of pixel's the area of pixels.
-     * @param iArray
-     *            the resulting array.
-     * @return the integer array of samples for the specified rectangular area
-     *         of pixels in this Raster.
-     */
-    public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
-        return sampleModel.getPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
-                iArray, dataBuffer);
-    }
-
-    /**
-     * Gets the sample for the specified band of the specified pixel as an
-     * integer.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param b
-     *            the band.
-     * @return the sample for the specified band of the specified pixel as an
-     *         integer.
-     */
-    public int getSample(int x, int y, int b) {
-        return sampleModel.getSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b,
-                dataBuffer);
-    }
-
-    /**
-     * Gets the sample for the specified band of the specified pixel as a
-     * double.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param b
-     *            the band.
-     * @return the sample for the specified band of the specified pixel as a
-     *         double.
-     */
-    public double getSampleDouble(int x, int y, int b) {
-        return sampleModel.getSampleDouble(x - sampleModelTranslateX, y - sampleModelTranslateY, b,
-                dataBuffer);
-    }
-
-    /**
-     * Gets the sample for the specified band of the specified pixel as a float.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param b
-     *            the band.
-     * @return the sample for the specified band of the specified pixel as a
-     *         float.
-     */
-    public float getSampleFloat(int x, int y, int b) {
-        return sampleModel.getSampleFloat(x - sampleModelTranslateX, y - sampleModelTranslateY, b,
-                dataBuffer);
-    }
-
-    /**
-     * Gets the SampleModel associated with this Raster.
-     * 
-     * @return the SampleModel associated with this Raster.
-     */
-    public SampleModel getSampleModel() {
-        return sampleModel;
-    }
-
-    /**
-     * Gets the translation of the X coordinate from the SampleModel coordinate
-     * system to the Rasters's coordinate system.
-     * 
-     * @return the value of the translation of the X coordinate from the
-     *         SampleModel coordinate system to the Rasters's coordinate system.
-     */
-    public final int getSampleModelTranslateX() {
-        return sampleModelTranslateX;
-    }
-
-    /**
-     * Gets the translation of the Y coordinate from the SampleModel coordinate
-     * system to the Rasters's coordinate system.
-     * 
-     * @return the value of the translation of the Y coordinate from the
-     *         SampleModel coordinate system to the Rasters's coordinate system.
-     */
-    public final int getSampleModelTranslateY() {
-        return sampleModelTranslateY;
-    }
-
-    /**
-     * Gets the double array of samples for the specified band of the specified
-     * rectangular area of pixels in this Raster as a double array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangular area of pixels.
-     * @param y
-     *            the Y coordinate of the rectangular area of pixels.
-     * @param w
-     *            the width of the rectangular area of pixels.
-     * @param h
-     *            the height of the rectangular area of pixels.
-     * @param b
-     *            the band.
-     * @param dArray
-     *            the resulting double array.
-     * @return the double array of samples for the specified band of the
-     *         specified rectangular area of pixels.
-     */
-    public double[] getSamples(int x, int y, int w, int h, int b, double dArray[]) {
-
-        return sampleModel.getSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
-                b, dArray, dataBuffer);
-    }
-
-    /**
-     * Gets the float array of samples for the specified band of the specified
-     * rectangular area of pixels in this Raster as a float array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangular area of pixels.
-     * @param y
-     *            the Y coordinate of the rectangular area of pixels.
-     * @param w
-     *            the width of the rectangular area of pixels.
-     * @param h
-     *            the height of the rectangular area of pixels.
-     * @param b
-     *            the band.
-     * @param fArray
-     *            the resulting float array.
-     * @return the float array of samples for the specified band of the
-     *         specified rectangular area of pixels.
-     */
-    public float[] getSamples(int x, int y, int w, int h, int b, float fArray[]) {
-
-        return sampleModel.getSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
-                b, fArray, dataBuffer);
-    }
-
-    /**
-     * Gets the integer array of samples for the specified band of the specified
-     * rectangular area of pixels in this Raster as a integer array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangular area of pixels.
-     * @param y
-     *            the Y coordinate of the rectangular area of pixels.
-     * @param w
-     *            the width of the rectangular area of pixels.
-     * @param h
-     *            the height of the rectangular area of pixels.
-     * @param b
-     *            the band.
-     * @param iArray
-     *            the resulting integer array.
-     * @return the integer array of samples for the specified band of the
-     *         specified rectangular area of pixels.
-     */
-    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[]) {
-        return sampleModel.getSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
-                b, iArray, dataBuffer);
-    }
-
-    /**
-     * Gets the transfer type for pixels of this Raster.
-     * 
-     * @see SampleModel#getTransferType()
-     * @return the transfer type for pixels of this Raster.
-     */
-    public final int getTransferType() {
-        return sampleModel.getTransferType();
-    }
-
-    /**
-     * Gets the width of this Raster.
-     * 
-     * @return the width of this Raster.
-     */
-    public final int getWidth() {
-        return width;
-    }
-
-    /**
-     * Validate data buffer.
-     * 
-     * @param dataBuffer
-     *            the data buffer.
-     * @param w
-     *            the w.
-     * @param h
-     *            the h.
-     * @param scanlineStride
-     *            the scanline stride.
-     */
-    private static void validateDataBuffer(final DataBuffer dataBuffer, final int w, final int h,
-            final int scanlineStride) {
-        if (dataBuffer.getSize() < (scanlineStride * (h - 1) + w - 1)) {
-            // awt.298=dataBuffer is too small
-            throw new RasterFormatException(Messages.getString("awt.298")); //$NON-NLS-1$
-        }
-    }
-}
diff --git a/awt/java/awt/image/RasterFormatException.java b/awt/java/awt/image/RasterFormatException.java
deleted file mode 100644
index c667141..0000000
--- a/awt/java/awt/image/RasterFormatException.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-/**
- * The RasterFormatException class represents the exception that is thrown when
- * there's an invalid layout in the Raster.
- * 
- * @since Android 1.0
- */
-public class RasterFormatException extends RuntimeException {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 96598996116164315L;
-
-    /**
-     * Instantiates a new RasterFormatException with the specified detail
-     * message.
-     * 
-     * @param s
-     *            the detail message.
-     */
-    public RasterFormatException(String s) {
-        super(s);
-    }
-
-}
diff --git a/awt/java/awt/image/RasterOp.java b/awt/java/awt/image/RasterOp.java
deleted file mode 100644
index 19a84c9..0000000
--- a/awt/java/awt/image/RasterOp.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.RenderingHints;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-
-/**
- * The RasterOp interface provides methods for performing transformations from
- * source data to destination data for Raster objects. The source and
- * destination objects should contain the appropriate number of bands for the
- * particular classes which implement this interface.
- * 
- * @since Android 1.0
- */
-public interface RasterOp {
-
-    /**
-     * Creates a destination WritableRaster with the specified Raster; this
-     * destination image data is empty and has the correct size and number of
-     * bands.
-     * 
-     * @param src
-     *            the source Raster.
-     * @return the WritableRaster.
-     */
-    public WritableRaster createCompatibleDestRaster(Raster src);
-
-    /**
-     * Performs a filter operation on the source Raster and stores the resulting
-     * image data to the destination WritableRaster.
-     * 
-     * @param src
-     *            the source Raster.
-     * @param dst
-     *            the destination WritableRaster, where the result is stored.
-     * @return the filtered WritableRaster.
-     */
-    public WritableRaster filter(Raster src, WritableRaster dst);
-
-    /**
-     * Gets the bounds of the filtered Raster.
-     * 
-     * @param src
-     *            the source Raster to be filtered.
-     * @return the rectangle bounds of the filtered Raster.
-     */
-    public Rectangle2D getBounds2D(Raster src);
-
-    /**
-     * Gets the point of the destination image which corresponds to the
-     * specified point in the source raster.
-     * 
-     * @param srcPoint
-     *            the point of the source raster.
-     * @param dstPoint
-     *            the point where the result will be stored.
-     * @return the destination point.
-     */
-    public Point2D getPoint2D(Point2D srcPoint, Point2D dstPoint);
-
-    /**
-     * Gets the RenderingHints of the RasterOp.
-     * 
-     * @return the RenderingHints of the RasterOp.
-     */
-    public RenderingHints getRenderingHints();
-}
diff --git a/awt/java/awt/image/RenderedImage.java b/awt/java/awt/image/RenderedImage.java
deleted file mode 100644
index 5eafa64..0000000
--- a/awt/java/awt/image/RenderedImage.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.Rectangle;
-import java.util.Vector;
-
-/**
- * The RenderedImage interface should be implemented by all objects which
- * contains image data. The image data is represented as a single tile or an
- * array of tiles.
- * 
- * @since Android 1.0
- */
-public interface RenderedImage {
-
-    /**
-     * Gets the property with the specified name from the property set of this
-     * RenderedImage.
-     * 
-     * @param name
-     *            the property's name.
-     * @return the property value corresponded to this property's name.
-     */
-    public Object getProperty(String name);
-
-    /**
-     * Copies the region of this RenderedImage to the specified WritableRaster.
-     * The bounds of the region are the bounds of the WritableRaster.
-     * 
-     * @param raster
-     *            the WritableRaster.
-     * @return the created WritableRaster.
-     */
-    public WritableRaster copyData(WritableRaster raster);
-
-    /**
-     * Gets the image data of the image's region as one tile.
-     * 
-     * @param rect
-     *            the rectangular region of RenderedImage.
-     * @return the image data of the image's region as one tile.
-     */
-    public Raster getData(Rectangle rect);
-
-    /**
-     * Gets all RenderedImage objects which are the source of this RenderedImage
-     * object.
-     * 
-     * @return a Vector of RenderedImage objects which are the source of this
-     *         RenderedImage object or null, if there is no information about
-     *         them.
-     */
-    public Vector<RenderedImage> getSources();
-
-    /**
-     * Gets the set of all property names for this RenderedImage.
-     * 
-     * @return the array of all property names for this RenderedImage.
-     */
-    public String[] getPropertyNames();
-
-    /**
-     * Gets the SampleModel of this RenderedImage.
-     * 
-     * @return the SampleModel of this RenderedImage.
-     */
-    public SampleModel getSampleModel();
-
-    /**
-     * Gets the tile corresponded to the specified indices in the tile array.
-     * 
-     * @param tileX
-     *            the X index of the tile.
-     * @param tileY
-     *            the Y index of the tile.
-     * @return the tile corresponded to the specified indices in the tile array.
-     */
-    public Raster getTile(int tileX, int tileY);
-
-    /**
-     * Gets the image data of this image as one tile.
-     * 
-     * @return the image data of this image as one tile.
-     */
-    public Raster getData();
-
-    /**
-     * Gets the ColorModel of this RenderedImage.
-     * 
-     * @return the ColorModel of this RenderedImage.
-     */
-    public ColorModel getColorModel();
-
-    /**
-     * Gets the width of the RenderedImage.
-     * 
-     * @return the width of the RenderedImage.
-     */
-    public int getWidth();
-
-    /**
-     * Gets the tile width.
-     * 
-     * @return the tile width in pixels.
-     */
-    public int getTileWidth();
-
-    /**
-     * Gets the tile height.
-     * 
-     * @return the tile height in pixels.
-     */
-    public int getTileHeight();
-
-    /**
-     * Gets the Y offset of the tile grid.
-     * 
-     * @return the Y offset of the tile grid.
-     */
-    public int getTileGridYOffset();
-
-    /**
-     * Gets the X offset of the tile grid.
-     * 
-     * @return the X offset of the tile grid.
-     */
-    public int getTileGridXOffset();
-
-    /**
-     * Gets the number of tiles along Y direction.
-     * 
-     * @return the number of tiles along Y direction.
-     */
-    public int getNumYTiles();
-
-    /**
-     * Gets the number of tiles along X direction.
-     * 
-     * @return the number of tiles along X direction.
-     */
-    public int getNumXTiles();
-
-    /**
-     * Gets the minimum Y coordinate of this RenderedImage.
-     * 
-     * @return the minimum Y coordinate of this RenderedImage.
-     */
-    public int getMinY();
-
-    /**
-     * Gets the minimum X coordinate of this RenderedImage.
-     * 
-     * @return the minimum X coordinate of this RenderedImage.
-     */
-    public int getMinX();
-
-    /**
-     * Gets the minimum tile's index along the Y direction.
-     * 
-     * @return the minimum tile's index along the Y direction.
-     */
-    public int getMinTileY();
-
-    /**
-     * Gets the minimum tile's index along the X direction.
-     * 
-     * @return the minimum tile's index along the X direction.
-     */
-    public int getMinTileX();
-
-    /**
-     * Gets the height of the RenderedImage.
-     * 
-     * @return the height of the RenderedImage.
-     */
-    public int getHeight();
-
-}
diff --git a/awt/java/awt/image/ReplicateScaleFilter.java b/awt/java/awt/image/ReplicateScaleFilter.java
deleted file mode 100644
index 51c0f49..0000000
--- a/awt/java/awt/image/ReplicateScaleFilter.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.util.Hashtable;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The ReplicateScaleFilter class scales an source image by replicating rows and
- * columns of pixels to scale up or omitting rows and columns of pixels to scale
- * down.
- * 
- * @since Android 1.0
- */
-public class ReplicateScaleFilter extends ImageFilter {
-
-    /**
-     * The width of a source image.
-     */
-    protected int srcWidth;
-
-    /**
-     * The height of a source image.
-     */
-    protected int srcHeight;
-
-    /**
-     * The width of a destination image.
-     */
-    protected int destWidth;
-
-    /**
-     * The height of a destination image.
-     */
-    protected int destHeight;
-
-    /**
-     * The integer array of source rows.
-     */
-    protected int[] srcrows;
-
-    /**
-     * The integer array of source columns.
-     */
-    protected int[] srccols;
-
-    /**
-     * An Object (byte array with a destination width) provides a row of pixel
-     * data to the ImageConsumer.
-     */
-    protected Object outpixbuf;
-
-    /**
-     * Instantiates a new ReplicateScaleFilter that filters the image with the
-     * specified width and height.
-     * 
-     * @param width
-     *            the width of scaled image.
-     * @param height
-     *            the height of scaled image.
-     */
-    public ReplicateScaleFilter(int width, int height) {
-        if (width == 0 || height == 0) {
-            // awt.234=Width or Height equals zero
-            throw new IllegalArgumentException(Messages.getString("awt.234")); //$NON-NLS-1$
-        }
-
-        this.destWidth = width;
-        this.destHeight = height;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void setProperties(Hashtable<?, ?> props) {
-        Hashtable<Object, Object> fprops;
-        if (props == null) {
-            fprops = new Hashtable<Object, Object>();
-        } else {
-            fprops = (Hashtable<Object, Object>)props.clone();
-        }
-        String propName = "Rescale Filters"; //$NON-NLS-1$
-        String prop = "destWidth=" + destWidth + "; " + //$NON-NLS-1$ //$NON-NLS-2$
-                "destHeight=" + destHeight; //$NON-NLS-1$
-        Object o = fprops.get(propName);
-        if (o != null) {
-            if (o instanceof String) {
-                prop = (String)o + "; " + prop; //$NON-NLS-1$
-            } else {
-                prop = o.toString() + "; " + prop; //$NON-NLS-1$
-            }
-        }
-        fprops.put(propName, prop);
-        consumer.setProperties(fprops);
-    }
-
-    // setPixels methods produce pixels according to Java API Spacification
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
-            int scansize) {
-
-        if (srccols == null) {
-            initArrays();
-        }
-        int buff[];
-        if (outpixbuf == null || !(outpixbuf instanceof int[])) {
-            buff = new int[destWidth];
-            outpixbuf = buff;
-        } else {
-            buff = (int[])outpixbuf;
-        }
-
-        int wa = (srcWidth - 1) >>> 1;
-        int ha = (srcHeight - 1) >>> 1;
-        int dstX = (x * destWidth + wa) / srcWidth;
-        int dstY = (y * destHeight + ha) / srcHeight;
-
-        int sx, sy, dx, dy;
-        dy = dstY;
-        while ((dy < destHeight) && ((sy = srcrows[dy]) < y + h)) {
-            dx = dstX;
-            int srcOff = off + (sy - y) * scansize;
-            while ((dx < destWidth) && ((sx = srccols[dx]) < x + w)) {
-                buff[dx] = pixels[srcOff + (sx - x)];
-                dx++;
-            }
-
-            consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, dstX, destWidth);
-            dy++;
-        }
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
-            int scansize) {
-
-        if (srccols == null) {
-            initArrays();
-        }
-        byte buff[];
-        if (outpixbuf == null || !(outpixbuf instanceof byte[])) {
-            buff = new byte[destWidth];
-            outpixbuf = buff;
-        } else {
-            buff = (byte[])outpixbuf;
-        }
-
-        int wa = (srcWidth - 1) >>> 1;
-        int ha = (srcHeight - 1) >>> 1;
-        int dstX = (x * destWidth + wa) / srcWidth;
-        int dstY = (y * destHeight + ha) / srcHeight;
-
-        int sx, sy, dx, dy;
-        dy = dstY;
-        while ((dy < destHeight) && ((sy = srcrows[dy]) < y + h)) {
-            dx = dstX;
-            int srcOff = off + (sy - y) * scansize;
-            while ((dx < destWidth) && ((sx = srccols[dx]) < x + w)) {
-                buff[dx] = pixels[srcOff + (sx - x)];
-                dx++;
-            }
-
-            consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, dstX, destWidth);
-            dy++;
-        }
-    }
-
-    @Override
-    public void setDimensions(int w, int h) {
-        srcWidth = w;
-        srcHeight = h;
-
-        if (destWidth < 0 && destHeight < 0) {
-            destWidth = srcWidth;
-            destHeight = srcHeight;
-        } else if (destWidth < 0) {
-            destWidth = destHeight * srcWidth / srcHeight;
-        } else if (destHeight < 0) {
-            destHeight = destWidth * srcHeight / srcWidth;
-        }
-        consumer.setDimensions(destWidth, destHeight);
-    }
-
-    /**
-     * Initialization of srccols and srcrows arrays.
-     */
-    private void initArrays() {
-        if ((destWidth < 0) || (destHeight < 0)) {
-            throw new IndexOutOfBoundsException();
-        }
-
-        srccols = new int[destWidth];
-        int ca = srcWidth >>> 1;
-        for (int i = 0; i < destWidth; i++) {
-            srccols[i] = (i * srcWidth + ca) / destWidth;
-        }
-
-        srcrows = new int[destHeight];
-        int ra = srcHeight >>> 1;
-        for (int i = 0; i < destHeight; i++) {
-            srcrows[i] = (i * srcHeight + ra) / destHeight;
-        }
-    }
-
-}
diff --git a/awt/java/awt/image/RescaleOp.java b/awt/java/awt/image/RescaleOp.java
deleted file mode 100644
index d7e2bd7..0000000
--- a/awt/java/awt/image/RescaleOp.java
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Oct 6, 2005
- */
-
-package java.awt.image;
-
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.*;
-import java.util.Arrays;
-
-import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class RescaleOp performs rescaling of the source image data by
- * multiplying the pixel values with a scale factor and then adding an offset.
- * 
- * @since Android 1.0
- */
-public class RescaleOp implements BufferedImageOp, RasterOp {
-
-    /**
-     * The scale factors.
-     */
-    private float scaleFactors[];
-
-    /**
-     * The offsets.
-     */
-    private float offsets[];
-
-    /**
-     * The hints.
-     */
-    private RenderingHints hints;
-
-    static {
-        // TODO
-        // System.loadLibrary("imageops");
-    }
-
-    /**
-     * Instantiates a new RescaleOp object with the specified scale factors and
-     * offsets.
-     * 
-     * @param scaleFactors
-     *            the array of scale factor values.
-     * @param offsets
-     *            the array of offset values.
-     * @param hints
-     *            the RenderingHints or null.
-     */
-    public RescaleOp(float[] scaleFactors, float[] offsets, RenderingHints hints) {
-        int numFactors = Math.min(scaleFactors.length, offsets.length);
-
-        this.scaleFactors = new float[numFactors];
-        this.offsets = new float[numFactors];
-
-        System.arraycopy(scaleFactors, 0, this.scaleFactors, 0, numFactors);
-        System.arraycopy(offsets, 0, this.offsets, 0, numFactors);
-
-        this.hints = hints;
-    }
-
-    /**
-     * Instantiates a new RescaleOp object with the specified scale factor and
-     * offset.
-     * 
-     * @param scaleFactor
-     *            the scale factor.
-     * @param offset
-     *            the offset.
-     * @param hints
-     *            the RenderingHints or null.
-     */
-    public RescaleOp(float scaleFactor, float offset, RenderingHints hints) {
-        scaleFactors = new float[1];
-        offsets = new float[1];
-
-        scaleFactors[0] = scaleFactor;
-        offsets[0] = offset;
-
-        this.hints = hints;
-    }
-
-    /**
-     * Gets the number of scaling factors.
-     * 
-     * @return the number of scaling factors.
-     */
-    public final int getNumFactors() {
-        return scaleFactors.length;
-    }
-
-    public final RenderingHints getRenderingHints() {
-        return hints;
-    }
-
-    /**
-     * Gets the scale factors of this RescaleOp.
-     * 
-     * @param scaleFactors
-     *            the desired scale factors array will be copied to this array.
-     * @return the scale factors array.
-     */
-    public final float[] getScaleFactors(float[] scaleFactors) {
-        if (scaleFactors == null) {
-            scaleFactors = new float[this.scaleFactors.length];
-        }
-
-        int minLength = Math.min(scaleFactors.length, this.scaleFactors.length);
-        System.arraycopy(this.scaleFactors, 0, scaleFactors, 0, minLength);
-        return scaleFactors;
-    }
-
-    /**
-     * Gets the offsets array of this RescaleOp.
-     * 
-     * @param offsets
-     *            the desired offsets array will be copied to this array.
-     * @return the offsets array of this RescaleOp.
-     */
-    public final float[] getOffsets(float[] offsets) {
-        if (offsets == null) {
-            offsets = new float[this.offsets.length];
-        }
-
-        int minLength = Math.min(offsets.length, this.offsets.length);
-        System.arraycopy(this.offsets, 0, offsets, 0, minLength);
-        return offsets;
-    }
-
-    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
-        if (dstPt == null) {
-            dstPt = new Point2D.Float();
-        }
-
-        dstPt.setLocation(srcPt);
-        return dstPt;
-    }
-
-    public final Rectangle2D getBounds2D(Raster src) {
-        return src.getBounds();
-    }
-
-    public final Rectangle2D getBounds2D(BufferedImage src) {
-        return getBounds2D(src.getRaster());
-    }
-
-    public WritableRaster createCompatibleDestRaster(Raster src) {
-        return src.createCompatibleWritableRaster();
-    }
-
-    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
-        if (dstCM == null) {
-            dstCM = src.getColorModel();
-        }
-
-        if (dstCM instanceof IndexColorModel) {
-            dstCM = ColorModel.getRGBdefault();
-        }
-
-        WritableRaster r = dstCM.isCompatibleSampleModel(src.getSampleModel()) ? src.getRaster()
-                .createCompatibleWritableRaster(src.getWidth(), src.getHeight()) : dstCM
-                .createCompatibleWritableRaster(src.getWidth(), src.getHeight());
-
-        return new BufferedImage(dstCM, r, dstCM.isAlphaPremultiplied(), null);
-    }
-
-    public final WritableRaster filter(Raster src, WritableRaster dst) {
-        if (dst == null) {
-            dst = createCompatibleDestRaster(src);
-        } else {
-            if (src.getNumBands() != dst.getNumBands()) {
-                // awt.21D=Number of src bands ({0}) does not match number of
-                // dst bands ({1})
-                throw new IllegalArgumentException(Messages.getString("awt.21D", //$NON-NLS-1$
-                        src.getNumBands(), dst.getNumBands()));
-            }
-        }
-
-        if (this.scaleFactors.length != 1 && this.scaleFactors.length != src.getNumBands()) {
-            // awt.21E=Number of scaling constants is not equal to the number of
-            // bands
-            throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
-        }
-
-        // TODO
-        // if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM, false) != 0)
-        if (slowFilter(src, dst, false) != 0) {
-            // awt.21F=Unable to transform source
-            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
-        }
-
-        return dst;
-    }
-
-    /**
-     * Slow filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @param skipAlpha
-     *            the skip alpha.
-     * @return the int.
-     */
-    private final int slowFilter(Raster src, WritableRaster dst, boolean skipAlpha) {
-        SampleModel sm = src.getSampleModel();
-
-        int numBands = src.getNumBands();
-        int srcHeight = src.getHeight();
-        int srcWidth = src.getWidth();
-
-        int srcMinX = src.getMinX();
-        int srcMinY = src.getMinY();
-        int dstMinX = dst.getMinX();
-        int dstMinY = dst.getMinY();
-
-        int[] maxValues = new int[numBands];
-        int[] masks = new int[numBands];
-        int[] sampleSizes = sm.getSampleSize();
-
-        for (int i = 0; i < numBands; i++) {
-            maxValues[i] = (1 << sampleSizes[i]) - 1;
-            masks[i] = ~(maxValues[i]);
-        }
-
-        // Processing bounds
-        float[] pixels = null;
-        pixels = src.getPixels(srcMinX, srcMinY, srcWidth, srcHeight, pixels);
-
-        // Cycle over pixels to be calculated
-        if (skipAlpha) { // Always suppose that alpha channel is the last band
-            if (scaleFactors.length > 1) {
-                for (int i = 0; i < pixels.length;) {
-                    for (int bandIdx = 0; bandIdx < numBands - 1; bandIdx++, i++) {
-                        pixels[i] = pixels[i] * scaleFactors[bandIdx] + offsets[bandIdx];
-                        // Check for overflow now
-                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
-                            if (pixels[i] < 0) {
-                                pixels[i] = 0;
-                            } else {
-                                pixels[i] = maxValues[bandIdx];
-                            }
-                        }
-                    }
-
-                    i++;
-                }
-            } else {
-                for (int i = 0; i < pixels.length;) {
-                    for (int bandIdx = 0; bandIdx < numBands - 1; bandIdx++, i++) {
-                        pixels[i] = pixels[i] * scaleFactors[0] + offsets[0];
-                        // Check for overflow now
-                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
-                            if (pixels[i] < 0) {
-                                pixels[i] = 0;
-                            } else {
-                                pixels[i] = maxValues[bandIdx];
-                            }
-                        }
-                    }
-
-                    i++;
-                }
-            }
-        } else {
-            if (scaleFactors.length > 1) {
-                for (int i = 0; i < pixels.length;) {
-                    for (int bandIdx = 0; bandIdx < numBands; bandIdx++, i++) {
-                        pixels[i] = pixels[i] * scaleFactors[bandIdx] + offsets[bandIdx];
-                        // Check for overflow now
-                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
-                            if (pixels[i] < 0) {
-                                pixels[i] = 0;
-                            } else {
-                                pixels[i] = maxValues[bandIdx];
-                            }
-                        }
-                    }
-                }
-            } else {
-                for (int i = 0; i < pixels.length;) {
-                    for (int bandIdx = 0; bandIdx < numBands; bandIdx++, i++) {
-                        pixels[i] = pixels[i] * scaleFactors[0] + offsets[0];
-                        // Check for overflow now
-                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
-                            if (pixels[i] < 0) {
-                                pixels[i] = 0;
-                            } else {
-                                pixels[i] = maxValues[bandIdx];
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        dst.setPixels(dstMinX, dstMinY, srcWidth, srcHeight, pixels);
-
-        return 0;
-    }
-
-    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
-        ColorModel srcCM = src.getColorModel();
-
-        if (srcCM instanceof IndexColorModel) {
-            // awt.220=Source should not have IndexColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.220")); //$NON-NLS-1$
-        }
-
-        // Check if the number of scaling factors matches the number of bands
-        int nComponents = srcCM.getNumComponents();
-        boolean skipAlpha;
-        if (srcCM.hasAlpha()) {
-            if (scaleFactors.length == 1 || scaleFactors.length == nComponents - 1) {
-                skipAlpha = true;
-            } else if (scaleFactors.length == nComponents) {
-                skipAlpha = false;
-            } else {
-                // awt.21E=Number of scaling constants is not equal to the
-                // number of bands
-                throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
-            }
-        } else if (scaleFactors.length == 1 || scaleFactors.length == nComponents) {
-            skipAlpha = false;
-        } else {
-            // awt.21E=Number of scaling constants is not equal to the number of
-            // bands
-            throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
-        }
-
-        BufferedImage finalDst = null;
-        if (dst == null) {
-            finalDst = dst;
-            dst = createCompatibleDestImage(src, srcCM);
-        } else if (!srcCM.equals(dst.getColorModel())) {
-            // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB
-            // as same
-            if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src.getType() == BufferedImage.TYPE_INT_ARGB) && (dst
-                    .getType() == BufferedImage.TYPE_INT_RGB || dst.getType() == BufferedImage.TYPE_INT_ARGB))) {
-                finalDst = dst;
-                dst = createCompatibleDestImage(src, srcCM);
-            }
-        }
-
-        // TODO
-        // if (ippFilter(src.getRaster(), dst.getRaster(), src.getType(),
-        // skipAlpha) != 0)
-        if (slowFilter(src.getRaster(), dst.getRaster(), skipAlpha) != 0) {
-            // awt.21F=Unable to transform source
-            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
-        }
-
-        if (finalDst != null) {
-            Graphics2D g = finalDst.createGraphics();
-            g.setComposite(AlphaComposite.Src);
-            g.drawImage(dst, 0, 0, null);
-        } else {
-            finalDst = dst;
-        }
-
-        return finalDst;
-    }
-
-    // Don't forget to pass allocated arrays for levels and values, size should
-    // be numBands*4
-    /**
-     * Creates the levels.
-     * 
-     * @param sm
-     *            the sm.
-     * @param numBands
-     *            the num bands.
-     * @param skipAlpha
-     *            the skip alpha.
-     * @param levels
-     *            the levels.
-     * @param values
-     *            the values.
-     * @param channelsOrder
-     *            the channels order.
-     */
-    private final void createLevels(SampleModel sm, int numBands, boolean skipAlpha, int levels[],
-            int values[], int channelsOrder[]) {
-        // Suppose same sample size for all channels, otherwise use slow filter
-        int maxValue = (1 << sm.getSampleSize(0)) - 1;
-
-        // For simplicity introduce these arrays
-        float extScaleFactors[] = new float[numBands];
-        float extOffsets[] = new float[numBands];
-
-        if (scaleFactors.length != 1) {
-            System.arraycopy(scaleFactors, 0, extScaleFactors, 0, scaleFactors.length);
-            System.arraycopy(offsets, 0, extOffsets, 0, scaleFactors.length);
-        } else {
-            for (int i = 0; i < numBands; i++) {
-                extScaleFactors[i] = scaleFactors[0];
-                extOffsets[i] = offsets[0];
-            }
-        }
-
-        if (skipAlpha) {
-            extScaleFactors[numBands - 1] = 1;
-            extOffsets[numBands - 1] = 0;
-        }
-
-        // Create a levels
-        for (int i = 0; i < numBands; i++) {
-            if (extScaleFactors[i] == 0) {
-                levels[i * 4] = 0;
-                levels[i * 4 + 1] = 0;
-                levels[i * 4 + 2] = maxValue + 1;
-                levels[i * 4 + 3] = maxValue + 1;
-            }
-
-            float minLevel = -extOffsets[i] / extScaleFactors[i];
-            float maxLevel = (maxValue - extOffsets[i]) / extScaleFactors[i];
-
-            if (minLevel < 0) {
-                minLevel = 0;
-            } else if (minLevel > maxValue) {
-                minLevel = maxValue;
-            }
-
-            if (maxLevel < 0) {
-                maxLevel = 0;
-            } else if (maxLevel > maxValue) {
-                maxLevel = maxValue;
-            }
-
-            levels[i * 4] = 0;
-            if (minLevel > maxLevel) {
-                levels[i * 4 + 1] = (int)maxLevel;
-                levels[i * 4 + 2] = (int)minLevel;
-            } else {
-                levels[i * 4 + 1] = (int)minLevel;
-                levels[i * 4 + 2] = (int)maxLevel;
-            }
-            levels[i * 4 + 3] = maxValue + 1;
-
-            // Fill values
-            for (int k = 0; k < 4; k++) {
-                int idx = i * 4 + k;
-                values[idx] = (int)(extScaleFactors[i] * levels[idx] + extOffsets[i]);
-                if (values[idx] < 0) {
-                    values[idx] = 0;
-                } else if (values[idx] > maxValue) {
-                    values[idx] = maxValue;
-                }
-            }
-        }
-
-        // Reorder data if channels are stored in different order
-        if (channelsOrder != null) {
-            int len = numBands * 4;
-            int savedLevels[] = new int[len];
-            int savedValues[] = new int[len];
-            System.arraycopy(levels, 0, savedLevels, 0, len);
-            System.arraycopy(values, 0, savedValues, 0, len);
-            for (int i = 0; i < channelsOrder.length; i++) {
-                System.arraycopy(savedLevels, i * 4, levels, channelsOrder[i] * 4, 4);
-                System.arraycopy(savedValues, i * 4, values, channelsOrder[i] * 4, 4);
-            }
-        }
-    }
-
-    // TODO remove when this method is used
-    /**
-     * Ipp filter.
-     * 
-     * @param src
-     *            the src.
-     * @param dst
-     *            the dst.
-     * @param imageType
-     *            the image type.
-     * @param skipAlpha
-     *            the skip alpha.
-     * @return the int.
-     */
-    @SuppressWarnings("unused")
-    private final int ippFilter(Raster src, WritableRaster dst, int imageType, boolean skipAlpha) {
-        int res;
-
-        int srcStride, dstStride;
-        int channels;
-        int offsets[] = null;
-        int channelsOrder[] = null;
-
-        switch (imageType) {
-            case BufferedImage.TYPE_INT_ARGB:
-            case BufferedImage.TYPE_INT_ARGB_PRE:
-            case BufferedImage.TYPE_INT_RGB: {
-                channels = 4;
-                srcStride = src.getWidth() * 4;
-                dstStride = dst.getWidth() * 4;
-                channelsOrder = new int[] {
-                        2, 1, 0, 3
-                };
-                break;
-            }
-
-            case BufferedImage.TYPE_4BYTE_ABGR:
-            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
-            case BufferedImage.TYPE_INT_BGR: {
-                channels = 4;
-                srcStride = src.getWidth() * 4;
-                dstStride = dst.getWidth() * 4;
-                break;
-            }
-
-            case BufferedImage.TYPE_BYTE_GRAY: {
-                channels = 1;
-                srcStride = src.getWidth();
-                dstStride = dst.getWidth();
-                break;
-            }
-
-            case BufferedImage.TYPE_3BYTE_BGR: {
-                channels = 3;
-                srcStride = src.getWidth() * 3;
-                dstStride = dst.getWidth() * 3;
-                channelsOrder = new int[] {
-                        2, 1, 0
-                };
-                break;
-            }
-
-            case BufferedImage.TYPE_USHORT_GRAY:
-            case BufferedImage.TYPE_USHORT_565_RGB:
-            case BufferedImage.TYPE_USHORT_555_RGB:
-            case BufferedImage.TYPE_BYTE_BINARY: {
-                return slowFilter(src, dst, skipAlpha);
-            }
-
-            default: {
-                SampleModel srcSM = src.getSampleModel();
-                SampleModel dstSM = dst.getSampleModel();
-
-                if (srcSM instanceof PixelInterleavedSampleModel
-                        && dstSM instanceof PixelInterleavedSampleModel) {
-                    // Check PixelInterleavedSampleModel
-                    if (srcSM.getDataType() != DataBuffer.TYPE_BYTE
-                            || dstSM.getDataType() != DataBuffer.TYPE_BYTE) {
-                        return slowFilter(src, dst, skipAlpha);
-                    }
-
-                    channels = srcSM.getNumBands(); // Have IPP functions for 1,
-                    // 3 and 4 channels
-                    if (!(channels == 1 || channels == 3 || channels == 4)) {
-                        return slowFilter(src, dst, skipAlpha);
-                    }
-
-                    srcStride = ((ComponentSampleModel)srcSM).getScanlineStride();
-                    dstStride = ((ComponentSampleModel)dstSM).getScanlineStride();
-
-                    channelsOrder = ((ComponentSampleModel)srcSM).getBandOffsets();
-                } else if (srcSM instanceof SinglePixelPackedSampleModel
-                        && dstSM instanceof SinglePixelPackedSampleModel) {
-                    // Check SinglePixelPackedSampleModel
-                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)srcSM;
-                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel)dstSM;
-
-                    channels = sppsm1.getNumBands();
-
-                    // TYPE_INT_RGB, TYPE_INT_ARGB...
-                    if (sppsm1.getDataType() != DataBuffer.TYPE_INT
-                            || sppsm2.getDataType() != DataBuffer.TYPE_INT
-                            || !(channels == 3 || channels == 4)) {
-                        return slowFilter(src, dst, skipAlpha);
-                    }
-
-                    // Check compatibility of sample models
-                    if (!Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets())
-                            || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) {
-                        return slowFilter(src, dst, skipAlpha);
-                    }
-
-                    for (int i = 0; i < channels; i++) {
-                        if (sppsm1.getSampleSize(i) != 8) {
-                            return slowFilter(src, dst, skipAlpha);
-                        }
-                    }
-
-                    channelsOrder = new int[channels];
-                    int bitOffsets[] = sppsm1.getBitOffsets();
-                    for (int i = 0; i < channels; i++) {
-                        channelsOrder[i] = bitOffsets[i] / 8;
-                    }
-
-                    if (channels == 3) { // Don't skip channel now, could be
-                        // optimized
-                        channels = 4;
-                    }
-
-                    srcStride = sppsm1.getScanlineStride() * 4;
-                    dstStride = sppsm2.getScanlineStride() * 4;
-                } else {
-                    return slowFilter(src, dst, skipAlpha);
-                }
-
-                // Fill offsets if there's a child raster
-                if (src.getParent() != null || dst.getParent() != null) {
-                    if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
-                            || dst.getSampleModelTranslateX() != 0
-                            || dst.getSampleModelTranslateY() != 0) {
-                        offsets = new int[4];
-                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
-                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
-                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
-                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
-                    }
-                }
-            }
-        }
-
-        int levels[] = new int[4 * channels];
-        int values[] = new int[4 * channels];
-
-        createLevels(src.getSampleModel(), channels, skipAlpha, levels, values, channelsOrder);
-
-        Object srcData, dstData;
-        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
-        try {
-            srcData = dbAccess.getData(src.getDataBuffer());
-            dstData = dbAccess.getData(dst.getDataBuffer());
-        } catch (IllegalArgumentException e) {
-            return -1; // Unknown data buffer type
-        }
-
-        res = LookupOp.ippLUT(srcData, src.getWidth(), src.getHeight(), srcStride, dstData, dst
-                .getWidth(), dst.getHeight(), dstStride, levels, values, channels, offsets, true);
-
-        return res;
-    }
-}
diff --git a/awt/java/awt/image/SampleModel.java b/awt/java/awt/image/SampleModel.java
deleted file mode 100644
index c967fa6..0000000
--- a/awt/java/awt/image/SampleModel.java
+++ /dev/null
@@ -1,1166 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The SampleModel class is abstract class for retrieving pixel's samples in the
- * data of an image. Each pixel contains several samples. A sample is the set of
- * values of the bands for single pixel. For example, each pixel in the RGB
- * model contains three samples and there are three corresponding bands in the
- * image data of such pixels representing red, green and blue components.
- * <p>
- * The image data is represented as a Raster with a DataBuffer and a
- * SampleModel. The SampleModel allows access to the samples in the DataBuffer.
- * 
- * @since Android 1.0
- */
-public abstract class SampleModel {
-
-    /**
-     * The width of the image data which this SampleModel describes.
-     */
-    protected int width;
-
-    /**
-     * The height of the image data which this SampleModel describes.
-     */
-    protected int height;
-
-    /**
-     * The number of bands of image data which this SampleModel describes.
-     */
-    protected int numBands;
-
-    /**
-     * The data type of the image data which this SampleModel describes.
-     */
-    protected int dataType;
-
-    /**
-     * Instantiates a new SampleModel with the specified data type, width,
-     * height and number of bands.
-     * 
-     * @param dataType
-     *            the data type of the image data.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param numBands
-     *            the number of bands of the image data.
-     */
-    public SampleModel(int dataType, int w, int h, int numBands) {
-        if (w <= 0 || h <= 0) {
-            // awt.22E=w or h is less than or equal to zero
-            throw new IllegalArgumentException(Messages.getString("awt.22E")); //$NON-NLS-1$
-        }
-
-        double squre = ((double)w) * ((double)h);
-        if (squre >= Integer.MAX_VALUE) {
-            // awt.22F=The product of w and h is greater than Integer.MAX_VALUE
-            throw new IllegalArgumentException(Messages.getString("awt.22F")); //$NON-NLS-1$
-        }
-
-        if (dataType < DataBuffer.TYPE_BYTE || dataType > DataBuffer.TYPE_DOUBLE
-                && dataType != DataBuffer.TYPE_UNDEFINED) {
-            // awt.230=dataType is not one of the supported data types
-            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
-        }
-
-        if (numBands < 1) {
-            // awt.231=Number of bands must be more then 0
-            throw new IllegalArgumentException(Messages.getString("awt.231")); //$NON-NLS-1$
-        }
-
-        this.dataType = dataType;
-        this.width = w;
-        this.height = h;
-        this.numBands = numBands;
-
-    }
-
-    /**
-     * Gets the data array for the specified pixel of the specified DataBuffer
-     * with one of the following types: DataBuffer.TYPE_BYTE,
-     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
-     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param obj
-     *            the Object is a data where the result will be stored.
-     * @param data
-     *            the image data.
-     * @return the data array for the specified pixel of the specified
-     *         DataBuffer.
-     */
-    public abstract Object getDataElements(int x, int y, Object obj, DataBuffer data);
-
-    /**
-     * Gets the array of pixel data for the specified rectangular area of pixels
-     * of the specified DataBuffer with one of the following types:
-     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
-     * DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
-     * 
-     * @param x
-     *            the X coordinate of the rectangular pixel area.
-     * @param y
-     *            the Y coordinate of the rectangular pixel area.
-     * @param w
-     *            the width of the rectangular pixel area.
-     * @param h
-     *            the height of the rectangular pixel area.
-     * @param obj
-     *            the Object is an array with the primitive type, where the
-     *            result array will be stored.
-     * @param data
-     *            the image data.
-     * @return the array of pixel data for the specified rectangular area of
-     *         pixels of the specified DataBuffer object.
-     */
-    public Object getDataElements(int x, int y, int w, int h, Object obj, DataBuffer data) {
-        int numDataElements = getNumDataElements();
-        int idx = 0;
-
-        switch (getTransferType()) {
-            case DataBuffer.TYPE_BYTE:
-                byte bdata[];
-                byte bbuf[] = null;
-
-                if (obj == null) {
-                    bdata = new byte[numDataElements * w * h];
-                } else {
-                    bdata = (byte[])obj;
-                }
-
-                for (int i = y; i < y + h; i++) {
-                    for (int j = x; j < x + w; j++) {
-                        bbuf = (byte[])getDataElements(j, i, bbuf, data);
-                        for (int n = 0; n < numDataElements; n++) {
-                            bdata[idx++] = bbuf[n];
-                        }
-                    }
-                }
-                obj = bdata;
-                break;
-
-            case DataBuffer.TYPE_SHORT:
-            case DataBuffer.TYPE_USHORT:
-                short sdata[];
-                short sbuf[] = null;
-
-                if (obj == null) {
-                    sdata = new short[numDataElements * w * h];
-                } else {
-                    sdata = (short[])obj;
-                }
-
-                for (int i = y; i < y + h; i++) {
-                    for (int j = x; j < x + w; j++) {
-                        sbuf = (short[])getDataElements(j, i, sbuf, data);
-                        for (int n = 0; n < numDataElements; n++) {
-                            sdata[idx++] = sbuf[n];
-                        }
-                    }
-                }
-                obj = sdata;
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int idata[];
-                int ibuf[] = null;
-
-                if (obj == null) {
-                    idata = new int[numDataElements * w * h];
-                } else {
-                    idata = (int[])obj;
-                }
-
-                for (int i = y; i < y + h; i++) {
-                    for (int j = x; j < x + w; j++) {
-                        ibuf = (int[])getDataElements(j, i, ibuf, data);
-                        for (int n = 0; n < numDataElements; n++) {
-                            idata[idx++] = ibuf[n];
-                        }
-                    }
-                }
-                obj = idata;
-                break;
-
-            case DataBuffer.TYPE_FLOAT:
-                float fdata[];
-                float fbuf[] = null;
-
-                if (obj == null) {
-                    fdata = new float[numDataElements * w * h];
-                } else {
-                    fdata = (float[])obj;
-                }
-
-                for (int i = y; i < y + h; i++) {
-                    for (int j = x; j < x + w; j++) {
-                        fbuf = (float[])getDataElements(j, i, fbuf, data);
-                        for (int n = 0; n < numDataElements; n++) {
-                            fdata[idx++] = fbuf[n];
-                        }
-                    }
-                }
-                obj = fdata;
-                break;
-
-            case DataBuffer.TYPE_DOUBLE:
-                double ddata[];
-                double dbuf[] = null;
-
-                if (obj == null) {
-                    ddata = new double[numDataElements * w * h];
-                } else {
-                    ddata = (double[])obj;
-                }
-
-                for (int i = y; i < y + h; i++) {
-                    for (int j = x; j < x + w; j++) {
-                        dbuf = (double[])getDataElements(j, i, dbuf, data);
-                        for (int n = 0; n < numDataElements; n++) {
-                            ddata[idx++] = dbuf[n];
-                        }
-                    }
-                }
-                obj = ddata;
-                break;
-
-        }
-
-        return obj;
-    }
-
-    /**
-     * Sets the data for a single pixel in the specified DataBuffer from a
-     * primitive array with one of the following types: DataBuffer.TYPE_BYTE,
-     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
-     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param obj
-     *            the Object - the array of primitive pixel data to be set.
-     * @param data
-     *            the image data.
-     */
-    public abstract void setDataElements(int x, int y, Object obj, DataBuffer data);
-
-    /**
-     * Sets the data elements for a rectangular area of pixels in the specified
-     * DataBuffer from a primitive array with one of the following types:
-     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
-     * DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
-     * 
-     * @param x
-     *            the X coordinate of the specified rectangular area.
-     * @param y
-     *            the Y coordinate of the specified rectangular area.
-     * @param w
-     *            the width of rectangle.
-     * @param h
-     *            the height of rectangle.
-     * @param obj
-     *            the Object - the array of primitive pixel data to be set.
-     * @param data
-     *            the image data.
-     */
-    public void setDataElements(int x, int y, int w, int h, Object obj, DataBuffer data) {
-        int numDataElements = getNumDataElements();
-        int idx = 0;
-
-        switch (getTransferType()) {
-            case DataBuffer.TYPE_BYTE:
-                byte bbuf[] = new byte[numDataElements];
-                for (int i = y; i < y + h; i++) {
-                    for (int j = x; j < x + w; j++) {
-                        for (int n = 0; n < numDataElements; n++) {
-                            bbuf[n] = ((byte[])obj)[idx++];
-                        }
-                        setDataElements(j, i, bbuf, data);
-                    }
-                }
-
-                break;
-
-            case DataBuffer.TYPE_SHORT:
-            case DataBuffer.TYPE_USHORT:
-                short sbuf[] = new short[numDataElements];
-                for (int i = y; i < y + h; i++) {
-                    for (int j = x; j < x + w; j++) {
-                        for (int n = 0; n < numDataElements; n++) {
-                            sbuf[n] = ((short[])obj)[idx++];
-                        }
-                        setDataElements(j, i, sbuf, data);
-                    }
-                }
-                break;
-
-            case DataBuffer.TYPE_INT:
-                int ibuf[] = new int[numDataElements];
-                for (int i = y; i < y + h; i++) {
-                    for (int j = x; j < x + w; j++) {
-                        for (int n = 0; n < numDataElements; n++) {
-                            ibuf[n] = ((int[])obj)[idx++];
-                        }
-                        setDataElements(j, i, ibuf, data);
-                    }
-                }
-                break;
-
-            case DataBuffer.TYPE_FLOAT:
-                float fbuf[] = new float[numDataElements];
-                for (int i = y; i < y + h; i++) {
-                    for (int j = x; j < x + w; j++) {
-                        for (int n = 0; n < numDataElements; n++) {
-                            fbuf[n] = ((float[])obj)[idx++];
-                        }
-                        setDataElements(j, i, fbuf, data);
-                    }
-                }
-                break;
-
-            case DataBuffer.TYPE_DOUBLE:
-                double dbuf[] = new double[numDataElements];
-                for (int i = y; i < y + h; i++) {
-                    for (int j = x; j < x + w; j++) {
-                        for (int n = 0; n < numDataElements; n++) {
-                            dbuf[n] = ((double[])obj)[idx++];
-                        }
-                        setDataElements(j, i, dbuf, data);
-                    }
-                }
-                break;
-
-        }
-    }
-
-    /**
-     * Creates a new SampleModel with the specified bands of this SampleModel.
-     * 
-     * @param bands
-     *            the array of bands from this SampleModel.
-     * @return the SampleModel with the specified bands of this SampleModel.
-     */
-    public abstract SampleModel createSubsetSampleModel(int bands[]);
-
-    /**
-     * Creates the SampleModel which has the same data as in this SampleModel
-     * with a different width and height.
-     * 
-     * @param a0
-     *            the width of the image data.
-     * @param a1
-     *            the height of the image data.
-     * @return the SampleModel which has the same data as in this SampleModel
-     *         with a different width and height.
-     */
-    public abstract SampleModel createCompatibleSampleModel(int a0, int a1);
-
-    /**
-     * Gets the samples of the specified pixel as an integer array.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param iArray
-     *            the integer array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the integer array with the samples of the specified pixel.
-     */
-    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int pixel[];
-
-        if (iArray == null) {
-            pixel = new int[numBands];
-        } else {
-            pixel = iArray;
-        }
-
-        for (int i = 0; i < numBands; i++) {
-            pixel[i] = getSample(x, y, i, data);
-        }
-
-        return pixel;
-    }
-
-    /**
-     * Sets a pixel of the DataBuffer from a integer array of samples.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param iArray
-     *            the integer array.
-     * @param data
-     *            the image data.
-     */
-    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        for (int i = 0; i < numBands; i++) {
-            setSample(x, y, i, iArray[i], data);
-        }
-    }
-
-    /**
-     * Gets the samples of the specified pixel as a float array.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param fArray
-     *            the float array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the float array with the samples of the specified pixel.
-     */
-    public float[] getPixel(int x, int y, float fArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        float pixel[];
-
-        if (fArray == null) {
-            pixel = new float[numBands];
-        } else {
-            pixel = fArray;
-        }
-
-        for (int i = 0; i < numBands; i++) {
-            pixel[i] = getSampleFloat(x, y, i, data);
-        }
-
-        return pixel;
-    }
-
-    /**
-     * Sets a pixel of the DataBuffer from a float array of samples.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param fArray
-     *            the float array.
-     * @param data
-     *            the image data.
-     */
-    public void setPixel(int x, int y, float fArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        for (int i = 0; i < numBands; i++) {
-            setSample(x, y, i, fArray[i], data);
-        }
-    }
-
-    /**
-     * Gets the samples of the specified pixel as a double array.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param dArray
-     *            the double array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the double array with the samples of the specified pixel.
-     */
-    public double[] getPixel(int x, int y, double dArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        double pixel[];
-
-        if (dArray == null) {
-            pixel = new double[numBands];
-        } else {
-            pixel = dArray;
-        }
-
-        for (int i = 0; i < numBands; i++) {
-            pixel[i] = getSampleDouble(x, y, i, data);
-        }
-
-        return pixel;
-    }
-
-    /**
-     * Sets a pixel of the DataBuffer from a double array of samples.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param dArray
-     *            the double array.
-     * @param data
-     *            the image data.
-     */
-    public void setPixel(int x, int y, double dArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        for (int i = 0; i < numBands; i++) {
-            setSample(x, y, i, dArray[i], data);
-        }
-    }
-
-    /**
-     * Gets the sample of a specified band for the specified pixel as an
-     * integer.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param b
-     *            the specified band.
-     * @param data
-     *            the image data.
-     * @return the sample of a specified band for the specified pixel.
-     */
-    public abstract int getSample(int x, int y, int b, DataBuffer data);
-
-    /**
-     * Gets the sample of a specified band for the specified pixel as a float.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param b
-     *            the specified band.
-     * @param data
-     *            the image data.
-     * @return the sample of a specified band for the specified pixel.
-     */
-    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
-        return getSample(x, y, b, data);
-    }
-
-    /**
-     * Gets the sample of a specified band for the specified pixel as a double.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param b
-     *            the specified band.
-     * @param data
-     *            the image data.
-     * @return the sample of a specified band for the specified pixel.
-     */
-    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
-        return getSample(x, y, b, data);
-    }
-
-    /**
-     * Gets the samples of the specified rectangular area of pixels as an
-     * integer array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle of pixels.
-     * @param y
-     *            the Y coordinate of the rectangle of pixels.
-     * @param w
-     *            the width of the rectangle of pixels.
-     * @param h
-     *            the height of the rectangle of pixels.
-     * @param iArray
-     *            the integer array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the integer array with the samples of the specified rectangular
-     *         area of pixels.
-     */
-    public int[] getPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int pixels[];
-        int idx = 0;
-
-        if (iArray == null) {
-            pixels = new int[w * h * numBands];
-        } else {
-            pixels = iArray;
-        }
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < numBands; n++) {
-                    pixels[idx++] = getSample(j, i, n, data);
-                }
-            }
-        }
-        return pixels;
-    }
-
-    /**
-     * Sets all of the samples for a rectangular area of pixels of the
-     * DataBuffer from an integer array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle of pixels.
-     * @param y
-     *            the Y coordinate of the rectangle of pixels.
-     * @param w
-     *            the width of the rectangle of pixels.
-     * @param h
-     *            the height of the rectangle of pixels.
-     * @param iArray
-     *            the integer array.
-     * @param data
-     *            the image data.
-     */
-    public void setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int idx = 0;
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < numBands; n++) {
-                    setSample(j, i, n, iArray[idx++], data);
-                }
-            }
-        }
-    }
-
-    /**
-     * Gets the samples of the specified rectangular area of pixels as a float
-     * array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle of pixels.
-     * @param y
-     *            the Y coordinate of the rectangle of pixels.
-     * @param w
-     *            the width of the rectangle of pixels.
-     * @param h
-     *            the height of the rectangle of pixels.
-     * @param fArray
-     *            the float array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the float array with the samples of the specified rectangular
-     *         area of pixels.
-     */
-    public float[] getPixels(int x, int y, int w, int h, float fArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        float pixels[];
-        int idx = 0;
-
-        if (fArray == null) {
-            pixels = new float[w * h * numBands];
-        } else {
-            pixels = fArray;
-        }
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < numBands; n++) {
-                    pixels[idx++] = getSampleFloat(j, i, n, data);
-                }
-            }
-        }
-        return pixels;
-    }
-
-    /**
-     * Sets all of the samples for a rectangular area of pixels of the
-     * DataBuffer from a float array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle of pixels.
-     * @param y
-     *            the Y coordinate of the rectangle of pixels.
-     * @param w
-     *            the width of the rectangle of pixels.
-     * @param h
-     *            the height of the rectangle of pixels.
-     * @param fArray
-     *            the float array.
-     * @param data
-     *            the image data.
-     */
-    public void setPixels(int x, int y, int w, int h, float fArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int idx = 0;
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < numBands; n++) {
-                    setSample(j, i, n, fArray[idx++], data);
-                }
-            }
-        }
-    }
-
-    /**
-     * Gets the samples of the specified rectangular area of pixels as a double
-     * array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle of pixels.
-     * @param y
-     *            the Y coordinate of the rectangle of pixels.
-     * @param w
-     *            the width of the rectangle of pixels.
-     * @param h
-     *            the height of the rectangle of pixels.
-     * @param dArray
-     *            the double array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the double array with the samples of the specified rectangular
-     *         area of pixels.
-     */
-    public double[] getPixels(int x, int y, int w, int h, double dArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        double pixels[];
-        int idx = 0;
-
-        if (dArray == null) {
-            pixels = new double[w * h * numBands];
-        } else {
-            pixels = dArray;
-        }
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < numBands; n++) {
-                    pixels[idx++] = getSampleDouble(j, i, n, data);
-                }
-            }
-        }
-        return pixels;
-    }
-
-    /**
-     * Sets all of the samples for a rectangular area of pixels of the
-     * DataBuffer from a double array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle of pixels.
-     * @param y
-     *            the Y coordinate of the rectangle of pixels.
-     * @param w
-     *            the width of the rectangle of pixels.
-     * @param h
-     *            the height of the rectangle of pixels.
-     * @param dArray
-     *            the double array.
-     * @param data
-     *            the image data.
-     */
-    public void setPixels(int x, int y, int w, int h, double dArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int idx = 0;
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < numBands; n++) {
-                    setSample(j, i, n, dArray[idx++], data);
-                }
-            }
-        }
-    }
-
-    /**
-     * Sets a sample of the specified band for the specified pixel in the
-     * DataBuffer as integer value.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param b
-     *            the specified band.
-     * @param s
-     *            the sample as an integer value.
-     * @param data
-     *            the image data.
-     */
-    public abstract void setSample(int x, int y, int b, int s, DataBuffer data);
-
-    /**
-     * Gets the samples of a specified band for a specified rectangular area of
-     * pixels as a integer array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle.
-     * @param y
-     *            the Y coordinate of the rectangle.
-     * @param w
-     *            the width of the rectangle.
-     * @param h
-     *            the height of the rectangle.
-     * @param b
-     *            the specified band.
-     * @param iArray
-     *            the integer array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the samples of a specified band for a specified rectangular area
-     *         of pixels.
-     */
-    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
-        int samples[];
-        int idx = 0;
-
-        if (iArray == null) {
-            samples = new int[w * h];
-        } else {
-            samples = iArray;
-        }
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                samples[idx++] = getSample(j, i, b, data);
-            }
-        }
-
-        return samples;
-    }
-
-    /**
-     * Sets the samples from an integer array in the specified band for the
-     * specified rectangle of pixels.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle.
-     * @param y
-     *            the Y coordinate of the rectangle.
-     * @param w
-     *            the width of the rectangle.
-     * @param h
-     *            the height of the rectangle.
-     * @param b
-     *            the specified band.
-     * @param iArray
-     *            the integer array.
-     * @param data
-     *            the image data.
-     */
-    public void setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
-        int idx = 0;
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                setSample(j, i, b, iArray[idx++], data);
-            }
-        }
-    }
-
-    /**
-     * Gets the samples of a specified band for a specified rectangular area of
-     * pixels as a float array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle.
-     * @param y
-     *            the Y coordinate of the rectangle.
-     * @param w
-     *            the width of the rectangle.
-     * @param h
-     *            the height of the rectangle.
-     * @param b
-     *            the specified band.
-     * @param fArray
-     *            the float array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the samples of a specified band for a specified rectangular area
-     *         of pixels.
-     */
-    public float[] getSamples(int x, int y, int w, int h, int b, float fArray[], DataBuffer data) {
-        float samples[];
-        int idx = 0;
-
-        if (fArray == null) {
-            samples = new float[w * h];
-        } else {
-            samples = fArray;
-        }
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                samples[idx++] = getSampleFloat(j, i, b, data);
-            }
-        }
-
-        return samples;
-    }
-
-    /**
-     * Sets the samples from an float array in the specified band for the
-     * specified rectangle of pixels.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle.
-     * @param y
-     *            the Y coordinate of the rectangle.
-     * @param w
-     *            the width of the rectangle.
-     * @param h
-     *            the height of the rectangle.
-     * @param b
-     *            the specified band.
-     * @param fArray
-     *            the float array.
-     * @param data
-     *            the image data.
-     */
-    public void setSamples(int x, int y, int w, int h, int b, float fArray[], DataBuffer data) {
-        int idx = 0;
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                setSample(j, i, b, fArray[idx++], data);
-            }
-        }
-    }
-
-    /**
-     * Gets the samples of a specified band for a specified rectangular area of
-     * pixels as a double array.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle.
-     * @param y
-     *            the Y coordinate of the rectangle.
-     * @param w
-     *            the width of the rectangle.
-     * @param h
-     *            the height of the rectangle.
-     * @param b
-     *            the specified band.
-     * @param dArray
-     *            the double array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the samples of a specified band for a specified rectangular area
-     *         of pixels.
-     */
-    public double[] getSamples(int x, int y, int w, int h, int b, double dArray[], DataBuffer data) {
-        double samples[];
-        int idx = 0;
-
-        if (dArray == null) {
-            samples = new double[w * h];
-        } else {
-            samples = dArray;
-        }
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                samples[idx++] = getSampleDouble(j, i, b, data);
-            }
-        }
-
-        return samples;
-    }
-
-    /**
-     * Sets the samples from an double array in the specified band for the
-     * specified rectangle of pixels.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle.
-     * @param y
-     *            the Y coordinate of the rectangle.
-     * @param w
-     *            the width of the rectangle.
-     * @param h
-     *            the height of the rectangle.
-     * @param b
-     *            the specified band.
-     * @param dArray
-     *            the double array.
-     * @param data
-     *            the image data.
-     */
-    public void setSamples(int x, int y, int w, int h, int b, double dArray[], DataBuffer data) {
-        int idx = 0;
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                setSample(j, i, b, dArray[idx++], data);
-            }
-        }
-    }
-
-    /**
-     * Sets a sample of the specified band for the specified pixel in the
-     * DataBuffer as float value.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param b
-     *            the specified band.
-     * @param s
-     *            the sample as float value.
-     * @param data
-     *            the image data.
-     */
-    public void setSample(int x, int y, int b, float s, DataBuffer data) {
-        setSample(x, y, b, (int)s, data);
-    }
-
-    /**
-     * Sets a sample of the specified band for the specified pixel in the
-     * DataBuffer as double value.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param b
-     *            the specified band.
-     * @param s
-     *            the sample as double value.
-     * @param data
-     *            the image data.
-     */
-    public void setSample(int x, int y, int b, double s, DataBuffer data) {
-        setSample(x, y, b, (int)s, data);
-    }
-
-    /**
-     * Creates a DataBuffer object which corresponds to the SampleModel.
-     * 
-     * @return the DataBuffer object which corresponds to the SampleModel.
-     */
-    public abstract DataBuffer createDataBuffer();
-
-    /**
-     * Gets the sample size in bits for the specified band.
-     * 
-     * @param band
-     *            the specified band.
-     * @return the sample size in bits for the specified band.
-     */
-    public abstract int getSampleSize(int band);
-
-    /**
-     * Gets an array of the sample size in bits for all bands.
-     * 
-     * @return an array of the sample size in bits for all bands.
-     */
-    public abstract int[] getSampleSize();
-
-    /**
-     * Gets the width of the image data of this SampleModel object.
-     * 
-     * @return the width of the image data of this SampleModel object.
-     */
-    public final int getWidth() {
-        return width;
-    }
-
-    /**
-     * Gets the transfer type used to transfer pixels via the getDataElements
-     * and setDataElements methods. Transfer type value can be one of the
-     * predefined type from DataBuffer class or not.
-     * 
-     * @return the transfer type.
-     */
-    public int getTransferType() {
-        return dataType;
-    }
-
-    /**
-     * Returns the number of data elements for pixel transferring via the
-     * getDataElements and setDataElements methods.
-     * 
-     * @return the number of data elements for pixel transferring via the
-     *         getDataElements and setDataElements methods.
-     */
-    public abstract int getNumDataElements();
-
-    /**
-     * Gets the number of bands in the image data of this SampleModel object.
-     * 
-     * @return the number of bands in the image data of this SampleModel object.
-     */
-    public final int getNumBands() {
-        return numBands;
-    }
-
-    /**
-     * Gets the height of the image data of this SampleModel object.
-     * 
-     * @return the height of the image data of this SampleModel object.
-     */
-    public final int getHeight() {
-        return height;
-    }
-
-    /**
-     * Gets the data type of image data of this SampleModel object.
-     * 
-     * @return the data type of image data of this SampleModel object.
-     */
-    public final int getDataType() {
-        return dataType;
-    }
-
-}
diff --git a/awt/java/awt/image/ShortLookupTable.java b/awt/java/awt/image/ShortLookupTable.java
deleted file mode 100644
index 4319d58..0000000
--- a/awt/java/awt/image/ShortLookupTable.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Oct 14, 2005
- */
-
-package java.awt.image;
-
-/**
- * The ShortLookupTable class provides provides functionality for lookup
- * operations, and is defined by an input short array for bands or components of
- * image and an offset value. The offset value will be subtracted from the input
- * values before indexing the input arrays. The output of a lookup operation is
- * represented as an unsigned short array.
- * 
- * @since Android 1.0
- */
-public class ShortLookupTable extends LookupTable {
-
-    /**
-     * The data.
-     */
-    private short data[][];
-
-    /**
-     * Instantiates a new ShortLookupTable with the specified offset value and
-     * the specified short array which represents lookup table for all bands.
-     * 
-     * @param offset
-     *            the offset value.
-     * @param data
-     *            the data array.
-     */
-    public ShortLookupTable(int offset, short[] data) {
-        super(offset, 1);
-        this.data = new short[1][data.length];
-        // The data array stored as a reference
-        this.data[0] = data;
-    }
-
-    /**
-     * Instantiates a new ShortLookupTable with the specified offset value and
-     * the specified short array of arrays which represents lookup table for
-     * each band.
-     * 
-     * @param offset
-     *            the offset value.
-     * @param data
-     *            the data array of arrays for each band.
-     */
-    public ShortLookupTable(int offset, short[][] data) {
-        super(offset, data.length);
-        this.data = new short[data.length][data[0].length];
-        for (int i = 0; i < data.length; i++) {
-            // The data array for each band stored as a reference
-            this.data[i] = data[i];
-        }
-    }
-
-    /**
-     * Gets the lookup table of this ShortLookupTable object. If this
-     * ShortLookupTable object has one short array for all bands, the returned
-     * array length is one.
-     * 
-     * @return the lookup table of this ShortLookupTable object.
-     */
-    public final short[][] getTable() {
-        return data;
-    }
-
-    /**
-     * Returns a short array which contains samples of the specified pixel which
-     * is translated with the lookup table of this ShortLookupTable object. The
-     * resulted array is stored to the dst array.
-     * 
-     * @param src
-     *            the source array.
-     * @param dst
-     *            the destination array where the result can be stored.
-     * @return the short array of translated samples of a pixel.
-     */
-    public short[] lookupPixel(short[] src, short[] dst) {
-        if (dst == null) {
-            dst = new short[src.length];
-        }
-
-        int offset = getOffset();
-        if (getNumComponents() == 1) {
-            for (int i = 0; i < src.length; i++) {
-                dst[i] = data[0][src[i] - offset];
-            }
-        } else {
-            for (int i = 0; i < getNumComponents(); i++) {
-                dst[i] = data[i][src[i] - offset];
-            }
-        }
-
-        return dst;
-    }
-
-    @Override
-    public int[] lookupPixel(int[] src, int[] dst) {
-        if (dst == null) {
-            dst = new int[src.length];
-        }
-
-        int offset = getOffset();
-        if (getNumComponents() == 1) {
-            for (int i = 0; i < src.length; i++) {
-                dst[i] = data[0][src[i] - offset];
-            }
-        } else {
-            for (int i = 0; i < getNumComponents(); i++) {
-                dst[i] = data[i][src[i] - offset];
-            }
-        }
-
-        return dst;
-    }
-}
diff --git a/awt/java/awt/image/SinglePixelPackedSampleModel.java b/awt/java/awt/image/SinglePixelPackedSampleModel.java
deleted file mode 100644
index 69f3353..0000000
--- a/awt/java/awt/image/SinglePixelPackedSampleModel.java
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.util.Arrays;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The SinglePixelPackedSampleModel class represents pixel data where several
- * samples combine to create a single pixel and are stored in a single data
- * array element. This class supports TYPE_BYTE, TYPE_USHORT, TYPE_INT data
- * types.
- * 
- * @since Android 1.0
- */
-public class SinglePixelPackedSampleModel extends SampleModel {
-
-    /**
-     * The bit masks.
-     */
-    private int bitMasks[];
-
-    /**
-     * The bit offsets.
-     */
-    private int bitOffsets[];
-
-    /**
-     * The bit sizes.
-     */
-    private int bitSizes[];
-
-    /**
-     * The scanline stride.
-     */
-    private int scanlineStride;
-
-    /**
-     * The max bit size.
-     */
-    private int maxBitSize;
-
-    /**
-     * Instantiates a new SinglePixelPackedSampleModel with the specified
-     * parameters.
-     * 
-     * @param dataType
-     *            the data type of samples.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param bitMasks
-     *            the bit masks for all the bands.
-     */
-    public SinglePixelPackedSampleModel(int dataType, int w, int h, int bitMasks[]) {
-        this(dataType, w, h, w, bitMasks);
-    }
-
-    /**
-     * Instantiates a new SinglePixelPackedSampleModel with the specified
-     * parameters.
-     * 
-     * @param dataType
-     *            the data type of the samples.
-     * @param w
-     *            the width of the image data.
-     * @param h
-     *            the height of the image data.
-     * @param scanlineStride
-     *            the scanline stride of the image data.
-     * @param bitMasks
-     *            the bit masks for all the bands.
-     */
-    public SinglePixelPackedSampleModel(int dataType, int w, int h, int scanlineStride,
-            int bitMasks[]) {
-
-        super(dataType, w, h, bitMasks.length);
-
-        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
-                && dataType != DataBuffer.TYPE_INT) {
-            // awt.61=Unsupported data type: {0}
-            throw new IllegalArgumentException(Messages.getString("awt.61", //$NON-NLS-1$
-                    dataType));
-        }
-
-        this.scanlineStride = scanlineStride;
-        this.bitMasks = bitMasks.clone();
-        this.bitOffsets = new int[this.numBands];
-        this.bitSizes = new int[this.numBands];
-
-        this.maxBitSize = 0;
-
-        for (int i = 0; i < this.numBands; i++) {
-            int offset = 0;
-            int size = 0;
-            int mask = bitMasks[i];
-
-            if (mask != 0) {
-                while ((mask & 1) == 0) {
-                    mask >>>= 1;
-                    offset++;
-                }
-
-                while ((mask & 1) == 1) {
-                    mask >>>= 1;
-                    size++;
-                }
-
-                if (mask != 0) {
-                    // awt.62=Wrong mask : {0}
-                    throw new IllegalArgumentException(Messages.getString("awt.62", bitMasks[i])); //$NON-NLS-1$
-                }
-            }
-
-            this.bitOffsets[i] = offset;
-            this.bitSizes[i] = size;
-
-            if (this.maxBitSize < size) {
-                this.maxBitSize = size;
-            }
-
-        }
-
-    }
-
-    @Override
-    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        switch (getTransferType()) {
-            case DataBuffer.TYPE_BYTE:
-                byte bdata[];
-                if (obj == null) {
-                    bdata = new byte[1];
-                } else {
-                    bdata = (byte[])obj;
-                }
-
-                bdata[0] = (byte)data.getElem(y * scanlineStride + x);
-                obj = bdata;
-                break;
-            case DataBuffer.TYPE_USHORT:
-                short sdata[];
-                if (obj == null) {
-                    sdata = new short[1];
-                } else {
-                    sdata = (short[])obj;
-                }
-
-                sdata[0] = (short)data.getElem(y * scanlineStride + x);
-                obj = sdata;
-                break;
-            case DataBuffer.TYPE_INT:
-                int idata[];
-                if (obj == null) {
-                    idata = new int[1];
-                } else {
-                    idata = (int[])obj;
-                }
-
-                idata[0] = data.getElem(y * scanlineStride + x);
-                obj = idata;
-                break;
-        }
-        return obj;
-    }
-
-    @Override
-    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        switch (getTransferType()) {
-            case DataBuffer.TYPE_BYTE:
-                data.setElem(y * scanlineStride + x, ((byte[])obj)[0] & 0xff);
-                break;
-            case DataBuffer.TYPE_USHORT:
-                data.setElem(y * scanlineStride + x, ((short[])obj)[0] & 0xffff);
-                break;
-            case DataBuffer.TYPE_INT:
-                data.setElem(y * scanlineStride + x, ((int[])obj)[0]);
-                break;
-        }
-    }
-
-    /**
-     * Compares this SinglePixelPackedSampleModel object with the specified
-     * object.
-     * 
-     * @param o
-     *            the Object to be compared.
-     * @return true, if this SinglePixelPackedSampleModel object is equal to the
-     *         specified object, false otherwise.
-     */
-    @Override
-    public boolean equals(Object o) {
-        if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
-            return false;
-        }
-
-        SinglePixelPackedSampleModel model = (SinglePixelPackedSampleModel)o;
-        return this.width == model.width && this.height == model.height
-                && this.numBands == model.numBands && this.dataType == model.dataType
-                && Arrays.equals(this.bitMasks, model.bitMasks)
-                && Arrays.equals(this.bitOffsets, model.bitOffsets)
-                && Arrays.equals(this.bitSizes, model.bitSizes)
-                && this.scanlineStride == model.scanlineStride;
-    }
-
-    @Override
-    public SampleModel createSubsetSampleModel(int bands[]) {
-        if (bands.length > this.numBands) {
-            // awt.64=The number of the bands in the subset is greater than the
-            // number of bands in the sample model
-            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
-        }
-
-        int masks[] = new int[bands.length];
-        for (int i = 0; i < bands.length; i++) {
-            masks[i] = this.bitMasks[bands[i]];
-        }
-        return new SinglePixelPackedSampleModel(this.dataType, this.width, this.height,
-                this.scanlineStride, masks);
-    }
-
-    @Override
-    public SampleModel createCompatibleSampleModel(int w, int h) {
-        return new SinglePixelPackedSampleModel(this.dataType, w, h, this.bitMasks);
-    }
-
-    @Override
-    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int pixel[];
-        if (iArray == null) {
-            pixel = new int[this.numBands];
-        } else {
-            pixel = iArray;
-        }
-
-        for (int i = 0; i < this.numBands; i++) {
-            pixel[i] = getSample(x, y, i, data);
-        }
-
-        return pixel;
-    }
-
-    @Override
-    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        for (int i = 0; i < this.numBands; i++) {
-            setSample(x, y, i, iArray[i], data);
-        }
-    }
-
-    @Override
-    public int getSample(int x, int y, int b, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int sample = data.getElem(y * scanlineStride + x);
-        return ((sample & this.bitMasks[b]) >>> this.bitOffsets[b]);
-    }
-
-    @Override
-    public int[] getPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
-        if ((x < 0) || (y < 0) || ((long)x + (long)w > this.width)
-                || ((long)y + (long)h > this.height)) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        int pixels[];
-
-        if (iArray == null) {
-            pixels = new int[w * h * this.numBands];
-        } else {
-            pixels = iArray;
-        }
-
-        int idx = 0;
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < this.numBands; n++) {
-                    pixels[idx++] = getSample(j, i, n, data);
-                }
-            }
-        }
-        return pixels;
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
-        if ((x < 0) || (y < 0) || ((long)x + (long)w > this.width)
-                || ((long)y + (long)h > this.height)) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        int idx = 0;
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                for (int n = 0; n < this.numBands; n++) {
-                    setSample(j, i, n, iArray[idx++], data);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, int s, DataBuffer data) {
-        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-        int tmp = data.getElem(y * scanlineStride + x);
-        tmp &= ~this.bitMasks[b];
-        tmp |= (s << this.bitOffsets[b]) & this.bitMasks[b];
-        data.setElem(y * scanlineStride + x, tmp);
-    }
-
-    @Override
-    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
-        if ((x < 0) || (y < 0) || ((long)x + (long)w > this.width)
-                || ((long)y + (long)h > this.height)) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        int samples[];
-        int idx = 0;
-
-        if (iArray == null) {
-            samples = new int[w * h];
-        } else {
-            samples = iArray;
-        }
-
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                samples[idx++] = getSample(j, i, b, data);
-            }
-        }
-
-        return samples;
-    }
-
-    @Override
-    public void setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
-        if ((x < 0) || (y < 0) || ((long)x + (long)w > this.width)
-                || ((long)y + (long)h > this.height)) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        int idx = 0;
-        for (int i = y; i < y + h; i++) {
-            for (int j = x; j < x + w; j++) {
-                setSample(x + j, y + i, b, iArray[idx++], data);
-            }
-        }
-    }
-
-    @Override
-    public DataBuffer createDataBuffer() {
-        DataBuffer data = null;
-        int size = (this.height - 1) * scanlineStride + width;
-
-        switch (this.dataType) {
-            case DataBuffer.TYPE_BYTE:
-                data = new DataBufferByte(size);
-                break;
-            case DataBuffer.TYPE_USHORT:
-                data = new DataBufferUShort(size);
-                break;
-            case DataBuffer.TYPE_INT:
-                data = new DataBufferInt(size);
-                break;
-        }
-        return data;
-    }
-
-    /**
-     * Gets the offset of the specified pixel in the data array.
-     * 
-     * @param x
-     *            the X coordinate of the specified pixel.
-     * @param y
-     *            the Y coordinate of the specified pixel.
-     * @return the offset of the specified pixel.
-     */
-    public int getOffset(int x, int y) {
-        return (y * scanlineStride + x);
-    }
-
-    @Override
-    public int getSampleSize(int band) {
-        return bitSizes[band];
-    }
-
-    @Override
-    public int[] getSampleSize() {
-        return bitSizes.clone();
-    }
-
-    /**
-     * Gets an array of the bit offsets of the data array elements.
-     * 
-     * @return an array of the bit offsets.
-     */
-    public int[] getBitOffsets() {
-        return bitOffsets.clone();
-    }
-
-    /**
-     * Gets an array of the bit masks for all bands.
-     * 
-     * @return an array of the bit masks for all bands.
-     */
-    public int[] getBitMasks() {
-        return bitMasks.clone();
-    }
-
-    /**
-     * Returns a hash code of this MultiPixelPackedSampleModel class.
-     * 
-     * @return the hash code of this MultiPixelPackedSampleModel class.
-     */
-    @Override
-    public int hashCode() {
-        int hash = 0;
-        int tmp = 0;
-
-        hash = width;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= height;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= numBands;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        hash ^= dataType;
-        tmp = hash >>> 24;
-        hash <<= 8;
-        hash |= tmp;
-        for (int element : bitMasks) {
-            hash ^= element;
-            tmp = hash >>> 24;
-            hash <<= 8;
-            hash |= tmp;
-        }
-        for (int element : bitOffsets) {
-            hash ^= element;
-            tmp = hash >>> 24;
-            hash <<= 8;
-            hash |= tmp;
-        }
-        for (int element : bitSizes) {
-            hash ^= element;
-            tmp = hash >>> 24;
-            hash <<= 8;
-            hash |= tmp;
-        }
-        hash ^= scanlineStride;
-        return hash;
-    }
-
-    /**
-     * Gets the scanline stride.
-     * 
-     * @return the scanline stride
-     */
-    public int getScanlineStride() {
-        return this.scanlineStride;
-    }
-
-    @Override
-    public int getNumDataElements() {
-        return 1;
-    }
-
-}
diff --git a/awt/java/awt/image/TileObserver.java b/awt/java/awt/image/TileObserver.java
deleted file mode 100644
index 7dd97e2..0000000
--- a/awt/java/awt/image/TileObserver.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-/**
- * An asynchronous update interface for receiving notifications about tile
- * information when tiles of a WritableRenderedImage become modifiable or
- * unmodifiable.
- * 
- * @since Android 1.0
- */
-public interface TileObserver {
-
-    /**
-     * This method is called when information about a tile update is available.
-     * 
-     * @param source
-     *            the source image.
-     * @param tileX
-     *            the X index of the tile.
-     * @param tileY
-     *            the Y index of the tile.
-     * @param willBeWritable
-     *            parameter which indicates whether the tile will be grabbed for
-     *            writing or be released.
-     */
-    public void tileUpdate(WritableRenderedImage source, int tileX, int tileY,
-            boolean willBeWritable);
-
-}
diff --git a/awt/java/awt/image/VolatileImage.java b/awt/java/awt/image/VolatileImage.java
deleted file mode 100644
index f24e866..0000000
--- a/awt/java/awt/image/VolatileImage.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.GraphicsConfiguration;
-import java.awt.Image;
-import java.awt.ImageCapabilities;
-import java.awt.Transparency;
-
-/**
- * The VolatileImage abstract class represents an image which can lose its
- * contents at any point. VolatileImage objects are device specific. This class
- * provides methods for checking if operation of this image are compatible for
- * the GraphicsConfiguration.
- * 
- * @since Android 1.0
- */
-public abstract class VolatileImage extends Image
-// Volatile image implements Transparency since 1.5
-        implements Transparency {
-
-    /**
-     * The Constant IMAGE_INCOMPATIBLE indicates that this VolatileImage is not
-     * applicable for the GraphicsConfiguration object.
-     */
-    public static final int IMAGE_INCOMPATIBLE = 2;
-
-    /**
-     * The Constant IMAGE_OK indicates that VolatileImage is ready for using.
-     */
-    public static final int IMAGE_OK = 0;
-
-    /**
-     * The Constant IMAGE_RESTORED indicates that VolatileImage will be ready to
-     * use after restoring.
-     */
-    public static final int IMAGE_RESTORED = 1;
-
-    /**
-     * The transparency value of this image.
-     */
-    protected int transparency = OPAQUE;
-
-    /**
-     * Instantiates a new VolatileImage object.
-     */
-    public VolatileImage() {
-        super();
-    }
-
-    /**
-     * Returns true if rendering data is lost during validating. This method
-     * should be called after rendering operation of image.
-     * 
-     * @return true, if contents lost during validating, false otherwise.
-     */
-
-    public abstract boolean contentsLost();
-
-    /**
-     * Creates a Graphics2D used to draw in this VolatileImage.
-     * 
-     * @return the Graphics2D object.
-     */
-    public abstract Graphics2D createGraphics();
-
-    /**
-     * Gets the ImageCapabilities of this VolatileImage.
-     * 
-     * @return the ImageCapabilities of this VolatileImage.
-     */
-    public abstract ImageCapabilities getCapabilities();
-
-    /**
-     * Gets the height of this VolatileImage.
-     * 
-     * @return the height of this VolatileImage.
-     */
-    public abstract int getHeight();
-
-    /**
-     * Gets a BufferedImage representation of current VolatileImage that won't
-     * be affected by any changes to this VolatileImage.
-     * 
-     * @return a BufferedImage representation of current VolatileImage.
-     */
-    public abstract BufferedImage getSnapshot();
-
-    /**
-     * Gets the width of this VolatileImage.
-     * 
-     * @return the width of this VolatileImage.
-     */
-    public abstract int getWidth();
-
-    /**
-     * Validates the drawing surface of the image if the surface had been lost
-     * and if the specified GraphicsConfiguration object is applicable to this
-     * image.
-     * 
-     * @param gc
-     *            the GraphicsConfiguration object.
-     * @return one of the image status constants: IMAGE_OK, IMAGE_RESTORED or
-     *         IMAGE_INCOMPATIBLE.
-     */
-    public abstract int validate(GraphicsConfiguration gc);
-
-    @Override
-    public void flush() {
-    }
-
-    @Override
-    public Graphics getGraphics() {
-        return createGraphics();
-    }
-
-    @Override
-    public ImageProducer getSource() {
-        return getSnapshot().getSource();
-    }
-
-    public int getTransparency() {
-        return transparency;
-    }
-}
diff --git a/awt/java/awt/image/WritableRaster.java b/awt/java/awt/image/WritableRaster.java
deleted file mode 100644
index 51366ee..0000000
--- a/awt/java/awt/image/WritableRaster.java
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The WritableRaster class provides functionality for writing samples and pixel
- * capabilities to the Raster.
- * 
- * @since Android 1.0
- */
-public class WritableRaster extends Raster {
-
-    /**
-     * Instantiates a new WritableRaster object with the specified SampleModel,
-     * DataBuffer, rectangular region and parent WritableRaster.
-     * 
-     * @param sampleModel
-     *            the specified SampleModel.
-     * @param dataBuffer
-     *            the specified DataBuffer.
-     * @param aRegion
-     *            the rectangular region which defines the new image bounds.
-     * @param sampleModelTranslate
-     *            this point defines the translation point from the SampleModel
-     *            to the new WritableRaster coordinates.
-     * @param parent
-     *            the parent of this WritableRaster.
-     */
-    protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, Rectangle aRegion,
-            Point sampleModelTranslate, WritableRaster parent) {
-        super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
-    }
-
-    /**
-     * Instantiates a new WritableRaster object with the specified SampleModel
-     * which defines a layout of this WritableRaster and DataBuffer objects
-     * which defines the image data.
-     * 
-     * @param sampleModel
-     *            the specified SampleModel.
-     * @param dataBuffer
-     *            the specified DataBuffer.
-     * @param origin
-     *            the point of origin.
-     */
-    protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin) {
-        this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y, sampleModel.width,
-                sampleModel.height), origin, null);
-    }
-
-    /**
-     * Instantiates a new WritableRaster with the specified SampleModel.
-     * 
-     * @param sampleModel
-     *            the specified SampleModel.
-     * @param origin
-     *            the origin.
-     */
-    protected WritableRaster(SampleModel sampleModel, Point origin) {
-        this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(origin.x, origin.y,
-                sampleModel.width, sampleModel.height), origin, null);
-    }
-
-    /**
-     * Sets the data for a single pixel from an input Object which represents an
-     * array of primitive types: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
-     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
-     * DataBuffer.TYPE_DOUBLE.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param inData
-     *            the input data.
-     */
-    public void setDataElements(int x, int y, Object inData) {
-        sampleModel.setDataElements(x - sampleModelTranslateX, y - sampleModelTranslateY, inData,
-                dataBuffer);
-    }
-
-    /**
-     * Sets the data elements which represent pixel data to the specified
-     * rectangle area as a primitive array. The following image data types are
-     * supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
-     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
-     * DataBuffer.TYPE_DOUBLE.
-     * 
-     * @param x
-     *            the X coordinate of the rectangle of pixels.
-     * @param y
-     *            the Y coordinate of the rectangle of pixels.
-     * @param w
-     *            the width of the rectangle of pixels.
-     * @param h
-     *            the height of the rectangle of pixels.
-     * @param inData
-     *            the array of primitive type data to be set to the specified
-     *            area.
-     */
-    public void setDataElements(int x, int y, int w, int h, Object inData) {
-        sampleModel.setDataElements(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
-                inData, dataBuffer);
-    }
-
-    /**
-     * Creates the child of this WritableRaster by sharing the specified
-     * rectangular area in this WritableRaster. The parentX, parentY, width and
-     * height parameters specify rectangular area to be shared.
-     * 
-     * @param parentX
-     *            the X coordinate of the upper left corner of the shared
-     *            rectangle with respect to this WritableRaster' coordinates.
-     * @param parentY
-     *            the Y coordinate of the upper left corner of the shared
-     *            rectangle with respect to this WritableRaster' coordinates.
-     * @param w
-     *            the width of the child area.
-     * @param h
-     *            the height of the child area.
-     * @param childMinX
-     *            the X coordinate of child area mapped to the parentX
-     *            coordinate.
-     * @param childMinY
-     *            the Y coordinate of child area mapped to the parentY
-     *            coordinate.
-     * @param bandList
-     *            the array of band indices.
-     * @return the child WritableRaster.
-     */
-    public WritableRaster createWritableChild(int parentX, int parentY, int w, int h,
-            int childMinX, int childMinY, int bandList[]) {
-        if (w <= 0 || h <= 0) {
-            // awt.244=Width or Height of child Raster is less than or equal to
-            // zero
-            throw new RasterFormatException(Messages.getString("awt.244")); //$NON-NLS-1$
-        }
-
-        if (parentX < this.minX || parentX + w > this.minX + this.width) {
-            // awt.245=parentX disposes outside Raster
-            throw new RasterFormatException(Messages.getString("awt.245")); //$NON-NLS-1$
-        }
-
-        if (parentY < this.minY || parentY + h > this.minY + this.height) {
-            // awt.246=parentY disposes outside Raster
-            throw new RasterFormatException(Messages.getString("awt.246")); //$NON-NLS-1$
-        }
-
-        if ((long)parentX + w > Integer.MAX_VALUE) {
-            // awt.247=parentX + w results in integer overflow
-            throw new RasterFormatException(Messages.getString("awt.247")); //$NON-NLS-1$
-        }
-
-        if ((long)parentY + h > Integer.MAX_VALUE) {
-            // awt.248=parentY + h results in integer overflow
-            throw new RasterFormatException(Messages.getString("awt.248")); //$NON-NLS-1$
-        }
-
-        if ((long)childMinX + w > Integer.MAX_VALUE) {
-            // awt.249=childMinX + w results in integer overflow
-            throw new RasterFormatException(Messages.getString("awt.249")); //$NON-NLS-1$
-        }
-
-        if ((long)childMinY + h > Integer.MAX_VALUE) {
-            // awt.24A=childMinY + h results in integer overflow
-            throw new RasterFormatException(Messages.getString("awt.24A")); //$NON-NLS-1$
-        }
-
-        SampleModel childModel;
-
-        if (bandList == null) {
-            childModel = sampleModel;
-        } else {
-            childModel = sampleModel.createSubsetSampleModel(bandList);
-        }
-
-        int childTranslateX = childMinX - parentX;
-        int childTranslateY = childMinY - parentY;
-
-        return new WritableRaster(childModel, dataBuffer,
-                new Rectangle(childMinX, childMinY, w, h), new Point(childTranslateX
-                        + sampleModelTranslateX, childTranslateY + sampleModelTranslateY), this);
-    }
-
-    /**
-     * Creates the translated child of this WritableRaster. New WritableRaster
-     * object is a reference to the this WritableRaster and with different
-     * location.
-     * 
-     * @param childMinX
-     *            the X coordinate of the new WritableRaster.
-     * @param childMinY
-     *            the Y coordinate of the new WritableRaster.
-     * @return the WritableRaster.
-     */
-    public WritableRaster createWritableTranslatedChild(int childMinX, int childMinY) {
-        return createWritableChild(minX, minY, width, height, childMinX, childMinY, null);
-    }
-
-    /**
-     * Gets the parent WritableRaster for this WritableRaster object.
-     * 
-     * @return the parent WritableRaster for this WritableRaster object.
-     */
-    public WritableRaster getWritableParent() {
-        return (WritableRaster)parent;
-    }
-
-    /**
-     * Sets pixels from the specified source Raster srcRaster to this
-     * WritableRaster.
-     * 
-     * @param srcRaster
-     *            the source Raster.
-     */
-    public void setRect(Raster srcRaster) {
-        setRect(0, 0, srcRaster);
-    }
-
-    /**
-     * Sets pixels from the specified source Raster srcRaster to this
-     * WritableRaster. Each pixel with (x, y) coordinates from the source Raster
-     * is copied to pixel with (x+dx, y+dy) coordinates in this WritableRaster.
-     * The pixels with (x+dx, y+dy) coordinates which are out the bounds of this
-     * raster are ignored.
-     * 
-     * @param dx
-     *            the distance the pixel's X coordinate in the source Raster is
-     *            translated when writtien to this WritableRaster.
-     * @param dy
-     *            the distance the pixel's Y coordinate in the source Raster is
-     *            translated when writtien to this WritableRaster.
-     * @param srcRaster
-     *            the source Raster.
-     */
-    public void setRect(int dx, int dy, Raster srcRaster) {
-        int w = srcRaster.getWidth();
-        int h = srcRaster.getHeight();
-
-        int srcX = srcRaster.getMinX();
-        int srcY = srcRaster.getMinY();
-
-        int dstX = srcX + dx;
-        int dstY = srcY + dy;
-
-        if (dstX < this.minX) {
-            int minOffX = this.minX - dstX;
-            w -= minOffX;
-            dstX = this.minX;
-            srcX += minOffX;
-        }
-
-        if (dstY < this.minY) {
-            int minOffY = this.minY - dstY;
-            h -= minOffY;
-            dstY = this.minY;
-            srcY += minOffY;
-        }
-
-        if (dstX + w > this.minX + this.width) {
-            int maxOffX = (dstX + w) - (this.minX + this.width);
-            w -= maxOffX;
-        }
-
-        if (dstY + h > this.minY + this.height) {
-            int maxOffY = (dstY + h) - (this.minY + this.height);
-            h -= maxOffY;
-        }
-
-        if (w <= 0 || h <= 0) {
-            return;
-        }
-
-        switch (sampleModel.getDataType()) {
-            case DataBuffer.TYPE_BYTE:
-            case DataBuffer.TYPE_SHORT:
-            case DataBuffer.TYPE_USHORT:
-            case DataBuffer.TYPE_INT:
-                int iPixelsLine[] = null;
-                for (int i = 0; i < h; i++) {
-                    iPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1, iPixelsLine);
-                    setPixels(dstX, dstY + i, w, 1, iPixelsLine);
-                }
-                break;
-
-            case DataBuffer.TYPE_FLOAT:
-                float fPixelsLine[] = null;
-                for (int i = 0; i < h; i++) {
-                    fPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1, fPixelsLine);
-                    setPixels(dstX, dstY + i, w, 1, fPixelsLine);
-                }
-                break;
-
-            case DataBuffer.TYPE_DOUBLE:
-                double dPixelsLine[] = null;
-                for (int i = 0; i < h; i++) {
-                    dPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1, dPixelsLine);
-                    setPixels(dstX, dstY + i, w, 1, dPixelsLine);
-                }
-                break;
-        }
-    }
-
-    /**
-     * Sets the data for a rectangle of pixels from an input Raster to this
-     * WritableRaster.
-     * 
-     * @param x
-     *            the X coordinate of the point where the data of the input
-     *            Raster is to be written.
-     * @param y
-     *            the Y coordinate of the point where the data of the input
-     *            Raster is to be written.
-     * @param inRaster
-     *            the input Raster.
-     */
-    public void setDataElements(int x, int y, Raster inRaster) {
-        int dstX = x + inRaster.getMinX();
-        int dstY = y + inRaster.getMinY();
-
-        int w = inRaster.getWidth();
-        int h = inRaster.getHeight();
-
-        if (dstX < this.minX || dstX + w > this.minX + this.width || dstY < this.minY
-                || dstY + h > this.minY + this.height) {
-            // awt.63=Coordinates are not in bounds
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
-        }
-
-        int srcX = inRaster.getMinX();
-        int srcY = inRaster.getMinY();
-        Object line = null;
-
-        for (int i = 0; i < h; i++) {
-            line = inRaster.getDataElements(srcX, srcY + i, w, 1, line);
-            setDataElements(dstX, dstY + i, w, 1, line);
-        }
-    }
-
-    /**
-     * Sets an integer array of samples for the specified pixel in this
-     * WritableRaster.
-     * 
-     * @param x
-     *            the pixel's X coordinate.
-     * @param y
-     *            the pixel's Y coordinate.
-     * @param iArray
-     *            the integer array of samples.
-     */
-    public void setPixel(int x, int y, int iArray[]) {
-        sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, iArray,
-                dataBuffer);
-    }
-
-    /**
-     * Sets a float array of samples for the specified pixel in this
-     * WritableRaster.
-     * 
-     * @param x
-     *            the pixel's X coordinate.
-     * @param y
-     *            the pixel's Y coordinate.
-     * @param fArray
-     *            the float array of samples.
-     */
-    public void setPixel(int x, int y, float fArray[]) {
-        sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, fArray,
-                dataBuffer);
-    }
-
-    /**
-     * Sets a double array of samples for the specified pixel in this
-     * WritableRaster.
-     * 
-     * @param x
-     *            the pixel's X coordinate.
-     * @param y
-     *            the pixel's Y coordinate.
-     * @param dArray
-     *            the double array of samples.
-     */
-    public void setPixel(int x, int y, double dArray[]) {
-        sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, dArray,
-                dataBuffer);
-    }
-
-    /**
-     * Sets a integer array of samples for the specified rectangular area of
-     * pixels in this WritableRaster.
-     * 
-     * @param x
-     *            the X coordinate of rectangular area.
-     * @param y
-     *            the Y coordinate of rectangular area.
-     * @param w
-     *            the width of rectangular area.
-     * @param h
-     *            the height of rectangular area.
-     * @param iArray
-     *            the integer array of samples.
-     */
-    public void setPixels(int x, int y, int w, int h, int iArray[]) {
-        sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, iArray,
-                dataBuffer);
-    }
-
-    /**
-     * Sets a float array of samples for the specified rectangular area of
-     * pixels in this WritableRaster.
-     * 
-     * @param x
-     *            the X coordinate of rectangular area.
-     * @param y
-     *            the Y coordinate of rectangular area.
-     * @param w
-     *            the width of rectangular area.
-     * @param h
-     *            the height of rectangular area.
-     * @param fArray
-     *            the float array of samples.
-     */
-    public void setPixels(int x, int y, int w, int h, float fArray[]) {
-        sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, fArray,
-                dataBuffer);
-    }
-
-    /**
-     * Sets a double array of samples for the specified rectangular area of
-     * pixels in this WritableRaster.
-     * 
-     * @param x
-     *            the X coordinate of rectangular area.
-     * @param y
-     *            the Y coordinate of rectangular area.
-     * @param w
-     *            the width of rectangular area.
-     * @param h
-     *            the height of rectangular area.
-     * @param dArray
-     *            the double array of samples.
-     */
-    public void setPixels(int x, int y, int w, int h, double dArray[]) {
-        sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, dArray,
-                dataBuffer);
-    }
-
-    /**
-     * Sets the samples for the specified band and the specified rectangular
-     * area of pixels with an integer array of samples.
-     * 
-     * @param x
-     *            the X coordinate of the area of pixels.
-     * @param y
-     *            the Y coordinate of the area of pixels.
-     * @param w
-     *            the width of the area of pixels.
-     * @param h
-     *            the height of the area of pixels.
-     * @param b
-     *            the specified band.
-     * @param iArray
-     *            the integer array of samples.
-     */
-    public void setSamples(int x, int y, int w, int h, int b, int iArray[]) {
-        sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, b,
-                iArray, dataBuffer);
-    }
-
-    /**
-     * Sets the samples for the specified band and the specified rectangular
-     * area of pixels with a float array of samples.
-     * 
-     * @param x
-     *            the X coordinate of the area of pixels.
-     * @param y
-     *            the Y coordinate of the area of pixels.
-     * @param w
-     *            the width of the area of pixels.
-     * @param h
-     *            the height of the area of pixels.
-     * @param b
-     *            the specified band.
-     * @param fArray
-     *            the float array of samples.
-     */
-    public void setSamples(int x, int y, int w, int h, int b, float fArray[]) {
-        sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, b,
-                fArray, dataBuffer);
-    }
-
-    /**
-     * Sets the samples for the specified band and the specified rectangular
-     * area of pixels with a double array of samples.
-     * 
-     * @param x
-     *            the X coordinate of the area of pixels.
-     * @param y
-     *            the Y coordinate of the area of pixels.
-     * @param w
-     *            the width of the area of pixels.
-     * @param h
-     *            the height of the area of pixels.
-     * @param b
-     *            the specified band.
-     * @param dArray
-     *            the double array of samples.
-     */
-    public void setSamples(int x, int y, int w, int h, int b, double dArray[]) {
-        sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, b,
-                dArray, dataBuffer);
-    }
-
-    /**
-     * Sets the sample for the specified band and the specified pixel with an
-     * integer sample.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param b
-     *            the specified band.
-     * @param s
-     *            the sample to be set.
-     */
-    public void setSample(int x, int y, int b, int s) {
-        sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b, s,
-                dataBuffer);
-    }
-
-    /**
-     * Sets the sample for the specified band and the specified pixel with a
-     * float sample.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param b
-     *            the specified band.
-     * @param s
-     *            the sample to be set.
-     */
-    public void setSample(int x, int y, int b, float s) {
-        sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b, s,
-                dataBuffer);
-    }
-
-    /**
-     * Sets the sample for the specified band and the specified pixel with an
-     * integer sample.
-     * 
-     * @param x
-     *            the X coordinate of the pixel.
-     * @param y
-     *            the Y coordinate of the pixel.
-     * @param b
-     *            the specified band.
-     * @param s
-     *            the sample to be set.
-     */
-    public void setSample(int x, int y, int b, double s) {
-        sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b, s,
-                dataBuffer);
-    }
-
-}
diff --git a/awt/java/awt/image/WritableRenderedImage.java b/awt/java/awt/image/WritableRenderedImage.java
deleted file mode 100644
index 052353b..0000000
--- a/awt/java/awt/image/WritableRenderedImage.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image;
-
-import java.awt.Point;
-
-/**
- * The WriteableRenderedImage interface is interface for objects which contains
- * Raster data of one or several tiles. This interface provides notification
- * mechanism for obtaining tile's writing status.
- * 
- * @since Android 1.0
- */
-public interface WritableRenderedImage extends RenderedImage {
-
-    /**
-     * Gets and checks out the writable tile for writing.
-     * 
-     * @param tileX
-     *            the X index of the tile.
-     * @param tileY
-     *            the Y index of the tile.
-     * @return the WritableRaster.
-     */
-    public WritableRaster getWritableTile(int tileX, int tileY);
-
-    /**
-     * Removes the registered TileObserver.
-     * 
-     * @param to
-     *            the TileObserver which is registered for this
-     *            WritableRenderedImage.
-     */
-    public void removeTileObserver(TileObserver to);
-
-    /**
-     * Adds the specified TileObserver to this WritableRenderedImage.
-     * 
-     * @param to
-     *            the TileObserver object to be added.
-     */
-    public void addTileObserver(TileObserver to);
-
-    /**
-     * Sets this image to the contents of the specified Raster.
-     * 
-     * @param r
-     *            the specified Raster.
-     */
-    public void setData(Raster r);
-
-    /**
-     * Gets the array of points which represent indices of tiles which are check
-     * out for writing.
-     * 
-     * @return the array of points.
-     */
-    public Point[] getWritableTileIndices();
-
-    /**
-     * Checks if the specified tile is writable or not.
-     * 
-     * @param tileX
-     *            the X index of tile.
-     * @param tileY
-     *            the Y index of tile.
-     * @return true, if the specified tile is writable, false otherwise.
-     */
-    public boolean isTileWritable(int tileX, int tileY);
-
-    /**
-     * Release the specified writable tile. This method removes the writer from
-     * the tile.
-     * 
-     * @param tileX
-     *            the X index of the tile.
-     * @param tileY
-     *            the Y index of the tile.
-     */
-    public void releaseWritableTile(int tileX, int tileY);
-
-    /**
-     * Checks if there is a tile which is checked out for writing.
-     * 
-     * @return true, if any tile is checked out for writing, false if there is
-     *         no such tile.
-     */
-    public boolean hasTileWriters();
-
-}
diff --git a/awt/java/awt/image/package.html b/awt/java/awt/image/package.html
deleted file mode 100644
index b4d6ef0..0000000
--- a/awt/java/awt/image/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes and interfaces that allow to modify existing images or to create a new image rather than loading it from a file.
-    </p>
-   @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java b/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
deleted file mode 100644
index 1881a0c2..0000000
--- a/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image.renderable;
-
-import java.awt.geom.Rectangle2D;
-import java.awt.image.RenderedImage;
-
-/**
- * A factory for creating ContextualRenderedImage objects with utilities for
- * manipulating the properties in the parameter block.
- * 
- * @since Android 1.0
- */
-public interface ContextualRenderedImageFactory extends RenderedImageFactory {
-
-    /**
-     * Maps a render context to a parameter block and a renderable image.
-     * 
-     * @param a0
-     *            the index.
-     * @param a1
-     *            the RenderContext.
-     * @param a2
-     *            the ParameterBlock.
-     * @param a3
-     *            the RenderableImage.
-     * @return the render context.
-     */
-    public RenderContext mapRenderContext(int a0, RenderContext a1, ParameterBlock a2,
-            RenderableImage a3);
-
-    /**
-     * Gets the value of the property from the parameter block.
-     * 
-     * @param a0
-     *            the parameter block to examine to find the property.
-     * @param a1
-     *            the name of the property.
-     * @return the value of the property.
-     */
-    public Object getProperty(ParameterBlock a0, String a1);
-
-    /**
-     * Creates the rendered image determined by the render context and parameter
-     * block.
-     * 
-     * @param a0
-     *            the RenderContext.
-     * @param a1
-     *            the ParameterBlock.
-     * @return the rendered image.
-     */
-    public RenderedImage create(RenderContext a0, ParameterBlock a1);
-
-    /**
-     * Gets the bounding rectangle from the parameter block.
-     * 
-     * @param a0
-     *            the parameter block to read the bounds from.
-     * @return the bounding rectangle.
-     */
-    public Rectangle2D getBounds2D(ParameterBlock a0);
-
-    /**
-     * Gets the names of all of the supported properties.
-     * 
-     * @return the property names.
-     */
-    public String[] getPropertyNames();
-
-    /**
-     * Checks if this image factory is dynamic.
-     * 
-     * @return true, if this image factory is dynamic.
-     */
-    public boolean isDynamic();
-
-}
diff --git a/awt/java/awt/image/renderable/ParameterBlock.java b/awt/java/awt/image/renderable/ParameterBlock.java
deleted file mode 100644
index 7dde73a..0000000
--- a/awt/java/awt/image/renderable/ParameterBlock.java
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image.renderable;
-
-import java.awt.image.RenderedImage;
-import java.io.Serializable;
-import java.util.Vector;
-
-/**
- * The class ParameterBlock groups an indexed set of parameter data with a set
- * of renderable (source) images. The mapping between the indexed parameters and
- * their property names is provided by a {@link ContextualRenderedImageFactory}.
- * 
- * @since Android 1.0
- */
-public class ParameterBlock implements Cloneable, Serializable {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -7577115551785240750L;
-
-    /**
-     * The sources (renderable images).
-     */
-    protected Vector<Object> sources = new Vector<Object>();
-
-    /**
-     * The parameters.
-     */
-    protected Vector<Object> parameters = new Vector<Object>();
-
-    /**
-     * Instantiates a new parameter block.
-     * 
-     * @param sources
-     *            the vector of source images.
-     * @param parameters
-     *            the vector of parameters.
-     */
-    public ParameterBlock(Vector<Object> sources, Vector<Object> parameters) {
-        setSources(sources);
-        setParameters(parameters);
-    }
-
-    /**
-     * Instantiates a new parameter block with no parameters.
-     * 
-     * @param sources
-     *            the vector of source images.
-     */
-    public ParameterBlock(Vector<Object> sources) {
-        setSources(sources);
-    }
-
-    /**
-     * Instantiates a new parameter block with no image or parameter vectors.
-     */
-    public ParameterBlock() {
-    }
-
-    /**
-     * Sets the source image at the specified index.
-     * 
-     * @param source
-     *            the source image.
-     * @param index
-     *            the index where the source will be placed.
-     * @return this parameter block.
-     */
-    public ParameterBlock setSource(Object source, int index) {
-        if (sources.size() < index + 1) {
-            sources.setSize(index + 1);
-        }
-        sources.setElementAt(source, index);
-        return this;
-    }
-
-    /**
-     * Sets the parameter value object at the specified index.
-     * 
-     * @param obj
-     *            the parameter value to place at the desired index.
-     * @param index
-     *            the index where the object is to be placed in the vector of
-     *            parameters.
-     * @return this parameter block.
-     */
-    public ParameterBlock set(Object obj, int index) {
-        if (parameters.size() < index + 1) {
-            parameters.setSize(index + 1);
-        }
-        parameters.setElementAt(obj, index);
-        return this;
-    }
-
-    /**
-     * Adds a source to the vector of sources.
-     * 
-     * @param source
-     *            the source to add.
-     * @return this parameter block.
-     */
-    public ParameterBlock addSource(Object source) {
-        sources.addElement(source);
-        return this;
-    }
-
-    /**
-     * Adds the object to the vector of parameter values
-     * 
-     * @param obj
-     *            the obj to add.
-     * @return this parameter block.
-     */
-    public ParameterBlock add(Object obj) {
-        parameters.addElement(obj);
-        return this;
-    }
-
-    /**
-     * Sets the vector of sources, replacing the existing vector of sources, if
-     * any.
-     * 
-     * @param sources
-     *            the new sources.
-     */
-    public void setSources(Vector<Object> sources) {
-        this.sources = sources;
-    }
-
-    /**
-     * Sets the vector of parameters, replacing the existing vector of
-     * parameters, if any.
-     * 
-     * @param parameters
-     *            the new parameters.
-     */
-    public void setParameters(Vector<Object> parameters) {
-        this.parameters = parameters;
-    }
-
-    /**
-     * Gets the vector of sources.
-     * 
-     * @return the sources.
-     */
-    public Vector<Object> getSources() {
-        return sources;
-    }
-
-    /**
-     * Gets the vector of parameters.
-     * 
-     * @return the parameters.
-     */
-    public Vector<Object> getParameters() {
-        return parameters;
-    }
-
-    /**
-     * Gets the source at the specified index.
-     * 
-     * @param index
-     *            the index.
-     * @return the source object found at the specified index.
-     */
-    public Object getSource(int index) {
-        return sources.elementAt(index);
-    }
-
-    /**
-     * Gets the object parameter found at the specified index.
-     * 
-     * @param index
-     *            the index.
-     * @return the parameter object found at the specified index.
-     */
-    public Object getObjectParameter(int index) {
-        return parameters.elementAt(index);
-    }
-
-    /**
-     * Shallow clone (clones using the superclass clone method).
-     * 
-     * @return the clone of this object.
-     */
-    public Object shallowClone() {
-        try {
-            return super.clone();
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    /**
-     * Returns a copy of this ParameterBlock instance.
-     * 
-     * @return the identical copy of this instance.
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public Object clone() {
-        ParameterBlock replica;
-        try {
-            replica = (ParameterBlock)super.clone();
-        } catch (Exception e) {
-            return null;
-        }
-        if (sources != null) {
-            replica.setSources((Vector<Object>)(sources.clone()));
-        }
-        if (parameters != null) {
-            replica.setParameters((Vector<Object>)(parameters.clone()));
-        }
-        return replica;
-    }
-
-    /**
-     * Gets an array of classes corresponding to all of the parameter values
-     * found in the array of parameters, in order.
-     * 
-     * @return the parameter classes.
-     */
-    public Class[] getParamClasses() {
-        int count = parameters.size();
-        Class paramClasses[] = new Class[count];
-
-        for (int i = 0; i < count; i++) {
-            paramClasses[i] = parameters.elementAt(i).getClass();
-        }
-        return paramClasses;
-    }
-
-    /**
-     * Gets the renderable source image found at the specified index in the
-     * source array.
-     * 
-     * @param index
-     *            the index.
-     * @return the renderable source image.
-     */
-    public RenderableImage getRenderableSource(int index) {
-        return (RenderableImage)sources.elementAt(index);
-    }
-
-    /**
-     * Wraps the short value in a Short and places it in the parameter block at
-     * the specified index.
-     * 
-     * @param s
-     *            the short value of the parameter.
-     * @param index
-     *            the index.
-     * @return this parameter block.
-     */
-    public ParameterBlock set(short s, int index) {
-        return set(new Short(s), index);
-    }
-
-    /**
-     * Wraps the short value in a Short and adds it to the parameter block.
-     * 
-     * @param s
-     *            the short value of the parameter.
-     * @return this parameter block.
-     */
-    public ParameterBlock add(short s) {
-        return add(new Short(s));
-    }
-
-    /**
-     * Wraps the long value in a Long and places it in the parameter block at
-     * the specified index.
-     * 
-     * @param l
-     *            the long value of the parameter.
-     * @param index
-     *            the index.
-     * @return this parameter block.
-     */
-    public ParameterBlock set(long l, int index) {
-        return set(new Long(l), index);
-    }
-
-    /**
-     * Wraps the long value in a Long and adds it to the parameter block.
-     * 
-     * @param l
-     *            the long value of the parameter.
-     * @return this parameter block.
-     */
-    public ParameterBlock add(long l) {
-        return add(new Long(l));
-    }
-
-    /**
-     * Wraps the integer value in an Integer and places it in the parameter
-     * block at the specified index.
-     * 
-     * @param i
-     *            the integer value of the parameter.
-     * @param index
-     *            the index.
-     * @return this parameter block.
-     */
-    public ParameterBlock set(int i, int index) {
-        return set(new Integer(i), index);
-    }
-
-    /**
-     * Wraps the integer value in an Integer and adds it to the parameter block.
-     * 
-     * @param i
-     *            the integer value of the parameter.
-     * @return this parameter block.
-     */
-    public ParameterBlock add(int i) {
-        return add(new Integer(i));
-    }
-
-    /**
-     * Wraps the float value in a Float and places it in the parameter block at
-     * the specified index.
-     * 
-     * @param f
-     *            the float value of the parameter.
-     * @param index
-     *            the index.
-     * @return this parameter block.
-     */
-    public ParameterBlock set(float f, int index) {
-        return set(new Float(f), index);
-    }
-
-    /**
-     * Wraps the float value in a Float and adds it to the parameter block.
-     * 
-     * @param f
-     *            the float value of the parameter.
-     * @return this parameter block.
-     */
-    public ParameterBlock add(float f) {
-        return add(new Float(f));
-    }
-
-    /**
-     * Wraps the double value in a Double and places it in the parameter block
-     * at the specified index.
-     * 
-     * @param d
-     *            the double value of the parameter.
-     * @param index
-     *            the index.
-     * @return this parameter block.
-     */
-    public ParameterBlock set(double d, int index) {
-        return set(new Double(d), index);
-    }
-
-    /**
-     * Wraps the double value in a Double and adds it to the parameter block.
-     * 
-     * @param d
-     *            the double value of the parameter.
-     * @return this parameter block.
-     */
-    public ParameterBlock add(double d) {
-        return add(new Double(d));
-    }
-
-    /**
-     * Wraps the char value in a Character and places it in the parameter block
-     * at the specified index.
-     * 
-     * @param c
-     *            the char value of the parameter.
-     * @param index
-     *            the index.
-     * @return this parameter block.
-     */
-    public ParameterBlock set(char c, int index) {
-        return set(new Character(c), index);
-    }
-
-    /**
-     * Wraps the char value in a Character and adds it to the parameter block.
-     * 
-     * @param c
-     *            the char value of the parameter.
-     * @return this parameter block.
-     */
-    public ParameterBlock add(char c) {
-        return add(new Character(c));
-    }
-
-    /**
-     * Wraps the byte value in a Byte and places it in the parameter block at
-     * the specified index.
-     * 
-     * @param b
-     *            the byte value of the parameter.
-     * @param index
-     *            the index.
-     * @return this parameter block.
-     */
-    public ParameterBlock set(byte b, int index) {
-        return set(new Byte(b), index);
-    }
-
-    /**
-     * Wraps the byte value in a Byte and adds it to the parameter block.
-     * 
-     * @param b
-     *            the byte value of the parameter.
-     * @return the parameter block.
-     */
-    public ParameterBlock add(byte b) {
-        return add(new Byte(b));
-    }
-
-    /**
-     * Gets the RenderedImage at the specified index from the vector of source
-     * images.
-     * 
-     * @param index
-     *            the index.
-     * @return the rendered image.
-     */
-    public RenderedImage getRenderedSource(int index) {
-        return (RenderedImage)sources.elementAt(index);
-    }
-
-    /**
-     * Gets the short-valued parameter found at the desired index in the vector
-     * of parameter values.
-     * 
-     * @param index
-     *            the index.
-     * @return the short parameter.
-     */
-    public short getShortParameter(int index) {
-        return ((Short)parameters.elementAt(index)).shortValue();
-    }
-
-    /**
-     * Gets the long-valued parameter found at the desired index in the vector
-     * of parameter values.
-     * 
-     * @param index
-     *            the index.
-     * @return the long parameter.
-     */
-    public long getLongParameter(int index) {
-        return ((Long)parameters.elementAt(index)).longValue();
-    }
-
-    /**
-     * Gets the integer-valued parameter found at the desired index in the
-     * vector of parameter values.
-     * 
-     * @param index
-     *            the index.
-     * @return the integer parameter.
-     */
-    public int getIntParameter(int index) {
-        return ((Integer)parameters.elementAt(index)).intValue();
-    }
-
-    /**
-     * Gets the float-valued parameter found at the desired index in the vector
-     * of parameter values.
-     * 
-     * @param index
-     *            the index.
-     * @return the float parameter.
-     */
-    public float getFloatParameter(int index) {
-        return ((Float)parameters.elementAt(index)).floatValue();
-    }
-
-    /**
-     * Gets the double-valued parameter found at the desired index in the vector
-     * of parameter values.
-     * 
-     * @param index
-     *            the index.
-     * @return the double parameter.
-     */
-    public double getDoubleParameter(int index) {
-        return ((Double)parameters.elementAt(index)).doubleValue();
-    }
-
-    /**
-     * Gets the char-valued parameter found at the desired index in the vector
-     * of parameter values.
-     * 
-     * @param index
-     *            the index.
-     * @return the char parameter.
-     */
-    public char getCharParameter(int index) {
-        return ((Character)parameters.elementAt(index)).charValue();
-    }
-
-    /**
-     * Gets the byte-valued parameter found at the desired index in the vector
-     * of parameter values.
-     * 
-     * @param index
-     *            the index.
-     * @return the byte parameter.
-     */
-    public byte getByteParameter(int index) {
-        return ((Byte)parameters.elementAt(index)).byteValue();
-    }
-
-    /**
-     * Clears the vector of sources.
-     */
-    public void removeSources() {
-        sources.removeAllElements();
-    }
-
-    /**
-     * Clears the vector of parameters.
-     */
-    public void removeParameters() {
-        parameters.removeAllElements();
-    }
-
-    /**
-     * Gets the number of elements in the vector of sources.
-     * 
-     * @return the number of elements in the vector of sources.
-     */
-    public int getNumSources() {
-        return sources.size();
-    }
-
-    /**
-     * Gets the number of elements in the vector of parameters.
-     * 
-     * @return the number of elements in the vector of parameters.
-     */
-    public int getNumParameters() {
-        return parameters.size();
-    }
-}
diff --git a/awt/java/awt/image/renderable/RenderContext.java b/awt/java/awt/image/renderable/RenderContext.java
deleted file mode 100644
index 0db512f..0000000
--- a/awt/java/awt/image/renderable/RenderContext.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image.renderable;
-
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-
-/**
- * The Class RenderContext stores data on how an image is to be rendered: the
- * affine transform, the area of interest, and the rendering hints.
- * 
- * @since Android 1.0
- */
-public class RenderContext implements Cloneable {
-
-    /**
-     * The affine transform.
-     */
-    AffineTransform transform;
-
-    /**
-     * The area of interest.
-     */
-    Shape aoi;
-
-    /**
-     * The rendering hints.
-     */
-    RenderingHints hints;
-
-    /**
-     * Instantiates a new render context.
-     * 
-     * @param usr2dev
-     *            the affine transform.
-     * @param aoi
-     *            the area of interest.
-     * @param hints
-     *            the rendering hints.
-     */
-    public RenderContext(AffineTransform usr2dev, Shape aoi, RenderingHints hints) {
-        this.transform = (AffineTransform)usr2dev.clone();
-        this.aoi = aoi;
-        this.hints = hints;
-    }
-
-    /**
-     * Instantiates a new render context with no specified hints.
-     * 
-     * @param usr2dev
-     *            the affine transform.
-     * @param aoi
-     *            the area of interest.
-     */
-    public RenderContext(AffineTransform usr2dev, Shape aoi) {
-        this(usr2dev, aoi, null);
-    }
-
-    /**
-     * Instantiates a new render context with no specified area of interest.
-     * 
-     * @param usr2dev
-     *            the affine transform.
-     * @param hints
-     *            the rendering hints.
-     */
-    public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
-        this(usr2dev, null, hints);
-    }
-
-    /**
-     * Instantiates a new render context with no rendering hints or area of
-     * interest.
-     * 
-     * @param usr2dev
-     *            the affine transform.
-     */
-    public RenderContext(AffineTransform usr2dev) {
-        this(usr2dev, null, null);
-    }
-
-    @Override
-    public Object clone() {
-        return new RenderContext(transform, aoi, hints);
-    }
-
-    /**
-     * Sets the affine transform for this render context.
-     * 
-     * @param newTransform
-     *            the new affine transform.
-     */
-    public void setTransform(AffineTransform newTransform) {
-        transform = (AffineTransform)newTransform.clone();
-    }
-
-    /**
-     * Concatenates the current transform with the specified transform (so they
-     * are applied with the specified transform acting first) and sets the
-     * resulting transform as the affine transform of this rendering context.
-     * 
-     * @param modTransform
-     *            the new transform which modifies the current transform.
-     * @deprecated use
-     *             {@link RenderContext#preConcatenateTransform(AffineTransform)}
-     *             .
-     */
-    @Deprecated
-    public void preConcetenateTransform(AffineTransform modTransform) {
-        preConcatenateTransform(modTransform);
-    }
-
-    /**
-     * Concatenates the current transform with the specified transform (so they
-     * are applied with the specified transform acting first) and sets the
-     * resulting transform as the affine transform of this rendering context.
-     * 
-     * @param modTransform
-     *            the new transform which modifies the current transform.
-     */
-    public void preConcatenateTransform(AffineTransform modTransform) {
-        transform.preConcatenate(modTransform);
-    }
-
-    /**
-     * Concatenate the specified transform with the current transform.
-     * 
-     * @param modTransform
-     *            the new transform which modifies the current transform.
-     * @deprecated use
-     *             {@link RenderContext#concatenateTransform(AffineTransform)}.
-     */
-    @Deprecated
-    public void concetenateTransform(AffineTransform modTransform) {
-        concatenateTransform(modTransform);
-    }
-
-    /**
-     * Concatenate the specified transform with the current transform.
-     * 
-     * @param modTransform
-     *            the new transform which modifies the current transform.
-     */
-    public void concatenateTransform(AffineTransform modTransform) {
-        transform.concatenate(modTransform);
-    }
-
-    /**
-     * Gets the transform.
-     * 
-     * @return the transform.
-     */
-    public AffineTransform getTransform() {
-        return (AffineTransform)transform.clone();
-    }
-
-    /**
-     * Sets the area of interest.
-     * 
-     * @param newAoi
-     *            the new area of interest.
-     */
-    public void setAreaOfInterest(Shape newAoi) {
-        aoi = newAoi;
-    }
-
-    /**
-     * Gets the area of interest.
-     * 
-     * @return the area of interest.
-     */
-    public Shape getAreaOfInterest() {
-        return aoi;
-    }
-
-    /**
-     * Sets the rendering hints.
-     * 
-     * @param hints
-     *            the new rendering hints.
-     */
-    public void setRenderingHints(RenderingHints hints) {
-        this.hints = hints;
-    }
-
-    /**
-     * Gets the rendering hints.
-     * 
-     * @return the rendering hints.
-     */
-    public RenderingHints getRenderingHints() {
-        return hints;
-    }
-}
diff --git a/awt/java/awt/image/renderable/RenderableImage.java b/awt/java/awt/image/renderable/RenderableImage.java
deleted file mode 100644
index 21332f7..0000000
--- a/awt/java/awt/image/renderable/RenderableImage.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image.renderable;
-
-import java.awt.RenderingHints;
-import java.awt.image.RenderedImage;
-import java.util.Vector;
-
-/**
- * The Interface RenderableImage is implemented by an object that collects all
- * of the image-specific data that defines a single image that could be rendered
- * to different rendering targets.
- * 
- * @since Android 1.0
- */
-public interface RenderableImage {
-
-    /**
-     * The Constant HINTS_OBSERVED indicates that the rendering hints are
-     * applied rather than ignored.
-     */
-    public static final String HINTS_OBSERVED = "HINTS_OBSERVED"; //$NON-NLS-1$
-
-    /**
-     * Gets the property from the RenderableImage's parameter block.
-     * 
-     * @param name
-     *            the name of the property to get.
-     * @return the value of the property.
-     */
-    public Object getProperty(String name);
-
-    /**
-     * Creates the rendered image based on the information contained in the
-     * parameters and the render context.
-     * 
-     * @param renderContext
-     *            the render context giving rendering specifications such as
-     *            transformations.
-     * @return the rendered image.
-     */
-    public RenderedImage createRendering(RenderContext renderContext);
-
-    /**
-     * Creates the scaled rendered image based on the information contained in
-     * the parameters and the render context.
-     * 
-     * @param w
-     *            the desired width after scaling or zero if the scaling should
-     *            be proportional, based on the height.
-     * @param h
-     *            the desired height after scaling or zero if the scaling should
-     *            be proportional, based on the width.
-     * @param hints
-     *            the rendering hints to use.
-     * @return the rendered image.
-     * @throws IllegalArgumentException
-     *             if both the height and width are zero.
-     */
-    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
-
-    /**
-     * Gets the vector of sources from the parameter block.
-     * 
-     * @return the sources.
-     */
-    public Vector<RenderableImage> getSources();
-
-    /**
-     * Gets the names of all of the supported properties in the current context.
-     * 
-     * @return the property names.
-     */
-    public String[] getPropertyNames();
-
-    /**
-     * Creates the default rendering (using the identity transform and default
-     * render context).
-     * 
-     * @return the rendered image.
-     */
-    public RenderedImage createDefaultRendering();
-
-    /**
-     * Checks if this context supports dynamic rendering.
-     * 
-     * @return true, if this context supports dynamic rendering.
-     */
-    public boolean isDynamic();
-
-    /**
-     * Gets the width of the image.
-     * 
-     * @return the width of the image.
-     */
-    public float getWidth();
-
-    /**
-     * Gets the y coordinate of the upper left corner.
-     * 
-     * @return the y coordinate of the upper left corner.
-     */
-    public float getMinY();
-
-    /**
-     * Gets the x coordinate of the upper left corner.
-     * 
-     * @return the x coordinate of the upper left corner.
-     */
-    public float getMinX();
-
-    /**
-     * Gets the height of the image.
-     * 
-     * @return the height of the image.
-     */
-    public float getHeight();
-
-}
diff --git a/awt/java/awt/image/renderable/RenderableImageOp.java b/awt/java/awt/image/renderable/RenderableImageOp.java
deleted file mode 100644
index dc453727..0000000
--- a/awt/java/awt/image/renderable/RenderableImageOp.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image.renderable;
-
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.RenderedImage;
-import java.util.Vector;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * The Class RenderableImageOp is a basic implementation of RenderableImage,
- * with methods to access the parameter data and perform rendering operations.
- * 
- * @since Android 1.0
- */
-public class RenderableImageOp implements RenderableImage {
-
-    /**
-     * The CRIF.
-     */
-    ContextualRenderedImageFactory CRIF;
-
-    /**
-     * The param block.
-     */
-    ParameterBlock paramBlock;
-
-    /**
-     * The height.
-     */
-    float minX, minY, width, height;
-
-    /**
-     * Instantiates a new renderable image op.
-     * 
-     * @param CRIF
-     *            the cRIF.
-     * @param paramBlock
-     *            the param block.
-     */
-    public RenderableImageOp(ContextualRenderedImageFactory CRIF, ParameterBlock paramBlock) {
-        this.CRIF = CRIF;
-        this.paramBlock = (ParameterBlock)paramBlock.clone();
-        Rectangle2D r = CRIF.getBounds2D(paramBlock);
-        minX = (float)r.getMinX();
-        minY = (float)r.getMinY();
-        width = (float)r.getWidth();
-        height = (float)r.getHeight();
-    }
-
-    public Object getProperty(String name) {
-        return CRIF.getProperty(paramBlock, name);
-    }
-
-    /**
-     * Sets the parameter block.
-     * 
-     * @param paramBlock
-     *            the param block.
-     * @return the parameter block.
-     */
-    public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
-        ParameterBlock oldParam = this.paramBlock;
-        this.paramBlock = (ParameterBlock)paramBlock.clone();
-        return oldParam;
-    }
-
-    public RenderedImage createRendering(RenderContext renderContext) {
-
-        Vector<RenderableImage> sources = getSources();
-        ParameterBlock rdParam = (ParameterBlock)paramBlock.clone();
-
-        if (sources != null) {
-            Vector<Object> rdSources = new Vector<Object>();
-            int i = 0;
-            while (i < sources.size()) {
-                RenderContext newContext = CRIF
-                        .mapRenderContext(i, renderContext, paramBlock, this);
-                RenderedImage rdim = sources.elementAt(i).createRendering(newContext);
-
-                if (rdim != null) {
-                    rdSources.addElement(rdim);
-                }
-                i++;
-            }
-            if (rdSources.size() > 0) {
-                rdParam.setSources(rdSources);
-            }
-        }
-        return CRIF.create(renderContext, rdParam);
-    }
-
-    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints) {
-        if (w == 0 && h == 0) {
-            // awt.60=Width and Height mustn't be equal zero both
-            throw new IllegalArgumentException(Messages.getString("awt.60")); //$NON-NLS-1$
-        }
-        if (w == 0) {
-            w = Math.round(h * (getWidth() / getHeight()));
-        }
-
-        if (h == 0) {
-            h = Math.round(w * (getHeight() / getWidth()));
-        }
-
-        double sx = (double)w / getWidth();
-        double sy = (double)h / getHeight();
-
-        AffineTransform at = AffineTransform.getScaleInstance(sx, sy);
-        RenderContext context = new RenderContext(at, hints);
-        return createRendering(context);
-    }
-
-    public Vector<RenderableImage> getSources() {
-        if (paramBlock.getNumSources() == 0) {
-            return null;
-        }
-        Vector<RenderableImage> v = new Vector<RenderableImage>();
-        int i = 0;
-        while (i < paramBlock.getNumSources()) {
-            Object o = paramBlock.getSource(i);
-            if (o instanceof RenderableImage) {
-                v.addElement((RenderableImage)o);
-            }
-            i++;
-        }
-        return v;
-    }
-
-    public String[] getPropertyNames() {
-        return CRIF.getPropertyNames();
-    }
-
-    /**
-     * Gets the parameter block.
-     * 
-     * @return the parameter block
-     */
-    public ParameterBlock getParameterBlock() {
-        return paramBlock;
-    }
-
-    public RenderedImage createDefaultRendering() {
-        AffineTransform at = new AffineTransform();
-        RenderContext context = new RenderContext(at);
-        return createRendering(context);
-    }
-
-    public boolean isDynamic() {
-        return CRIF.isDynamic();
-    }
-
-    public float getWidth() {
-        return width;
-    }
-
-    public float getMinY() {
-        return minY;
-    }
-
-    public float getMinX() {
-        return minX;
-    }
-
-    public float getHeight() {
-        return height;
-    }
-
-}
diff --git a/awt/java/awt/image/renderable/RenderableImageProducer.java b/awt/java/awt/image/renderable/RenderableImageProducer.java
deleted file mode 100644
index e83ebc7..0000000
--- a/awt/java/awt/image/renderable/RenderableImageProducer.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image.renderable;
-
-import java.awt.image.ColorModel;
-import java.awt.image.ImageConsumer;
-import java.awt.image.ImageProducer;
-import java.awt.image.Raster;
-import java.awt.image.RenderedImage;
-import java.util.Vector;
-
-/**
- * The Class RenderableImageProducer provides the implementation for the image
- * rendering.
- * 
- * @since Android 1.0
- */
-public class RenderableImageProducer implements ImageProducer, Runnable {
-
-    /**
-     * The rbl.
-     */
-    RenderableImage rbl;
-
-    /**
-     * The rc.
-     */
-    RenderContext rc;
-
-    /**
-     * The consumers.
-     */
-    Vector<ImageConsumer> consumers = new Vector<ImageConsumer>();
-
-    /**
-     * Instantiates a new renderable image producer.
-     * 
-     * @param rdblImage
-     *            the rdbl image.
-     * @param rc
-     *            the rc.
-     */
-    public RenderableImageProducer(RenderableImage rdblImage, RenderContext rc) {
-        this.rbl = rdblImage;
-        this.rc = rc;
-    }
-
-    /**
-     * Sets the render context.
-     * 
-     * @param rc
-     *            the new render context.
-     */
-    public synchronized void setRenderContext(RenderContext rc) {
-        this.rc = rc;
-    }
-
-    public synchronized boolean isConsumer(ImageConsumer ic) {
-        return consumers.contains(ic);
-    }
-
-    public synchronized void startProduction(ImageConsumer ic) {
-        addConsumer(ic);
-        Thread t = new Thread(this, "RenderableImageProducer thread"); //$NON-NLS-1$
-        t.start();
-    }
-
-    public void requestTopDownLeftRightResend(ImageConsumer ic) {
-    }
-
-    public synchronized void removeConsumer(ImageConsumer ic) {
-        if (ic != null) {
-            consumers.removeElement(ic);
-        }
-    }
-
-    public synchronized void addConsumer(ImageConsumer ic) {
-        if (ic != null && !consumers.contains(ic)) {
-            consumers.addElement(ic);
-        }
-    }
-
-    /**
-     * Creates the rendered image in a new thread.
-     */
-    public void run() {
-        if (rbl == null) {
-            return;
-        }
-
-        RenderedImage rd;
-        if (rc != null) {
-            rd = rbl.createRendering(rc);
-        } else {
-            rd = rbl.createDefaultRendering();
-        }
-
-        ColorModel cm = rd.getColorModel();
-        if (cm == null) {
-            cm = ColorModel.getRGBdefault();
-        }
-
-        Raster r = rd.getData();
-        int w = r.getWidth();
-        int h = r.getHeight();
-
-        for (ImageConsumer c : consumers) {
-            c.setDimensions(w, h);
-            c.setHints(ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES
-                    | ImageConsumer.SINGLEFRAME | ImageConsumer.SINGLEPASS);
-        }
-
-        int scanLine[] = new int[w];
-        int pixel[] = null;
-
-        for (int y = 0; y < h; y++) {
-            for (int x = 0; x < w; x++) {
-                pixel = r.getPixel(x, y, pixel);
-                scanLine[x] = cm.getDataElement(pixel, 0);
-            }
-
-            for (ImageConsumer c : consumers) {
-                c.setPixels(0, y, w, 1, cm, scanLine, 0, w);
-            }
-        }
-
-        for (ImageConsumer c : consumers) {
-            c.imageComplete(ImageConsumer.STATICIMAGEDONE);
-        }
-    }
-
-}
diff --git a/awt/java/awt/image/renderable/RenderedImageFactory.java b/awt/java/awt/image/renderable/RenderedImageFactory.java
deleted file mode 100644
index 881a40a..0000000
--- a/awt/java/awt/image/renderable/RenderedImageFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package java.awt.image.renderable;
-
-import java.awt.RenderingHints;
-import java.awt.image.RenderedImage;
-
-/**
- * A factory for creating RenderedImage objects based on parameters and
- * rendering hints.
- * 
- * @since Android 1.0
- */
-public interface RenderedImageFactory {
-
-    /**
-     * Creates the rendered image.
-     * 
-     * @param a0
-     *            the ParameterBlock.
-     * @param a1
-     *            the RenderingHints.
-     * @return the rendered image.
-     */
-    public RenderedImage create(ParameterBlock a0, RenderingHints a1);
-
-}
diff --git a/awt/java/awt/image/renderable/package.html b/awt/java/awt/image/renderable/package.html
deleted file mode 100644
index 43aaabc..0000000
--- a/awt/java/awt/image/renderable/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes to create images which are rendering-independent.
-    </p>
-    @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/package.html b/awt/java/awt/package.html
deleted file mode 100644
index 5a6f9f0..0000000
--- a/awt/java/awt/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes and interfaces for creating (graphical) user interfaces (GUI), painting 2D graphics and creating, manipulating and drawing images. 
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/peer/ButtonPeer.java b/awt/java/awt/peer/ButtonPeer.java
deleted file mode 100644
index cc45b49..0000000
--- a/awt/java/awt/peer/ButtonPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface ButtonPeer {
-
-}
diff --git a/awt/java/awt/peer/CanvasPeer.java b/awt/java/awt/peer/CanvasPeer.java
deleted file mode 100644
index e276366..0000000
--- a/awt/java/awt/peer/CanvasPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface CanvasPeer {
-
-}
diff --git a/awt/java/awt/peer/CheckboxMenuItemPeer.java b/awt/java/awt/peer/CheckboxMenuItemPeer.java
deleted file mode 100644
index 296f422..0000000
--- a/awt/java/awt/peer/CheckboxMenuItemPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface CheckboxMenuItemPeer {
-
-}
diff --git a/awt/java/awt/peer/CheckboxPeer.java b/awt/java/awt/peer/CheckboxPeer.java
deleted file mode 100644
index e9f8dd1..0000000
--- a/awt/java/awt/peer/CheckboxPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface CheckboxPeer {
-
-}
diff --git a/awt/java/awt/peer/ChoicePeer.java b/awt/java/awt/peer/ChoicePeer.java
deleted file mode 100644
index 57b7629..0000000
--- a/awt/java/awt/peer/ChoicePeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface ChoicePeer {
-
-}
diff --git a/awt/java/awt/peer/ComponentPeer.java b/awt/java/awt/peer/ComponentPeer.java
deleted file mode 100644
index bc26791..0000000
--- a/awt/java/awt/peer/ComponentPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface ComponentPeer {
-
-}
diff --git a/awt/java/awt/peer/DialogPeer.java b/awt/java/awt/peer/DialogPeer.java
deleted file mode 100644
index 8ae3049..0000000
--- a/awt/java/awt/peer/DialogPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface DialogPeer {
-
-}
diff --git a/awt/java/awt/peer/FileDialogPeer.java b/awt/java/awt/peer/FileDialogPeer.java
deleted file mode 100644
index 0d15e48..0000000
--- a/awt/java/awt/peer/FileDialogPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface FileDialogPeer {
-
-}
diff --git a/awt/java/awt/peer/FontPeer.java b/awt/java/awt/peer/FontPeer.java
deleted file mode 100644
index fd9815f..0000000
--- a/awt/java/awt/peer/FontPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface FontPeer {
-
-}
diff --git a/awt/java/awt/peer/FramePeer.java b/awt/java/awt/peer/FramePeer.java
deleted file mode 100644
index 9cfc40b..0000000
--- a/awt/java/awt/peer/FramePeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface FramePeer {
-
-}
diff --git a/awt/java/awt/peer/LabelPeer.java b/awt/java/awt/peer/LabelPeer.java
deleted file mode 100644
index 052ca9d..0000000
--- a/awt/java/awt/peer/LabelPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface LabelPeer {
-
-}
diff --git a/awt/java/awt/peer/LightweightPeer.java b/awt/java/awt/peer/LightweightPeer.java
deleted file mode 100644
index 1dee905..0000000
--- a/awt/java/awt/peer/LightweightPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface LightweightPeer {
-
-}
diff --git a/awt/java/awt/peer/ListPeer.java b/awt/java/awt/peer/ListPeer.java
deleted file mode 100644
index 0a27885..0000000
--- a/awt/java/awt/peer/ListPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface ListPeer {
-
-}
diff --git a/awt/java/awt/peer/MenuBarPeer.java b/awt/java/awt/peer/MenuBarPeer.java
deleted file mode 100644
index 3ad2c16..0000000
--- a/awt/java/awt/peer/MenuBarPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface MenuBarPeer {
-
-}
diff --git a/awt/java/awt/peer/MenuComponentPeer.java b/awt/java/awt/peer/MenuComponentPeer.java
deleted file mode 100644
index 3ac3b34..0000000
--- a/awt/java/awt/peer/MenuComponentPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface MenuComponentPeer {
-
-}
diff --git a/awt/java/awt/peer/MenuItemPeer.java b/awt/java/awt/peer/MenuItemPeer.java
deleted file mode 100644
index b133897..0000000
--- a/awt/java/awt/peer/MenuItemPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface MenuItemPeer {
-
-}
diff --git a/awt/java/awt/peer/MenuPeer.java b/awt/java/awt/peer/MenuPeer.java
deleted file mode 100644
index d643ce72..0000000
--- a/awt/java/awt/peer/MenuPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface MenuPeer {
-
-}
diff --git a/awt/java/awt/peer/MouseInfoPeer.java b/awt/java/awt/peer/MouseInfoPeer.java
deleted file mode 100644
index 9173a62..0000000
--- a/awt/java/awt/peer/MouseInfoPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface MouseInfoPeer {
-
-}
diff --git a/awt/java/awt/peer/PanelPeer.java b/awt/java/awt/peer/PanelPeer.java
deleted file mode 100644
index 1faa1fe..0000000
--- a/awt/java/awt/peer/PanelPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface PanelPeer {
-
-}
diff --git a/awt/java/awt/peer/PopupMenuPeer.java b/awt/java/awt/peer/PopupMenuPeer.java
deleted file mode 100644
index cf1ef61..0000000
--- a/awt/java/awt/peer/PopupMenuPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface PopupMenuPeer {
-
-}
diff --git a/awt/java/awt/peer/ScrollPanePeer.java b/awt/java/awt/peer/ScrollPanePeer.java
deleted file mode 100644
index df3de83..0000000
--- a/awt/java/awt/peer/ScrollPanePeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface ScrollPanePeer {
-
-}
diff --git a/awt/java/awt/peer/ScrollbarPeer.java b/awt/java/awt/peer/ScrollbarPeer.java
deleted file mode 100644
index eec8961..0000000
--- a/awt/java/awt/peer/ScrollbarPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface ScrollbarPeer {
-
-}
diff --git a/awt/java/awt/peer/TextAreaPeer.java b/awt/java/awt/peer/TextAreaPeer.java
deleted file mode 100644
index 636707f..0000000
--- a/awt/java/awt/peer/TextAreaPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface TextAreaPeer {
-
-}
diff --git a/awt/java/awt/peer/TextFieldPeer.java b/awt/java/awt/peer/TextFieldPeer.java
deleted file mode 100644
index 2b8232a..0000000
--- a/awt/java/awt/peer/TextFieldPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface TextFieldPeer {
-
-}
diff --git a/awt/java/awt/peer/WindowPeer.java b/awt/java/awt/peer/WindowPeer.java
deleted file mode 100644
index 384646f..0000000
--- a/awt/java/awt/peer/WindowPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package java.awt.peer;
-
-public interface WindowPeer {
-
-}
diff --git a/awt/java/beans/FeatureDescriptor.java b/awt/java/beans/FeatureDescriptor.java
deleted file mode 100644
index 2945c65..0000000
--- a/awt/java/beans/FeatureDescriptor.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES 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.beans;
-
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-
-/**
- * Common base class for Descriptors.
- */
-public class FeatureDescriptor {
-
-    private Map<String, Object> values;
-
-    boolean preferred, hidden, expert;
-
-    String shortDescription;
-
-    String name;
-
-    String displayName;
-
-    /**
-     * <p>
-     * Constructs an instance.
-     * </p>
-     */
-    public FeatureDescriptor() {
-        this.values = new HashMap<String, Object>();
-    }
-
-    /**
-     * <p>
-     * Sets the value for the named attribute.
-     * </p>
-     * 
-     * @param attributeName
-     *            The name of the attribute to set a value with.
-     * @param value
-     *            The value to set.
-     */
-    public void setValue(String attributeName, Object value) {
-        if (attributeName == null || value == null) {
-            throw new NullPointerException();
-        }
-        values.put(attributeName, value);
-    }
-
-    /**
-     * <p>
-     * Gets the value associated with the named attribute.
-     * </p>
-     * 
-     * @param attributeName
-     *            The name of the attribute to get a value for.
-     * @return The attribute's value.
-     */
-    public Object getValue(String attributeName) {
-        Object result = null;
-        if (attributeName != null) {
-            result = values.get(attributeName);
-        }
-        return result;
-    }
-
-    /**
-     * <p>
-     * Enumerates the attribute names.
-     * </p>
-     * 
-     * @return An instance of {@link Enumeration}.
-     */
-    public Enumeration<String> attributeNames() {
-        // Create a new list, so that the references are copied
-        return Collections.enumeration(new LinkedList<String>(values.keySet()));
-    }
-
-    /**
-     * <p>
-     * Sets the short description.
-     * </p>
-     * 
-     * @param text
-     *            The description to set.
-     */
-    public void setShortDescription(String text) {
-        this.shortDescription = text;
-    }
-
-    /**
-     * <p>
-     * Sets the name.
-     * </p>
-     * 
-     * @param name
-     *            The name to set.
-     */
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    /**
-     * <p>
-     * Sets the display name.
-     * </p>
-     * 
-     * @param displayName
-     *            The display name to set.
-     */
-    public void setDisplayName(String displayName) {
-        this.displayName = displayName;
-    }
-
-    /**
-     * <p>
-     * Gets the short description or {@link #getDisplayName()} if not set.
-     * </p>
-     * 
-     * @return The description.
-     */
-    public String getShortDescription() {
-        return shortDescription == null ? getDisplayName() : shortDescription;
-    }
-
-    /**
-     * <p>
-     * Gets the name.
-     * </p>
-     * 
-     * @return The name.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * <p>
-     * Gets the display name or {@link #getName()} if not set.
-     * </p>
-     * 
-     * @return The display name.
-     */
-    public String getDisplayName() {
-        return displayName == null ? getName() : displayName;
-    }
-
-    /**
-     * <p>
-     * Sets the preferred indicator.
-     * </p>
-     * 
-     * @param preferred
-     *            <code>true</code> if preferred, <code>false</code>
-     *            otherwise.
-     */
-    public void setPreferred(boolean preferred) {
-        this.preferred = preferred;
-    }
-
-    /**
-     * <p>
-     * Sets the hidden indicator.
-     * </p>
-     * 
-     * @param hidden
-     *            <code>true</code> if hidden, <code>false</code> otherwise.
-     */
-    public void setHidden(boolean hidden) {
-        this.hidden = hidden;
-    }
-
-    /**
-     * <p>
-     * Sets the expert indicator.
-     * </p>
-     * 
-     * @param expert
-     *            <code>true</code> if expert, <code>false</code> otherwise.
-     */
-    public void setExpert(boolean expert) {
-        this.expert = expert;
-    }
-
-    /**
-     * <p>
-     * Indicates if this feature is preferred.
-     * </p>
-     * 
-     * @return <code>true</code> if preferred, <code>false</code> otherwise.
-     */
-    public boolean isPreferred() {
-        return preferred;
-    }
-
-    /**
-     * <p>
-     * Indicates if this feature is hidden.
-     * </p>
-     * 
-     * @return <code>true</code> if hidden, <code>false</code> otherwise.
-     */
-    public boolean isHidden() {
-        return hidden;
-    }
-
-    /**
-     * <p>
-     * Indicates if this feature is an expert feature.
-     * </p>
-     * 
-     * @return <code>true</code> if hidden, <code>false</code> otherwise.
-     */
-    public boolean isExpert() {
-        return expert;
-    }
-}
diff --git a/awt/java/beans/IndexedPropertyDescriptor.java b/awt/java/beans/IndexedPropertyDescriptor.java
deleted file mode 100644
index 25667d9..0000000
--- a/awt/java/beans/IndexedPropertyDescriptor.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.beans;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import org.apache.harmony.beans.internal.nls.Messages;
-
-public class IndexedPropertyDescriptor extends PropertyDescriptor {
-    private Method indexedGetter;
-
-    private Method indexedSetter;
-
-    public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass,
-            String getterName, String setterName, String indexedGetterName,
-            String indexedSetterName) throws IntrospectionException {
-        super(propertyName, beanClass, getterName, setterName);
-
-        // RI behaves like this
-        if (indexedGetterName == null && indexedSetterName == null &&
-                (getterName != null || setterName != null)) {
-            throw new IntrospectionException(Messages.getString("beans.50"));
-        }
-        setIndexedReadMethod(beanClass, indexedGetterName);
-        setIndexedWriteMethod(beanClass, indexedSetterName);
-    }
-
-    public IndexedPropertyDescriptor(String propertyName, Method getter, Method setter,
-            Method indexedGetter, Method indexedSetter) throws IntrospectionException {
-        super(propertyName, getter, setter);
-        
-        // we need this in order to be compatible with RI
-        if (indexedGetter == null && indexedSetter == null &&
-                (getter != null || setter != null)) {
-            throw new IntrospectionException(Messages.getString("beans.50"));
-        }
-        setIndexedReadMethod(indexedGetter);
-        setIndexedWriteMethod(indexedSetter);
-    }
-
-    public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass)
-            throws IntrospectionException {
-        super(propertyName, beanClass, null, null);
-        String getterName;
-        String setterName;
-        String indexedGetterName;
-        String indexedSetterName;
-
-        // array getter
-        getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
-        if (hasMethod(beanClass, getterName)) {
-            setReadMethod(beanClass, getterName);
-        }
-        // array setter
-        setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
-        if (hasMethod(beanClass, setterName)) {
-            setWriteMethod(beanClass, setterName);
-        }
-        // indexed getter
-        indexedGetterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
-        if (hasMethod(beanClass, indexedGetterName)) {
-            setIndexedReadMethod(beanClass, indexedGetterName);
-        }
-        // indexed setter
-        indexedSetterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
-        if (hasMethod(beanClass, indexedSetterName)) {
-            setIndexedWriteMethod(beanClass, indexedSetterName);
-        }
-        // RI seems to behave a bit differently
-        if (indexedGetter == null && indexedSetter == null &&
-                getReadMethod() == null && getWriteMethod() == null) {
-            throw new IntrospectionException(
-                    Messages.getString("beans.01", propertyName)); //$NON-NLS-1$
-        }
-        if (indexedGetter == null && indexedSetter == null) {
-            // not an indexed property indeed
-            throw new IntrospectionException(Messages.getString("beans.50"));
-        }
-    }
-
-    public void setIndexedReadMethod(Method indexedGetter) throws IntrospectionException {
-        if (indexedGetter != null) {
-            int modifiers = indexedGetter.getModifiers();
-            Class<?>[] parameterTypes;
-            Class<?> returnType;
-            Class<?> indexedPropertyType;
-
-            if (!Modifier.isPublic(modifiers)) {
-                throw new IntrospectionException(Messages.getString("beans.21")); //$NON-NLS-1$
-            }
-            parameterTypes = indexedGetter.getParameterTypes();
-            if (parameterTypes.length != 1) {
-                throw new IntrospectionException(Messages.getString("beans.22")); //$NON-NLS-1$
-            }
-            if (!parameterTypes[0].equals(int.class)) {
-                throw new IntrospectionException(Messages.getString("beans.23")); //$NON-NLS-1$
-            }
-            returnType = indexedGetter.getReturnType();
-            indexedPropertyType = getIndexedPropertyType();
-            if ((indexedPropertyType != null) && !returnType.equals(indexedPropertyType)) {
-                throw new IntrospectionException(Messages.getString("beans.24")); //$NON-NLS-1$
-            }
-        }
-        this.indexedGetter = indexedGetter;
-    }
-
-    public void setIndexedWriteMethod(Method indexedSetter) throws IntrospectionException {
-        if (indexedSetter != null) {
-            int modifiers = indexedSetter.getModifiers();
-            Class<?>[] parameterTypes;
-            Class<?> firstParameterType;
-            Class<?> secondParameterType;
-            Class<?> propType;
-
-            if (!Modifier.isPublic(modifiers)) {
-                throw new IntrospectionException(Messages.getString("beans.25")); //$NON-NLS-1$
-            }
-            parameterTypes = indexedSetter.getParameterTypes();
-            if (parameterTypes.length != 2) {
-                throw new IntrospectionException(Messages.getString("beans.26")); //$NON-NLS-1$
-            }
-            firstParameterType = parameterTypes[0];
-            if (!firstParameterType.equals(int.class)) {
-                throw new IntrospectionException(Messages.getString("beans.27")); //$NON-NLS-1$
-            }
-            secondParameterType = parameterTypes[1];
-            propType = getIndexedPropertyType();
-            if (propType != null && !secondParameterType.equals(propType)) {
-                throw new IntrospectionException(Messages.getString("beans.28")); //$NON-NLS-1$
-            }
-        }
-        this.indexedSetter = indexedSetter;
-    }
-
-    public Method getIndexedWriteMethod() {
-        return indexedSetter;
-    }
-
-    public Method getIndexedReadMethod() {
-        return indexedGetter;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        boolean result = super.equals(obj);
-        
-        if (result) {
-            IndexedPropertyDescriptor pd = (IndexedPropertyDescriptor) obj;
-    
-            if (indexedGetter != null) {
-                result = indexedGetter.equals(pd.getIndexedReadMethod());
-            } else if (result && indexedGetter == null) {
-                result = pd.getIndexedReadMethod() == null;
-            }
-                
-            if (result) {
-                if (indexedSetter != null) {
-                    result = indexedSetter.equals(pd.getIndexedWriteMethod());
-                } else if (indexedSetter == null) {
-                    result = pd.getIndexedWriteMethod() == null;
-                }
-            }
-        }
-            
-        return result;
-    }
-
-    public Class<?> getIndexedPropertyType() {
-        Class<?> result = null;
-
-        if (indexedGetter != null) {
-            result = indexedGetter.getReturnType();
-        } else if (indexedSetter != null) {
-            Class<?>[] parameterTypes = indexedSetter.getParameterTypes();
-
-            result = parameterTypes[1];
-        }
-        return result;
-    }
-
-    private void setIndexedReadMethod(Class<?> beanClass, String indexedGetterName) {
-        Method[] getters = findMethods(beanClass, indexedGetterName);
-        boolean result = false;
-
-        for (Method element : getters) {
-            try {
-                setIndexedReadMethod(element);
-                result = true;
-            } catch (IntrospectionException ie) {}
-
-            if (result) {
-                break;
-            }
-        }
-    }
-
-    private void setIndexedWriteMethod(Class<?> beanClass, String indexedSetterName) {
-        Method[] setters = findMethods(beanClass, indexedSetterName);
-        boolean result = false;
-
-        for (Method element : setters) {
-            try {
-                setIndexedWriteMethod(element);
-                result = true;
-            } catch (IntrospectionException ie) {}
-
-            if (result) {
-                break;
-            }
-        }
-    }
-}
diff --git a/awt/java/beans/IntrospectionException.java b/awt/java/beans/IntrospectionException.java
deleted file mode 100644
index c895afe..0000000
--- a/awt/java/beans/IntrospectionException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.beans;
-
-public class IntrospectionException extends Exception {
-
-    static final long serialVersionUID = -3728150539969542619L;
-
-    public IntrospectionException(String message) {
-        super(message);
-    }
-}
diff --git a/awt/java/beans/PropertyDescriptor.java b/awt/java/beans/PropertyDescriptor.java
deleted file mode 100644
index 9389152..0000000
--- a/awt/java/beans/PropertyDescriptor.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.beans;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Vector;
-import org.apache.harmony.beans.internal.nls.Messages;
-
-public class PropertyDescriptor extends FeatureDescriptor {
-    private Method getter;
-
-    private Method setter;
-
-    private Class<?> propertyEditorClass;
-
-    private boolean constrained;
-
-    private boolean bound;
-
-    public PropertyDescriptor(String propertyName, Class<?> beanClass, String getterName,
-            String setterName) throws IntrospectionException {
-        super();
-        if (beanClass == null) {
-            throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$
-        }
-        if (propertyName == null || propertyName.length() == 0) {
-            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
-        }
-        this.setName(propertyName);
-        this.setDisplayName(propertyName);
-        if (setterName != null) {
-            if (hasMethod(beanClass, setterName)) {
-                setWriteMethod(beanClass, setterName);
-            } else {
-                throw new IntrospectionException(Messages.getString("beans.20")); //$NON-NLS-1$
-            }
-        }
-        if (getterName != null) {
-            if (hasMethod(beanClass, getterName)) {
-                setReadMethod(beanClass, getterName);
-            } else {
-                throw new IntrospectionException(Messages.getString("beans.1F")); //$NON-NLS-1$
-            }
-        }
-    }
-
-    public PropertyDescriptor(String propertyName, Method getter, Method setter)
-            throws IntrospectionException {
-        super();
-        if (propertyName == null || propertyName.length() == 0) {
-            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
-        }
-        this.setName(propertyName);
-        this.setDisplayName(propertyName);
-        setWriteMethod(setter);
-        setReadMethod(getter);
-    }
-
-    public PropertyDescriptor(String propertyName, Class<?> beanClass)
-            throws IntrospectionException {
-        String getterName;
-        String setterName;
-        if (beanClass == null) {
-            throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$
-        }
-        if (propertyName == null || propertyName.length() == 0) {
-            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
-        }
-        this.setName(propertyName);
-        this.setDisplayName(propertyName);
-        getterName = createDefaultMethodName(propertyName, "is"); //$NON-NLS-1$
-        if (hasMethod(beanClass, getterName)) {
-            setReadMethod(beanClass, getterName);
-        } else {
-            getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
-            if (hasMethod(beanClass, getterName)) {
-                setReadMethod(beanClass, getterName);
-            }
-        }
-        setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
-        if (hasMethod(beanClass, setterName)) {
-            setWriteMethod(beanClass, setterName);
-        }
-        if (getter == null && setter == null) {
-            throw new IntrospectionException(Messages.getString("beans.01", propertyName)); //$NON-NLS-1$
-        }
-    }
-
-    public void setWriteMethod(Method setter) throws IntrospectionException {
-        if (setter != null) {
-            int modifiers = setter.getModifiers();
-            if (!Modifier.isPublic(modifiers)) {
-                throw new IntrospectionException(Messages.getString("beans.05")); //$NON-NLS-1$
-            }
-            Class<?>[] parameterTypes = setter.getParameterTypes();
-            if (parameterTypes.length != 1) {
-                throw new IntrospectionException(Messages.getString("beans.06")); //$NON-NLS-1$
-            }
-            Class<?> parameterType = parameterTypes[0];
-            Class<?> propertyType = getPropertyType();
-            if (propertyType != null && !propertyType.equals(parameterType)) {
-                throw new IntrospectionException(Messages.getString("beans.07")); //$NON-NLS-1$
-            }
-        }
-        this.setter = setter;
-    }
-
-    public void setReadMethod(Method getter) throws IntrospectionException {
-        if (getter != null) {
-            int modifiers = getter.getModifiers();
-            if (!Modifier.isPublic(modifiers)) {
-                throw new IntrospectionException(Messages.getString("beans.0A")); //$NON-NLS-1$
-            }
-            Class<?>[] parameterTypes = getter.getParameterTypes();
-            if (parameterTypes.length != 0) {
-                throw new IntrospectionException(Messages.getString("beans.08")); //$NON-NLS-1$
-            }
-            Class<?> returnType = getter.getReturnType();
-            if (returnType.equals(Void.TYPE)) {
-                throw new IntrospectionException(Messages.getString("beans.33")); //$NON-NLS-1$
-            }
-            Class<?> propertyType = getPropertyType();
-            if ((propertyType != null) && !returnType.equals(propertyType)) {
-                throw new IntrospectionException(Messages.getString("beans.09")); //$NON-NLS-1$
-            }
-        }
-        this.getter = getter;
-    }
-
-    public Method getWriteMethod() {
-        return setter;
-    }
-
-    public Method getReadMethod() {
-        return getter;
-    }
-
-    @Override
-    public boolean equals(Object object) {
-        boolean result = (object != null && object instanceof PropertyDescriptor);
-        if (result) {
-            PropertyDescriptor pd = (PropertyDescriptor) object;
-            boolean gettersAreEqual = (this.getter == null) && (pd.getReadMethod() == null)
-                    || (this.getter != null) && (this.getter.equals(pd.getReadMethod()));
-            boolean settersAreEqual = (this.setter == null) && (pd.getWriteMethod() == null)
-                    || (this.setter != null) && (this.setter.equals(pd.getWriteMethod()));
-            boolean propertyTypesAreEqual = this.getPropertyType() == pd.getPropertyType();
-            boolean propertyEditorClassesAreEqual = this.getPropertyEditorClass() == pd
-                    .getPropertyEditorClass();
-            boolean boundPropertyAreEqual = this.isBound() == pd.isBound();
-            boolean constrainedPropertyAreEqual = this.isConstrained() == pd.isConstrained();
-            result = gettersAreEqual && settersAreEqual && propertyTypesAreEqual
-                    && propertyEditorClassesAreEqual && boundPropertyAreEqual
-                    && constrainedPropertyAreEqual;
-        }
-        return result;
-    }
-
-    public void setPropertyEditorClass(Class<?> propertyEditorClass) {
-        this.propertyEditorClass = propertyEditorClass;
-    }
-
-    public Class<?> getPropertyType() {
-        Class<?> result = null;
-        if (getter != null) {
-            result = getter.getReturnType();
-        } else if (setter != null) {
-            Class<?>[] parameterTypes = setter.getParameterTypes();
-            result = parameterTypes[0];
-        }
-        return result;
-    }
-
-    public Class<?> getPropertyEditorClass() {
-        return propertyEditorClass;
-    }
-
-    public void setConstrained(boolean constrained) {
-        this.constrained = constrained;
-    }
-
-    public void setBound(boolean bound) {
-        this.bound = bound;
-    }
-
-    public boolean isConstrained() {
-        return constrained;
-    }
-
-    public boolean isBound() {
-        return bound;
-    }
-
-    boolean hasMethod(Class<?> beanClass, String methodName) {
-        Method[] methods = findMethods(beanClass, methodName);
-        return (methods.length > 0);
-    }
-
-    String createDefaultMethodName(String propertyName, String prefix) {
-        String result = null;
-        if (propertyName != null) {
-            String bos = propertyName.substring(0, 1).toUpperCase();
-            String eos = propertyName.substring(1, propertyName.length());
-            result = prefix + bos + eos;
-        }
-        return result;
-    }
-
-    Method[] findMethods(Class<?> aClass, String methodName) {
-        Method[] allMethods = aClass.getMethods();
-        Vector<Method> matchedMethods = new Vector<Method>();
-        Method[] result;
-        for (Method method : allMethods) {
-            if (method.getName().equals(methodName)) {
-                matchedMethods.add(method);
-            }
-        }
-        result = new Method[matchedMethods.size()];
-        for (int j = 0; j < matchedMethods.size(); ++j) {
-            result[j] = matchedMethods.elementAt(j);
-        }
-        return result;
-    }
-
-    void setReadMethod(Class<?> beanClass, String getterName) {
-        boolean result = false;
-        Method[] getters = findMethods(beanClass, getterName);
-        for (Method element : getters) {
-            try {
-                setReadMethod(element);
-                result = true;
-            } catch (IntrospectionException ie) {
-            }
-            if (result) {
-                break;
-            }
-        }
-    }
-
-    void setWriteMethod(Class<?> beanClass, String setterName) throws IntrospectionException {
-        boolean result = false;
-        Method[] setters = findMethods(beanClass, setterName);
-        for (Method element : setters) {
-            try {
-                setWriteMethod(element);
-                result = true;
-            } catch (IntrospectionException ie) {
-            }
-            if (result) {
-                break;
-            }
-        }
-    }
-
-    public PropertyEditor createPropertyEditor(Object bean) {
-        PropertyEditor editor;
-        if (propertyEditorClass == null) {
-            return null;
-        }
-        if (!PropertyEditor.class.isAssignableFrom(propertyEditorClass)) {
-            // beans.48=Property editor is not assignable from the
-            // PropertyEditor interface
-            throw new ClassCastException(Messages.getString("beans.48")); //$NON-NLS-1$
-        }
-        try {
-            Constructor<?> constr;
-            try {
-                // try to look for the constructor with single Object argument
-                constr = propertyEditorClass.getConstructor(Object.class);
-                editor = (PropertyEditor) constr.newInstance(bean);
-            } catch (NoSuchMethodException e) {
-                // try no-argument constructor
-                constr = propertyEditorClass.getConstructor();
-                editor = (PropertyEditor) constr.newInstance();
-            }
-        } catch (Exception e) {
-            // beans.47=Unable to instantiate property editor
-            RuntimeException re = new RuntimeException(Messages.getString("beans.47"), e); //$NON-NLS-1$
-            throw re;
-        }
-        return editor;
-    }
-}
diff --git a/awt/java/beans/PropertyEditor.java b/awt/java/beans/PropertyEditor.java
deleted file mode 100644
index 65bedea..0000000
--- a/awt/java/beans/PropertyEditor.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.beans;
-
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.Rectangle;
-
-public interface PropertyEditor {
-
-    public void paintValue(Graphics gfx, Rectangle box);
-
-    public void setAsText(String text) throws IllegalArgumentException;
-
-    public String[] getTags();
-
-    public String getJavaInitializationString();
-
-    public String getAsText();
-
-    public void setValue(Object value);
-
-    public Object getValue();
-
-    public void removePropertyChangeListener(PropertyChangeListener listener);
-
-    public void addPropertyChangeListener(PropertyChangeListener listener);
-
-    public Component getCustomEditor();
-
-    public boolean supportsCustomEditor();
-
-    public boolean isPaintable();
-}
diff --git a/awt/java/beans/PropertyEditorManager.java b/awt/java/beans/PropertyEditorManager.java
deleted file mode 100644
index ed55829..0000000
--- a/awt/java/beans/PropertyEditorManager.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.beans;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class PropertyEditorManager {
-
-    private static String[] path = { "org.apache.harmony.beans.editors" }; //$NON-NLS-1$
-
-    private static final Map<Class<?>, Class<?>> registeredEditors = new HashMap<Class<?>, Class<?>>();
-
-    public PropertyEditorManager() {
-    }
-
-    public static void registerEditor(Class<?> targetType, Class<?> editorClass) {
-        if (targetType == null) {
-            throw new NullPointerException();
-        }
-
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPropertiesAccess();
-        }
-        if (editorClass != null) {
-            registeredEditors.put(targetType, editorClass);
-        } else {
-            registeredEditors.remove(targetType);
-        }
-    }
-
-    public static synchronized PropertyEditor findEditor(Class<?> targetType) {
-        if (targetType == null) {
-            throw new NullPointerException();
-        }
-
-        Class<?> editorClass = null;
-        PropertyEditor editor = null;
-
-        editorClass = registeredEditors.get(targetType);
-
-        if (editorClass == null) {
-            String editorClassName = targetType.getName() + "Editor"; //$NON-NLS-1$
-            ClassLoader loader = targetType.getClassLoader();
-
-            if (loader == null) {
-                loader = Thread.currentThread().getContextClassLoader();
-            }
-
-            try {
-                editorClass = Class.forName(editorClassName, true, loader);
-            } catch (ClassNotFoundException cnfe) {
-                String shortEditorClassName = editorClassName
-                        .substring(editorClassName.lastIndexOf(".") + 1); //$NON-NLS-1$
-
-                if (targetType.isPrimitive()) {
-                    shortEditorClassName = shortEditorClassName.substring(0, 1)
-                            .toUpperCase()
-                            + shortEditorClassName.substring(1);
-                }
-
-                for (String element : path) {
-                    editorClassName = element + "." + shortEditorClassName; //$NON-NLS-1$
-
-                    try {
-                        editorClass = Class.forName(editorClassName, true,
-                                loader);
-                        break;
-                    } catch (Exception e) {
-                    }
-                }
-            } catch (Exception e) {
-            }
-        }
-
-        if (editorClass != null) {
-            try {
-                editor = (PropertyEditor) editorClass.newInstance();
-            } catch (Exception e) {
-            }
-        }
-
-        return editor;
-    }
-
-    public static synchronized void setEditorSearchPath(String[] apath) {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPropertiesAccess();
-        }
-
-        path = apath;
-    }
-
-    public static synchronized String[] getEditorSearchPath() {
-        return path;
-    }
-}
diff --git a/awt/java/beans/PropertyEditorSupport.java b/awt/java/beans/PropertyEditorSupport.java
deleted file mode 100644
index c3929a1..0000000
--- a/awt/java/beans/PropertyEditorSupport.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.beans;
-
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.Rectangle;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.harmony.beans.internal.nls.Messages;
-
-public class PropertyEditorSupport implements PropertyEditor {
-
-    Object source = null;
-
-    List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
-
-    Object oldValue = null;
-
-    Object newValue = null;
-
-    public PropertyEditorSupport(Object source) {
-        if (source == null) {
-            throw new NullPointerException(Messages.getString("beans.0C")); //$NON-NLS-1$
-        }
-        this.source = source;
-    }
-
-    public PropertyEditorSupport() {
-        source = this;
-    }
-
-    public void paintValue(Graphics gfx, Rectangle box) {
-    }
-
-    public void setAsText(String text) throws IllegalArgumentException {
-        if (newValue instanceof String) {
-            setValue(text);
-        } else {
-            throw new IllegalArgumentException(text);
-        }
-    }
-
-    public String[] getTags() {
-        return null;
-    }
-
-    public String getJavaInitializationString() {
-        return "???"; //$NON-NLS-1$
-    }
-
-    public String getAsText() {
-        return newValue == null ? "null" : newValue.toString(); //$NON-NLS-1$
-    }
-
-    public void setValue(Object value) {
-        this.oldValue = this.newValue;
-        this.newValue = value;
-        firePropertyChange();
-    }
-
-    public Object getValue() {
-        return newValue;
-    }
-
-    public void setSource(Object source) {
-        if (source == null) {
-            throw new NullPointerException(Messages.getString("beans.0C")); //$NON-NLS-1$
-        }
-        this.source = source;
-    }
-
-    public Object getSource() {
-        return source;
-    }
-
-    public synchronized void removePropertyChangeListener(
-            PropertyChangeListener listener) {
-        if (listeners != null) {
-            listeners.remove(listener);
-        }
-    }
-
-    public synchronized void addPropertyChangeListener(
-            PropertyChangeListener listener) {
-        listeners.add(listener);
-    }
-
-    public Component getCustomEditor() {
-        return null;
-    }
-
-    public boolean supportsCustomEditor() {
-        return false;
-    }
-
-    public boolean isPaintable() {
-        return false;
-    }
-
-    public void firePropertyChange() {
-        if (listeners.size() > 0) {
-            PropertyChangeEvent event = new PropertyChangeEvent(source, null,
-                    oldValue, newValue);
-            Iterator<PropertyChangeListener> iterator = listeners.iterator();
-
-            while (iterator.hasNext()) {
-                PropertyChangeListener listener = iterator.next();
-                listener.propertyChange(event);
-            }
-        }
-    }
-}
diff --git a/awt/java/beans/PropertyVetoException.java b/awt/java/beans/PropertyVetoException.java
deleted file mode 100644
index c7f092a..0000000
--- a/awt/java/beans/PropertyVetoException.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.beans;
-
-/**
- * Indicates that a proposed property change is unacceptable.
- */
-public class PropertyVetoException extends Exception {
-
-    private static final long serialVersionUID = 129596057694162164L;
-
-    private final PropertyChangeEvent evt;
-
-    /**
-     * <p>
-     * Constructs an instance with a message and the change event.
-     * </p>
-     * 
-     * @param message
-     *            A description of the veto.
-     * @param event
-     *            The event that was vetoed.
-     */
-    public PropertyVetoException(String message, PropertyChangeEvent event) {
-        super(message);
-        this.evt = event;
-    }
-
-    /**
-     * <p>
-     * Gets the property change event.
-     * </p>
-     * 
-     * @return An instance of {@link PropertyChangeEvent}
-     */
-    public PropertyChangeEvent getPropertyChangeEvent() {
-        return evt;
-    }
-}
diff --git a/awt/javax/imageio/IIOException.java b/awt/javax/imageio/IIOException.java
deleted file mode 100644
index c77716c..0000000
--- a/awt/javax/imageio/IIOException.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio;
-
-import java.io.IOException;
-
-/**
- * The IIOException class indicates errors in reading/writing operations.
- * 
- * @since Android 1.0
- */
-public class IIOException extends IOException {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = -3216210718638985251L;
-
-    /**
-     * Instantiates a new IIOException.
-     * 
-     * @param message
-     *            the detailed message.
-     */
-    public IIOException(String message) {
-        super(message);
-    }
-
-    /**
-     * Instantiates a new IIOException.
-     * 
-     * @param message
-     *            the detailed message.
-     * @param cause
-     *            the cause of this exception.
-     */
-    public IIOException(String message, Throwable cause) {
-        super(message);
-        initCause(cause);
-    }
-}
diff --git a/awt/javax/imageio/IIOImage.java b/awt/javax/imageio/IIOImage.java
deleted file mode 100644
index e9e5130..0000000
--- a/awt/javax/imageio/IIOImage.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio;
-
-import javax.imageio.metadata.IIOMetadata;
-import java.awt.image.RenderedImage;
-import java.awt.image.Raster;
-import java.awt.image.BufferedImage;
-import java.util.List;
-
-/**
- * The IIOImage class combines the image, image's thumbnail and image's
- * metadata. The image can be presented as RenderedImage or Raster object.
- * 
- * @since Android 1.0
- */
-public class IIOImage {
-
-    /**
-     * The image of this IIOImage.
-     */
-    protected RenderedImage image;
-
-    /**
-     * The raster of this IIOImage.
-     */
-    protected Raster raster;
-
-    /**
-     * The list with thumbnails associated with the image.
-     */
-    protected List<? extends BufferedImage> thumbnails;
-
-    /**
-     * The metadata associated with the image.
-     */
-    protected IIOMetadata metadata;
-
-    /**
-     * Instantiates a new IIOImage with the specified RenderedImage, list of
-     * thumbnails and metadata.
-     * 
-     * @param image
-     *            the image specified by RenderedImage.
-     * @param thumbnails
-     *            the list of BufferedImage objects which represent the
-     *            thumbnails of the image.
-     * @param metadata
-     *            the metadata of the image.
-     */
-    public IIOImage(RenderedImage image, List<? extends BufferedImage> thumbnails,
-            IIOMetadata metadata) {
-        if (image == null) {
-            throw new IllegalArgumentException("image should not be NULL");
-        }
-        this.raster = null;
-        this.image = image;
-        this.thumbnails = thumbnails;
-        this.metadata = metadata;
-    }
-
-    /**
-     * Instantiates a new IIOImage with the specified Raster, list of thumbnails
-     * and metadata.
-     * 
-     * @param raster
-     *            the Raster.
-     * @param thumbnails
-     *            the list of BufferedImage objects which represent the
-     *            thumbnails of Raster data.
-     * @param metadata
-     *            the metadata.
-     */
-    public IIOImage(Raster raster, List<? extends BufferedImage> thumbnails, IIOMetadata metadata) {
-        if (raster == null) {
-            throw new IllegalArgumentException("raster should not be NULL");
-        }
-        this.image = null;
-        this.raster = raster;
-        this.thumbnails = thumbnails;
-        this.metadata = metadata;
-    }
-
-    /**
-     * Gets the RenderedImage object or returns null if this IIOImage object is
-     * associated with a Raster.
-     * 
-     * @return the RenderedImage object or null if this IIOImage object is
-     *         associated with a Raster.
-     */
-    public RenderedImage getRenderedImage() {
-        return image;
-    }
-
-    /**
-     * Sets the RenderedImage to this IIOImage object.
-     * 
-     * @param image
-     *            the RenderedImage to be set to this IIOImage.
-     */
-    public void setRenderedImage(RenderedImage image) {
-        if (image == null) {
-            throw new IllegalArgumentException("image should not be NULL");
-        }
-        raster = null;
-        this.image = image;
-    }
-
-    /**
-     * Returns true if the IIOImage object associated with a Raster, or false if
-     * it's associated with a RenderedImage.
-     * 
-     * @return true, if the IIOImage object associated with a Raster, or false
-     *         if it's associated with a RenderedImage.
-     */
-    public boolean hasRaster() {
-        return raster != null;
-    }
-
-    /**
-     * Gets the Raster object or returns null if this IIOImage object is
-     * associated with a RenderedImage.
-     * 
-     * @return the Raster or null if this IIOImage object is associated with a
-     *         RenderedImage.
-     */
-    public Raster getRaster() {
-        return raster;
-    }
-
-    /**
-     * Sets the Raster to the IIOImage.
-     * 
-     * @param raster
-     *            the new Raster to the IIOImage.
-     */
-    public void setRaster(Raster raster) {
-        if (raster == null) {
-            throw new IllegalArgumentException("raster should not be NULL");
-        }
-        image = null;
-        this.raster = raster;
-    }
-
-    /**
-     * Gets the number of thumbnails for this IIOImage.
-     * 
-     * @return the number of thumbnails for this IIOImage.
-     */
-    public int getNumThumbnails() {
-        return thumbnails != null ? thumbnails.size() : 0;
-    }
-
-    /**
-     * Gets the thumbnail with the specified index in the list.
-     * 
-     * @param index
-     *            the index of the thumbnail in the list.
-     * @return the thumbnail with the specified index in the list.
-     */
-    public BufferedImage getThumbnail(int index) {
-        if (thumbnails != null) {
-            return thumbnails.get(index);
-        }
-        throw new IndexOutOfBoundsException("no thumbnails were set");
-    }
-
-    /**
-     * Gets the list of thumbnails.
-     * 
-     * @return the list of thumbnails.
-     */
-    public List<? extends BufferedImage> getThumbnails() {
-        return thumbnails;
-    }
-
-    /**
-     * Sets the list of thumbnails images to this IIOImage object.
-     * 
-     * @param thumbnails
-     *            the list of BufferedImage which represent thumbnails.
-     */
-    public void setThumbnails(List<? extends BufferedImage> thumbnails) {
-        this.thumbnails = thumbnails;
-    }
-
-    /**
-     * Gets the metadata of this IIOImage.
-     * 
-     * @return the metadata of this IIOImage.
-     */
-    public IIOMetadata getMetadata() {
-        return metadata;
-    }
-
-    /**
-     * Sets the metadata to this IIOImage object.
-     * 
-     * @param metadata
-     *            the IIOMetadata, or null.
-     */
-    public void setMetadata(IIOMetadata metadata) {
-        this.metadata = metadata;
-    }
-}
diff --git a/awt/javax/imageio/IIOParam.java b/awt/javax/imageio/IIOParam.java
deleted file mode 100644
index 2ccc945..0000000
--- a/awt/javax/imageio/IIOParam.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio;
-
-import java.awt.*;
-
-/**
- * The IIOParam abstract class is superclass for ImageReadParam and
- * ImageWriteParam classes and provides methods and variables which they share.
- * 
- * @since Android 1.0
- */
-public abstract class IIOParam {
-
-    /**
-     * The source region.
-     */
-    protected Rectangle sourceRegion;
-
-    /**
-     * The source x subsampling.
-     */
-    protected int sourceXSubsampling = 1;
-
-    /**
-     * The source y subsampling.
-     */
-    protected int sourceYSubsampling = 1;
-
-    /**
-     * The subsampling x offset.
-     */
-    protected int subsamplingXOffset;
-
-    /**
-     * The subsampling y offset.
-     */
-    protected int subsamplingYOffset;
-
-    /**
-     * The source bands.
-     */
-    protected int[] sourceBands;
-
-    /**
-     * The destination type.
-     */
-    protected ImageTypeSpecifier destinationType;
-
-    /**
-     * The destination offset.
-     */
-    protected Point destinationOffset = new Point(0, 0);
-
-    /**
-     * The default controller.
-     */
-    protected IIOParamController defaultController;
-
-    /**
-     * The controller.
-     */
-    protected IIOParamController controller;
-
-    /**
-     * Instantiates a new IIOParam.
-     */
-    protected IIOParam() {
-    }
-
-    /**
-     * Sets the source region as a Rectangle object.
-     * 
-     * @param sourceRegion
-     *            the Rectangle which specifies the source region.
-     */
-    public void setSourceRegion(Rectangle sourceRegion) {
-        if (sourceRegion != null) {
-            if (sourceRegion.x < 0) {
-                throw new IllegalArgumentException("x < 0");
-            }
-            if (sourceRegion.y < 0) {
-                throw new IllegalArgumentException("y < 0");
-            }
-            if (sourceRegion.width <= 0) {
-                throw new IllegalArgumentException("width <= 0");
-            }
-            if (sourceRegion.height <= 0) {
-                throw new IllegalArgumentException("height <= 0");
-            }
-
-            if (sourceRegion.width <= subsamplingXOffset) {
-                throw new IllegalArgumentException("width <= subsamplingXOffset");
-            }
-
-            if (sourceRegion.height <= subsamplingYOffset) {
-                throw new IllegalArgumentException("height <= subsamplingXOffset");
-            }
-            // -- clone it to avoid unexpected modifications
-            this.sourceRegion = (Rectangle)sourceRegion.clone();
-        } else {
-            this.sourceRegion = null;
-        }
-    }
-
-    /**
-     * Gets the source region.
-     * 
-     * @return the source region as Rectangle.
-     */
-    public Rectangle getSourceRegion() {
-        if (sourceRegion == null) {
-            return null;
-        }
-        // -- clone it to avoid unexpected modifications
-        return (Rectangle)sourceRegion.clone();
-    }
-
-    /**
-     * Sets the source subsampling. The sourceXSubsampling and
-     * sourceYSubsampling parameters specify the number of rows and columns to
-     * advance after every source pixel.
-     * 
-     * @param sourceXSubsampling
-     *            the source X subsampling.
-     * @param sourceYSubsampling
-     *            the source Y subsampling.
-     * @param subsamplingXOffset
-     *            the subsampling X offset.
-     * @param subsamplingYOffset
-     *            the subsampling Y offset.
-     */
-    public void setSourceSubsampling(int sourceXSubsampling, int sourceYSubsampling,
-            int subsamplingXOffset, int subsamplingYOffset) {
-
-        if (sourceXSubsampling <= 0) {
-            throw new IllegalArgumentException("sourceXSubsampling <= 0");
-        }
-        if (sourceYSubsampling <= 0) {
-            throw new IllegalArgumentException("sourceYSubsampling <= 0");
-        }
-
-        if (subsamplingXOffset <= 0 || subsamplingXOffset >= sourceXSubsampling) {
-            throw new IllegalArgumentException("subsamplingXOffset is wrong");
-        }
-
-        if (subsamplingYOffset <= 0 || subsamplingYOffset >= sourceYSubsampling) {
-            throw new IllegalArgumentException("subsamplingYOffset is wrong");
-        }
-
-        // -- does region contain pixels
-        if (sourceRegion != null) {
-            if (sourceRegion.width <= subsamplingXOffset
-                    || sourceRegion.height <= subsamplingYOffset) {
-                throw new IllegalArgumentException("there are no pixels in region");
-            }
-        }
-
-        this.sourceXSubsampling = sourceXSubsampling;
-        this.sourceYSubsampling = sourceYSubsampling;
-        this.subsamplingXOffset = subsamplingXOffset;
-        this.subsamplingYOffset = subsamplingYOffset;
-    }
-
-    /**
-     * Gets the source X subsampling - the number of source columns to advance
-     * for each pixel.
-     * 
-     * @return the source X subsampling.
-     */
-    public int getSourceXSubsampling() {
-        return sourceXSubsampling;
-    }
-
-    /**
-     * Gets the source Y subsampling - the number of source rows to advance for
-     * each pixel.
-     * 
-     * @return the source Y subsampling.
-     */
-    public int getSourceYSubsampling() {
-        return sourceYSubsampling;
-    }
-
-    /**
-     * Gets the horizontal offset of the subsampling grid.
-     * 
-     * @return the horizontal offset of the subsampling grid.
-     */
-    public int getSubsamplingXOffset() {
-        return subsamplingXOffset;
-    }
-
-    /**
-     * Gets the vertical offset of the subsampling grid.
-     * 
-     * @return the vertical offset of the subsampling grid.
-     */
-    public int getSubsamplingYOffset() {
-        return subsamplingYOffset;
-    }
-
-    /**
-     * Sets the indices of the source bands.
-     * 
-     * @param sourceBands
-     *            the indices of the source bands.
-     */
-    public void setSourceBands(int[] sourceBands) {
-        // TODO implement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    /**
-     * Gets the array of source bands.
-     * 
-     * @return the array of source bands.
-     */
-    public int[] getSourceBands() {
-        // TODO implement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    /**
-     * Sets the specified ImageTypeSpecifier for the destination image.
-     * 
-     * @param destinationType
-     *            the ImageTypeSpecifier.
-     */
-    public void setDestinationType(ImageTypeSpecifier destinationType) {
-        // TODO implement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    /**
-     * Gets the type of the destination image as an ImageTypeSpecifier. .
-     * 
-     * @return the ImageTypeSpecifier.
-     */
-    public ImageTypeSpecifier getDestinationType() {
-        // TODO implement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    /**
-     * Sets the offset in the destination image where the decoded pixels are
-     * placed as a result of reading, or specified an area to be written while
-     * writing operation.
-     * 
-     * @param destinationOffset
-     *            the destination offset.
-     */
-    public void setDestinationOffset(Point destinationOffset) {
-        if (destinationOffset == null) {
-            throw new IllegalArgumentException("destinationOffset == null!");
-        }
-
-        this.destinationOffset = (Point)destinationOffset.clone();
-    }
-
-    /**
-     * Gets the offset in the destination image for placing pixels.
-     * 
-     * @return the offset in the destination image.
-     */
-    public Point getDestinationOffset() {
-        return (Point)destinationOffset.clone();
-    }
-
-    /**
-     * Sets the IIOParamController to this IIOParam object for providing
-     * settings to this IIOParam.
-     * 
-     * @param controller
-     *            the new IIOParamController.
-     */
-    public void setController(IIOParamController controller) {
-        // TODO implement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    /**
-     * Gets the current IIOParamController controller for this IIOParam.
-     * 
-     * @return the current IIOParamController controller for this IIOParam.
-     */
-    public IIOParamController getController() {
-        // TODO implement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    /**
-     * Gets the default IIOParamController controller for this IIOParam.
-     * 
-     * @return the default IIOParamController controller for this IIOParam, or
-     *         null.
-     */
-    public IIOParamController getDefaultController() {
-        // TODO implement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    /**
-     * Returns true if IIOParamController is installed for this IIOParam.
-     * 
-     * @return true, if IIOParamController is installed for this IIOParam, false
-     *         otherwise.
-     */
-    public boolean hasController() {
-        // TODO implement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    /**
-     * Activates the controller.
-     * 
-     * @return true, if successful, false otherwise.
-     */
-    public boolean activateController() {
-        // TODO implement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-}
diff --git a/awt/javax/imageio/IIOParamController.java b/awt/javax/imageio/IIOParamController.java
deleted file mode 100644
index 338cb25..0000000
--- a/awt/javax/imageio/IIOParamController.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-package javax.imageio;
-
-/* 
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-/**
- * The IIOParamController specifies an activate method that invokes the
- * controller.
- * 
- * @since Android 1.0
- */
-public interface IIOParamController {
-
-    /**
-     * Activates the controller.
-     * 
-     * @param param
-     *            the IIOParam.
-     * @return true, if the IIOParam has been modified, false otherwise.
-     */
-    boolean activate(IIOParam param);
-}
diff --git a/awt/javax/imageio/ImageIO.java b/awt/javax/imageio/ImageIO.java
deleted file mode 100644
index e0d7ec9..0000000
--- a/awt/javax/imageio/ImageIO.java
+++ /dev/null
@@ -1,800 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio;
-
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.stream.ImageOutputStream;
-import javax.imageio.spi.*;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.Arrays;
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-import java.net.URL;
-
-/**
- * The ImageIO class provides static methods to perform reading and writing
- * operations using registered ImageReader and ImageWriter objects.
- * 
- * @since Android 1.0
- */
-public final class ImageIO {
-
-    /**
-     * The constant registry.
-     */
-    private static final IIORegistry registry = IIORegistry.getDefaultInstance();
-
-    /**
-     * Instantiates a new ImageIO.
-     */
-    private ImageIO() {
-    }
-
-    /**
-     * Scans for plug-ins in the class path, loads spi classes, and registers
-     * them with the IIORegistry.
-     */
-    public static void scanForPlugins() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Sets flag which indicates whether a cache file is used when creating
-     * ImageInputStreams and ImageOutputStreams or not.
-     * 
-     * @param useCache
-     *            the use cache flag.
-     */
-    public static void setUseCache(boolean useCache) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets the flag which indicates whether a cache file is used when creating
-     * ImageInputStreams and ImageOutputStreams or not. This method returns the
-     * current value which is set by setUseCache method.
-     * 
-     * @return the use cache flag.
-     */
-    public static boolean getUseCache() {
-        // TODO implement
-        return false;
-    }
-
-    /**
-     * Sets the cache directory.
-     * 
-     * @param cacheDirectory
-     *            the File which specifies a cache directory.
-     */
-    public static void setCacheDirectory(File cacheDirectory) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets the directory where cache files are created, returned the file which
-     * is set by setCacheDirectory method, or null.
-     * 
-     * @return the File object which is set by setCacheDirectory method, or
-     *         null.
-     */
-    public static File getCacheDirectory() {
-        // TODO implement
-        // -- null indicates system-dep default temporary directory
-        return null;
-    }
-
-    /**
-     * Creates an ImageInputStream from the specified Object. The specified
-     * Object should obtain the input source such as File, or InputStream.
-     * 
-     * @param input
-     *            the input Object such as File, or InputStream.
-     * @return the ImageInputStream object, or null.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public static ImageInputStream createImageInputStream(Object input) throws IOException {
-
-        if (input == null) {
-            throw new IllegalArgumentException("input source cannot be NULL");
-        }
-
-        Iterator<ImageInputStreamSpi> it = registry.getServiceProviders(ImageInputStreamSpi.class,
-                true);
-
-        while (it.hasNext()) {
-            ImageInputStreamSpi spi = it.next();
-            if (spi.getInputClass().isInstance(input)) {
-                return spi.createInputStreamInstance(input);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Creates an ImageOutputStream using the specified Object. The specified
-     * Object should obtain the output source such as File, or OutputStream.
-     * 
-     * @param output
-     *            the output Object such as File, or OutputStream.
-     * @return the ImageOutputStream object, or null.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public static ImageOutputStream createImageOutputStream(Object output) throws IOException {
-        if (output == null) {
-            throw new IllegalArgumentException("output destination cannot be NULL");
-        }
-
-        Iterator<ImageOutputStreamSpi> it = registry.getServiceProviders(
-                ImageOutputStreamSpi.class, true);
-
-        while (it.hasNext()) {
-            ImageOutputStreamSpi spi = it.next();
-            if (spi.getOutputClass().isInstance(output)) {
-                // todo - use getUseCache and getCacheDir here
-                return spi.createOutputStreamInstance(output);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Gets the array of format names as String which can be decoded by
-     * registered ImageReader objects.
-     * 
-     * @return the array of format names.
-     */
-    public static String[] getReaderFormatNames() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets the array of MIME types as String which can be decoded by registered
-     * ImageReader objects.
-     * 
-     * @return the array of MIME types.
-     */
-    public static String[] getReaderMIMETypes() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets the Iterator of registered ImageReader which are able to decode an
-     * input data specified by input Object.
-     * 
-     * @param input
-     *            the input Object with encoded data such as ImageInputStream
-     *            object.
-     * @return the Iterator of registered ImageReader.
-     */
-    public static Iterator<ImageReader> getImageReaders(Object input) {
-        if (input == null) {
-            throw new NullPointerException("input cannot be NULL");
-        }
-
-        Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
-                new CanReadFilter(input), true);
-
-        return new SpiIteratorToReadersIteratorWrapper(it);
-    }
-
-    /**
-     * Gets the Iterator of registered ImageReader which are able to decode the
-     * specified format.
-     * 
-     * @param formatName
-     *            the format name such as "jpeg", or "gif".
-     * @return the Iterator of registered ImageReader.
-     */
-    public static Iterator<ImageReader> getImageReadersByFormatName(String formatName) {
-        if (formatName == null) {
-            throw new NullPointerException("format name cannot be NULL");
-        }
-
-        Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
-                new FormatFilter(formatName), true);
-
-        return new SpiIteratorToReadersIteratorWrapper(it);
-    }
-
-    /**
-     * Gets the Iterator which lists the registered ImageReader objects that are
-     * able to decode files with the specified suffix.
-     * 
-     * @param fileSuffix
-     *            the file suffix such as "jpg".
-     * @return the Iterator of registered ImageReaders.
-     */
-    public static Iterator<ImageReader> getImageReadersBySuffix(String fileSuffix) {
-        if (fileSuffix == null) {
-            throw new NullPointerException("suffix cannot be NULL");
-        }
-        Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
-                new SuffixFilter(fileSuffix), true);
-
-        return new SpiIteratorToReadersIteratorWrapper(it);
-    }
-
-    /**
-     * Gets the Iterator of registered ImageReader objects that are able to
-     * decode files with the specified MIME type.
-     * 
-     * @param MIMEType
-     *            the MIME type such as "image/jpeg".
-     * @return the Iterator of registered ImageReaders.
-     */
-    public static Iterator<ImageReader> getImageReadersByMIMEType(String MIMEType) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets an array of Strings giving the names of the formats supported by
-     * registered ImageWriter objects.
-     * 
-     * @return the array of format names.
-     */
-    public static String[] getWriterFormatNames() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets an array of Strings giving the MIME types of the formats supported
-     * by registered ImageWriter objects.
-     * 
-     * @return the array of MIME types.
-     */
-    public static String[] getWriterMIMETypes() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets the Iterator which lists the registered ImageReader objects that are
-     * able to encode the specified image format.
-     * 
-     * @param formatName
-     *            the image format name such as "jpeg".
-     * @return the Iterator of registered ImageWriter.
-     */
-    public static Iterator<ImageWriter> getImageWritersByFormatName(String formatName) {
-        if (formatName == null) {
-            throw new NullPointerException("format name cannot be NULL");
-        }
-
-        Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class,
-                new FormatFilter(formatName), true);
-
-        return new SpiIteratorToWritersIteratorWrapper(it);
-    }
-
-    /**
-     * Gets the Iterator which lists the registered ImageReader objects that are
-     * able to encode the specified suffix.
-     * 
-     * @param fileSuffix
-     *            the file suffix such as "jpg".
-     * @return the Iterator of registered ImageWriter.
-     */
-    public static Iterator<ImageWriter> getImageWritersBySuffix(String fileSuffix) {
-        if (fileSuffix == null) {
-            throw new NullPointerException("suffix cannot be NULL");
-        }
-        Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class,
-                new SuffixFilter(fileSuffix), true);
-        return new SpiIteratorToWritersIteratorWrapper(it);
-    }
-
-    /**
-     * Gets the Iterator which lists the registered ImageReader objects that are
-     * able to encode the specified MIME type.
-     * 
-     * @param MIMEType
-     *            the MIME type such as "image/jpeg".
-     * @return the Iterator of registered ImageWriter.
-     */
-    public static Iterator<ImageWriter> getImageWritersByMIMEType(String MIMEType) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets an ImageWriter object which corresponds to the specified
-     * ImageReader, or returns null if the specified ImageReader is not
-     * registered.
-     * 
-     * @param reader
-     *            the specified ImageReader.
-     * @return the ImageWriter, or null.
-     */
-    public static ImageWriter getImageWriter(ImageReader reader) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets an ImageReader object which corresponds to the specified
-     * ImageWriter, or returns null if the specified ImageWriter is not
-     * registered.
-     * 
-     * @param writer
-     *            the registered ImageWriter object.
-     * @return the ImageReader.
-     */
-    public static ImageReader getImageReader(ImageWriter writer) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets the Iterator of ImageWriter objects which are able to encode images
-     * with the specified ImageTypeSpecifier and format.
-     * 
-     * @param type
-     *            the ImageTypeSpecifier, which defines layout.
-     * @param formatName
-     *            the format name.
-     * @return the Iterator of ImageWriter objects.
-     */
-    public static Iterator<ImageWriter> getImageWriters(ImageTypeSpecifier type, String formatName) {
-        if (type == null) {
-            throw new NullPointerException("type cannot be NULL");
-        }
-
-        if (formatName == null) {
-            throw new NullPointerException("format name cannot be NULL");
-        }
-
-        Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class,
-                new FormatAndEncodeFilter(type, formatName), true);
-
-        return new SpiIteratorToWritersIteratorWrapper(it);
-    }
-
-    /**
-     * Gets the Iterator of registered ImageTranscoders which are able to
-     * transcode the metadata of the specified ImageReader object to a suitable
-     * object for encoding by the specified ImageWriter.
-     * 
-     * @param reader
-     *            the specified ImageReader.
-     * @param writer
-     *            the specified ImageWriter.
-     * @return the Iterator of registered ImageTranscoders.
-     */
-    public static Iterator<ImageTranscoder> getImageTranscoders(ImageReader reader,
-            ImageWriter writer) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Reads image data from the specified File and decodes it using the
-     * appropriate registered ImageReader object. The File is wrapped in an
-     * ImageInputStream.
-     * 
-     * @param input
-     *            the File to be read.
-     * @return the BufferedImage decoded from the specified File, or null.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public static BufferedImage read(File input) throws IOException {
-        if (input == null) {
-            throw new IllegalArgumentException("input == null!");
-        }
-
-        ImageInputStream stream = createImageInputStream(input);
-        return read(stream);
-    }
-
-    /**
-     * Reads image data from the specified InputStream and decodes it using an
-     * appropriate registered an ImageReader object.
-     * 
-     * @param input
-     *            the InputStream.
-     * @return the BufferedImage decoded from the specified InputStream, or
-     *         null.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public static BufferedImage read(InputStream input) throws IOException {
-        if (input == null) {
-            throw new IllegalArgumentException("input == null!");
-        }
-
-        ImageInputStream stream = createImageInputStream(input);
-        return read(stream);
-    }
-
-    /**
-     * Reads image data from the specified URL and decodes it using the
-     * appropriate registered ImageReader object.
-     * 
-     * @param input
-     *            the URL to be read.
-     * @return the BufferedImage decoded from the specified URL, or null.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public static BufferedImage read(URL input) throws IOException {
-        if (input == null) {
-            throw new IllegalArgumentException("input == null!");
-        }
-
-        InputStream stream = input.openStream();
-        BufferedImage res = read(stream);
-        stream.close();
-
-        return res;
-    }
-
-    /**
-     * Reads image data from the specified ImageInputStream and decodes it using
-     * appropriate registered an ImageReader object.
-     * 
-     * @param stream
-     *            the ImageInputStream.
-     * @return the BufferedImage decoded from the specified ImageInputStream, or
-     *         null.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public static BufferedImage read(ImageInputStream stream) throws IOException {
-        if (stream == null) {
-            throw new IllegalArgumentException("stream == null!");
-        }
-
-        Iterator<ImageReader> imageReaders = getImageReaders(stream);
-        if (!imageReaders.hasNext()) {
-            return null;
-        }
-
-        ImageReader reader = imageReaders.next();
-        reader.setInput(stream, false, true);
-        BufferedImage res = reader.read(0);
-        reader.dispose();
-
-        try {
-            stream.close();
-        } catch (IOException e) {
-            // Stream could be already closed, proceed silently in this case
-        }
-
-        return res;
-    }
-
-    /**
-     * Writes the specified image in the specified format (using an appropriate
-     * ImageWriter) to the specified ImageOutputStream.
-     * 
-     * @param im
-     *            the RenderedImage.
-     * @param formatName
-     *            the format name.
-     * @param output
-     *            the ImageOutputStream where Image to be written.
-     * @return true, if Image is written successfully, false otherwise.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public static boolean write(RenderedImage im, String formatName, ImageOutputStream output)
-            throws IOException {
-
-        if (im == null) {
-            throw new IllegalArgumentException("image cannot be NULL");
-        }
-        if (formatName == null) {
-            throw new IllegalArgumentException("format name cannot be NULL");
-        }
-        if (output == null) {
-            throw new IllegalArgumentException("output cannot be NULL");
-        }
-
-        Iterator<ImageWriter> it = getImageWriters(ImageTypeSpecifier.createFromRenderedImage(im),
-                formatName);
-        if (it.hasNext()) {
-            ImageWriter writer = it.next();
-            writer.setOutput(output);
-            writer.write(im);
-            output.flush();
-            writer.dispose();
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Writes the specified image in the specified format (using an appropriate
-     * ImageWriter) to the specified File.
-     * 
-     * @param im
-     *            the RenderedImage.
-     * @param formatName
-     *            the format name.
-     * @param output
-     *            the output File where Image to be written.
-     * @return true, if Image is written successfully, false otherwise.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public static boolean write(RenderedImage im, String formatName, File output)
-            throws IOException {
-
-        if (output == null) {
-            throw new IllegalArgumentException("output cannot be NULL");
-        }
-
-        if (output.exists()) {
-            output.delete();
-        }
-
-        ImageOutputStream ios = createImageOutputStream(output);
-        boolean rt = write(im, formatName, ios);
-        ios.close();
-        return rt;
-    }
-
-    /**
-     * Writes the specified image in the specified format (using an appropriate
-     * ImageWriter) to the specified OutputStream.
-     * 
-     * @param im
-     *            the RenderedImage.
-     * @param formatName
-     *            the format name.
-     * @param output
-     *            the OutputStream where Image is to be written.
-     * @return true, if Image is written successfully, false otherwise.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public static boolean write(RenderedImage im, String formatName, OutputStream output)
-            throws IOException {
-
-        if (output == null) {
-            throw new IllegalArgumentException("output cannot be NULL");
-        }
-
-        ImageOutputStream ios = createImageOutputStream(output);
-        boolean rt = write(im, formatName, ios);
-        ios.close();
-        return rt;
-    }
-
-    /**
-     * Filter to match spi by format name.
-     */
-    static class FormatFilter implements ServiceRegistry.Filter {
-
-        /**
-         * The name.
-         */
-        private String name;
-
-        /**
-         * Instantiates a new format filter.
-         * 
-         * @param name
-         *            the name.
-         */
-        public FormatFilter(String name) {
-            this.name = name;
-        }
-
-        public boolean filter(Object provider) {
-            ImageReaderWriterSpi spi = (ImageReaderWriterSpi)provider;
-            return Arrays.asList(spi.getFormatNames()).contains(name);
-        }
-    }
-
-    /**
-     * Filter to match spi by format name and encoding possibility.
-     */
-    static class FormatAndEncodeFilter extends FormatFilter {
-
-        /**
-         * The type.
-         */
-        private ImageTypeSpecifier type;
-
-        /**
-         * Instantiates a new format and encode filter.
-         * 
-         * @param type
-         *            the type.
-         * @param name
-         *            the name.
-         */
-        public FormatAndEncodeFilter(ImageTypeSpecifier type, String name) {
-            super(name);
-            this.type = type;
-        }
-
-        @Override
-        public boolean filter(Object provider) {
-            ImageWriterSpi spi = (ImageWriterSpi)provider;
-            return super.filter(provider) && spi.canEncodeImage(type);
-        }
-    }
-
-    /**
-     * Filter to match spi by suffix.
-     */
-    static class SuffixFilter implements ServiceRegistry.Filter {
-
-        /**
-         * The suf.
-         */
-        private String suf;
-
-        /**
-         * Instantiates a new suffix filter.
-         * 
-         * @param suf
-         *            the suf.
-         */
-        public SuffixFilter(String suf) {
-            this.suf = suf;
-        }
-
-        public boolean filter(Object provider) {
-            ImageReaderWriterSpi spi = (ImageReaderWriterSpi)provider;
-            return Arrays.asList(spi.getFileSuffixes()).contains(suf);
-        }
-    }
-
-    /**
-     * Filter to match spi by decoding possibility.
-     */
-    static class CanReadFilter implements ServiceRegistry.Filter {
-
-        /**
-         * The input.
-         */
-        private Object input;
-
-        /**
-         * Instantiates a new can read filter.
-         * 
-         * @param input
-         *            the input.
-         */
-        public CanReadFilter(Object input) {
-            this.input = input;
-        }
-
-        public boolean filter(Object provider) {
-            ImageReaderSpi spi = (ImageReaderSpi)provider;
-            try {
-                return spi.canDecodeInput(input);
-            } catch (IOException e) {
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Wraps Spi's iterator to ImageWriter iterator.
-     */
-    static class SpiIteratorToWritersIteratorWrapper implements Iterator<ImageWriter> {
-
-        /**
-         * The backend.
-         */
-        private Iterator<ImageWriterSpi> backend;
-
-        /**
-         * Instantiates a new spi iterator to writers iterator wrapper.
-         * 
-         * @param backend
-         *            the backend.
-         */
-        public SpiIteratorToWritersIteratorWrapper(Iterator<ImageWriterSpi> backend) {
-            this.backend = backend;
-        }
-
-        /**
-         * Next.
-         * 
-         * @return the image writer.
-         */
-        public ImageWriter next() {
-            try {
-                return backend.next().createWriterInstance();
-            } catch (IOException e) {
-                e.printStackTrace();
-                return null;
-            }
-        }
-
-        /**
-         * Checks for next.
-         * 
-         * @return true, if successful.
-         */
-        public boolean hasNext() {
-            return backend.hasNext();
-        }
-
-        /**
-         * Removes the.
-         */
-        public void remove() {
-            throw new UnsupportedOperationException(
-                    "Use deregisterServiceprovider instead of Iterator.remove()");
-        }
-    }
-
-    /**
-     * Wraps spi's iterator to ImageReader iterator.
-     */
-    static class SpiIteratorToReadersIteratorWrapper implements Iterator<ImageReader> {
-
-        /**
-         * The backend.
-         */
-        private Iterator<ImageReaderSpi> backend;
-
-        /**
-         * Instantiates a new spi iterator to readers iterator wrapper.
-         * 
-         * @param backend
-         *            the backend.
-         */
-        public SpiIteratorToReadersIteratorWrapper(Iterator<ImageReaderSpi> backend) {
-            this.backend = backend;
-        }
-
-        /**
-         * Next.
-         * 
-         * @return the image reader.
-         */
-        public ImageReader next() {
-            try {
-                return backend.next().createReaderInstance();
-            } catch (IOException e) {
-                e.printStackTrace();
-                return null;
-            }
-        }
-
-        /**
-         * Checks for next.
-         * 
-         * @return true, if successful.
-         */
-        public boolean hasNext() {
-            return backend.hasNext();
-        }
-
-        /**
-         * Removes the.
-         */
-        public void remove() {
-            throw new UnsupportedOperationException(
-                    "Use deregisterServiceprovider instead of Iterator.remove()");
-        }
-    }
-}
diff --git a/awt/javax/imageio/ImageReadParam.java b/awt/javax/imageio/ImageReadParam.java
deleted file mode 100644
index 9cc5c5f..0000000
--- a/awt/javax/imageio/ImageReadParam.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-package javax.imageio;
-
-import java.awt.Dimension;
-import java.awt.image.BufferedImage;
-
-/*
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-/**
- * The ImageReadParam class provides information to the ImageReader about how an
- * image is to be decoded.
- * 
- * @since Android 1.0
- */
-public class ImageReadParam extends IIOParam {
-
-    /**
-     * This flag indicates if this ImageReadParam supports setting the source
-     * rendering size.
-     */
-    protected boolean canSetSourceRenderSize;
-
-    /**
-     * The destination BufferedImage.
-     */
-    protected BufferedImage destination;
-
-    /**
-     * The destination bands.
-     */
-    protected int[] destinationBands;
-
-    /**
-     * The minimum progressive pass.
-     */
-    protected int minProgressivePass;
-
-    /**
-     * The number of progressive passes.
-     */
-    protected int numProgressivePasses;
-
-    /**
-     * The source render size.
-     */
-    protected Dimension sourceRenderSize;
-
-    /**
-     * Returns true if this ImageReaderParam supports rendering a source image
-     * at an arbitrary size.
-     * 
-     * @return true, if this ImageReaderParam supports rendering a source image
-     *         at an arbitrary size, false otherwise.
-     */
-    public boolean canSetSourceRenderSize() {
-        return canSetSourceRenderSize;
-    }
-
-    /**
-     * Gets the current destination image as BufferedImage.
-     * 
-     * @return the BufferedImage which represents the destination.
-     */
-    public BufferedImage getDestination() {
-        return destination;
-    }
-
-    /**
-     * Gets the indices of destination bands.
-     * 
-     * @return the array of destination bands.
-     */
-    public int[] getDestinationBands() {
-        return destinationBands;
-    }
-
-    /**
-     * Gets the index of the maximum pass to be decoded. This method returns
-     * Integer.MAX_VALUE, if getSourceNumProgressivePasses() method returns
-     * value that is equal to Integer.MAX_VALUE. Otherwise this method returns
-     * getSourceMinProgressivePass() + getSourceNumProgressivePasses() - 1.
-     * 
-     * @return the index of the maximum pass to be decoded.
-     */
-    public int getSourceMaxProgressivePass() {
-        if (getSourceNumProgressivePasses() == Integer.MAX_VALUE) {
-            return Integer.MAX_VALUE;
-        }
-        return getSourceMinProgressivePass() + getSourceNumProgressivePasses() - 1;
-    }
-
-    /**
-     * Gets the index of the minimum progressive pass that is decoded, default
-     * is 0.
-     * 
-     * @return the index of the minimum progressive pass that is decoded,
-     *         default is 0.
-     */
-    public int getSourceMinProgressivePass() {
-        return minProgressivePass;
-    }
-
-    /**
-     * Gets the number of progressive passes. The default value is
-     * Integer.MAX_VALUE.
-     * 
-     * @return the number of progressive passes.
-     */
-    public int getSourceNumProgressivePasses() {
-        return numProgressivePasses;
-    }
-
-    /**
-     * Gets the dimension of source image which will be rendered during decoding
-     * process.
-     * 
-     * @return the source render size.
-     */
-    public Dimension getSourceRenderSize() {
-        return sourceRenderSize;
-    }
-
-    /**
-     * Sets the specified destination image. This image will be used by read,
-     * readAll, and readRaster methods, and a reference to it will be returned
-     * by those methods.
-     * 
-     * @param destination
-     *            the destination image.
-     */
-    public void setDestination(BufferedImage destination) {
-        this.destination = destination;
-    }
-
-    /**
-     * Sets the indices of the destination bands.
-     * 
-     * @param destinationBands
-     *            the indices of the destination bands.
-     */
-    public void setDestinationBands(int[] destinationBands) {
-        this.destinationBands = destinationBands;
-    }
-
-    @Override
-    public void setDestinationType(ImageTypeSpecifier destinationType) {
-        this.destinationType = destinationType;
-    }
-
-    /**
-     * Sets the source progressive passes.
-     * 
-     * @param minPass
-     *            the index of the minimum pass to be decoded.
-     * @param numPasses
-     *            the number of passes to be decoded.
-     */
-    public void setSourceProgressivePasses(int minPass, int numPasses) {
-        minProgressivePass = minPass;
-        numProgressivePasses = numPasses;
-    }
-
-    /**
-     * Sets the dimension size of source image if an image can be rendered at an
-     * arbitrary size.
-     * 
-     * @param size
-     *            the size of rendered image.
-     * @throws UnsupportedOperationException
-     *             the unsupported operation exception.
-     */
-    public void setSourceRenderSize(Dimension size) throws UnsupportedOperationException {
-        if (!canSetSourceRenderSize) {
-            throw new UnsupportedOperationException("can't set source renderer size");
-        }
-        sourceRenderSize = size;
-    }
-}
diff --git a/awt/javax/imageio/ImageReader.java b/awt/javax/imageio/ImageReader.java
deleted file mode 100644
index cf282ed..0000000
--- a/awt/javax/imageio/ImageReader.java
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio;
-
-import javax.imageio.spi.ImageReaderSpi;
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.metadata.IIOMetadata;
-import javax.imageio.event.IIOReadWarningListener;
-import javax.imageio.event.IIOReadProgressListener;
-import javax.imageio.event.IIOReadUpdateListener;
-import java.util.Locale;
-import java.util.List;
-import java.util.Iterator;
-import java.util.Set;
-import java.io.IOException;
-import java.awt.image.BufferedImage;
-import java.awt.image.Raster;
-import java.awt.image.RenderedImage;
-import java.awt.*;
-
-/**
- * The ImageReader class is an abstract class for decoding images. ImageReader
- * objects are instantiated by the service provider interface, ImageReaderSpi
- * class, for the specific format. ImageReaderSpi class should be registered
- * with the IIORegistry, which uses them for format recognition and presentation
- * of available format readers and writers.
- * 
- * @since Android 1.0
- */
-public abstract class ImageReader {
-
-    /**
-     * The originating provider.
-     */
-    protected ImageReaderSpi originatingProvider;
-
-    /**
-     * The input object such as ImageInputStream.
-     */
-    protected Object input;
-
-    /**
-     * The seek forward only.
-     */
-    protected boolean seekForwardOnly;
-
-    /**
-     * The ignore metadata flag indicates whether current input source has been
-     * marked as metadata is allowed to be ignored by setInput.
-     */
-    protected boolean ignoreMetadata;
-
-    /**
-     * The minimum index.
-     */
-    protected int minIndex;
-
-    /**
-     * The available locales.
-     */
-    protected Locale[] availableLocales;
-
-    /**
-     * The locale.
-     */
-    protected Locale locale;
-
-    /**
-     * The list of warning listeners.
-     */
-    protected List<IIOReadWarningListener> warningListeners;
-
-    /**
-     * The list of warning locales.
-     */
-    protected List<Locale> warningLocales;
-
-    /**
-     * The list of progress listeners.
-     */
-    protected List<IIOReadProgressListener> progressListeners;
-
-    /**
-     * The list of update listeners.
-     */
-    protected List<IIOReadUpdateListener> updateListeners;
-
-    /**
-     * Instantiates a new ImageReader.
-     * 
-     * @param originatingProvider
-     *            the ImageReaderSpi which instantiates this ImageReader.
-     */
-    protected ImageReader(ImageReaderSpi originatingProvider) {
-        this.originatingProvider = originatingProvider;
-    }
-
-    /**
-     * Gets the format name of this input source.
-     * 
-     * @return the format name of this input source.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public String getFormatName() throws IOException {
-        return originatingProvider.getFormatNames()[0];
-    }
-
-    /**
-     * Gets the ImageReaderSpi which instantiated this ImageReader.
-     * 
-     * @return the ImageReaderSpi.
-     */
-    public ImageReaderSpi getOriginatingProvider() {
-        return originatingProvider;
-    }
-
-    /**
-     * Sets the specified Object as the input source of this ImageReader.
-     * 
-     * @param input
-     *            the input source, it can be an ImageInputStream or other
-     *            supported objects.
-     * @param seekForwardOnly
-     *            indicates whether the stream must be read sequentially from
-     *            its current starting point.
-     * @param ignoreMetadata
-     *            parameter which indicates if metadata may be ignored during
-     *            reads or not.
-     */
-    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
-        if (input != null) {
-            if (!isSupported(input) && !(input instanceof ImageInputStream)) {
-                throw new IllegalArgumentException("input " + input + " is not supported");
-            }
-        }
-        this.minIndex = 0;
-        this.seekForwardOnly = seekForwardOnly;
-        this.ignoreMetadata = ignoreMetadata;
-        this.input = input;
-    }
-
-    /**
-     * Checks if is supported.
-     * 
-     * @param input
-     *            the input.
-     * @return true, if is supported.
-     */
-    private boolean isSupported(Object input) {
-        ImageReaderSpi spi = getOriginatingProvider();
-        if (null != spi) {
-            Class[] outTypes = spi.getInputTypes();
-            for (Class<?> element : outTypes) {
-                if (element.isInstance(input)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Sets the specified Object as the input source of this ImageReader.
-     * Metadata is not ignored.
-     * 
-     * @param input
-     *            the input source, it can be an ImageInputStream or other
-     *            supported objects.
-     * @param seekForwardOnly
-     *            indicates whether the stream must be read sequentially from
-     *            its current starting point.
-     */
-    public void setInput(Object input, boolean seekForwardOnly) {
-        setInput(input, seekForwardOnly, false);
-    }
-
-    /**
-     * Sets the specified Object as the input source of this ImageReader.
-     * Metadata is not ignored and forward seeking is not required.
-     * 
-     * @param input
-     *            the input source, it can be ImageInputStream or other objects.
-     */
-    public void setInput(Object input) {
-        setInput(input, false, false);
-    }
-
-    /**
-     * Gets the input source object of this ImageReader, or returns null.
-     * 
-     * @return the input source object such as ImageInputStream, or null.
-     */
-    public Object getInput() {
-        return input;
-    }
-
-    /**
-     * Checks if the input source supports only forward reading, or not.
-     * 
-     * @return true, if the input source supports only forward reading, false
-     *         otherwise.
-     */
-    public boolean isSeekForwardOnly() {
-        return seekForwardOnly;
-    }
-
-    /**
-     * Returns true if the current input source allows to metadata to be ignored
-     * by passing true as the ignoreMetadata argument to the setInput method.
-     * 
-     * @return true, if the current input source allows to metadata to be
-     *         ignored by passing true as the ignoreMetadata argument to the
-     *         setInput method.
-     */
-    public boolean isIgnoringMetadata() {
-        return ignoreMetadata;
-    }
-
-    /**
-     * Gets the minimum valid index for reading an image, thumbnail, or image
-     * metadata.
-     * 
-     * @return the minimum valid index for reading an image, thumbnail, or image
-     *         metadata.
-     */
-    public int getMinIndex() {
-        return minIndex;
-    }
-
-    /**
-     * Gets the available locales.
-     * 
-     * @return an array of the available locales.
-     */
-    public Locale[] getAvailableLocales() {
-        return availableLocales;
-    }
-
-    /**
-     * Sets the locale to this ImageReader.
-     * 
-     * @param locale
-     *            the Locale.
-     */
-    public void setLocale(Locale locale) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Gets the locale of this ImageReader.
-     * 
-     * @return the locale of this ImageReader.
-     */
-    public Locale getLocale() {
-        return locale;
-    }
-
-    /**
-     * Gets the number of images available in the current input source.
-     * 
-     * @param allowSearch
-     *            the parameter which indicates what a search is required; if
-     *            false, the reader may return -1 without searching.
-     * @return the number of images.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract int getNumImages(boolean allowSearch) throws IOException;
-
-    /**
-     * Gets the width of the specified image in input source.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @return the width in pixels.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract int getWidth(int imageIndex) throws IOException;
-
-    /**
-     * Gets the height of the specified image in input source.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @return the height in pixels.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract int getHeight(int imageIndex) throws IOException;
-
-    /**
-     * Checks if the storage format of the specified image places an impediment
-     * on random pixels access or not.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @return true, if the storage format of the specified image places an
-     *         impediment on random pixels access, false otherwise.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public boolean isRandomAccessEasy(int imageIndex) throws IOException {
-        return false; // def
-    }
-
-    /**
-     * Gets the aspect ratio (width devided by height) of the image.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @return the aspect ratio of the image.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public float getAspectRatio(int imageIndex) throws IOException {
-        return (float)getWidth(imageIndex) / getHeight(imageIndex);
-    }
-
-    /**
-     * Gets an ImageTypeSpecifier which indicates the type of the specified
-     * image.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @return the ImageTypeSpecifier.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public ImageTypeSpecifier getRawImageType(int imageIndex) throws IOException {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Gets an Iterator of ImageTypeSpecifier objects which are associated with
-     * image types that may be used when decoding specified image.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @return an Iterator of ImageTypeSpecifier objects.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException;
-
-    /**
-     * Gets the default ImageReadParam object.
-     * 
-     * @return the ImageReadParam object.
-     */
-    public ImageReadParam getDefaultReadParam() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Gets an IIOMetadata object for this input source.
-     * 
-     * @return the IIOMetadata.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract IIOMetadata getStreamMetadata() throws IOException;
-
-    /**
-     * Gets an IIOMetadata object for this input source.
-     * 
-     * @param formatName
-     *            the desired metadata format to be used in the returned
-     *            IIOMetadata object.
-     * @param nodeNames
-     *            the node names of the document.
-     * @return the IIOMetadata.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public IIOMetadata getStreamMetadata(String formatName, Set<String> nodeNames)
-            throws IOException {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Gets the image metadata of the specified image in input source.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @return the IIOMetadata.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract IIOMetadata getImageMetadata(int imageIndex) throws IOException;
-
-    /**
-     * Gets the image metadata of the specified image input source.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param formatName
-     *            the desired metadata format to be used in the returned
-     *            IIOMetadata object.
-     * @param nodeNames
-     *            the node names which can be contained in the document.
-     * @return the IIOMetadata.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public IIOMetadata getImageMetadata(int imageIndex, String formatName, Set<String> nodeNames)
-            throws IOException {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Reads the specified image and returns it as a BufferedImage using the
-     * default ImageReadParam.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @return the BufferedImage.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public BufferedImage read(int imageIndex) throws IOException {
-        return read(imageIndex, null);
-    }
-
-    /**
-     * Reads the specified image and returns it as a BufferedImage using the
-     * specified ImageReadParam.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param param
-     *            the ImageReadParam.
-     * @return the BufferedImage.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract BufferedImage read(int imageIndex, ImageReadParam param) throws IOException;
-
-    /**
-     * Reads the specified image and returns an IIOImage with this image,
-     * thumbnails, and metadata for this image, using the specified
-     * ImageReadParam.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param param
-     *            the ImageReadParam.
-     * @return the IIOImage.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public IIOImage readAll(int imageIndex, ImageReadParam param) throws IOException {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Returns an Iterator of IIOImages from the input source.
-     * 
-     * @param params
-     *            the Iterator of ImageReadParam objects.
-     * @return the iterator of IIOImages.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public Iterator<IIOImage> readAll(Iterator<? extends ImageReadParam> params) throws IOException {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Checks whether or not this plug-in supports reading a Raster.
-     * 
-     * @return true, if this plug-in supports reading a Raster, false otherwise.
-     */
-    public boolean canReadRaster() {
-        return false; // def
-    }
-
-    /**
-     * Reads a new Raster object which contains the raw pixel data from the
-     * image.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param param
-     *            the ImageReadParam.
-     * @return the Raster.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public Raster readRaster(int imageIndex, ImageReadParam param) throws IOException {
-        throw new UnsupportedOperationException("Unsupported");
-    }
-
-    /**
-     * Checks if the specified image has tiles or not.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @return true, if the specified image has tiles, false otherwise.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public boolean isImageTiled(int imageIndex) throws IOException {
-        return false; // def
-    }
-
-    /**
-     * Gets the tile width in the specified image.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @return the tile width.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public int getTileWidth(int imageIndex) throws IOException {
-        return getWidth(imageIndex); // def
-    }
-
-    /**
-     * Gets the tile height in the specified image.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @return the tile height.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public int getTileHeight(int imageIndex) throws IOException {
-        return getHeight(imageIndex); // def
-    }
-
-    /**
-     * Gets the X coordinate of the upper left corner of the tile grid in the
-     * specified image.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @return the X coordinate of the upper left corner of the tile grid.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public int getTileGridXOffset(int imageIndex) throws IOException {
-        return 0; // def
-    }
-
-    /**
-     * Gets the Y coordinate of the upper left corner of the tile grid in the
-     * specified image.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @return the Y coordinate of the upper left corner of the tile grid.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public int getTileGridYOffset(int imageIndex) throws IOException {
-        return 0; // def
-    }
-
-    /**
-     * Reads the tile specified by the tileX and tileY parameters of the
-     * specified image and returns it as a BufferedImage.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param tileX
-     *            the X index of tile.
-     * @param tileY
-     *            the Y index of tile.
-     * @return the BufferedImage.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public BufferedImage readTile(int imageIndex, int tileX, int tileY) throws IOException {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Reads the tile specified by the tileX and tileY parameters of the
-     * specified image and returns it as a Raster.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param tileX
-     *            the X index of tile.
-     * @param tileY
-     *            the Y index of tile.
-     * @return the Raster.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public Raster readTileRaster(int imageIndex, int tileX, int tileY) throws IOException {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Reads the specified image using the specified ImageReadParam and returns
-     * it as a RenderedImage.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param param
-     *            the ImageReadParam.
-     * @return the RenderedImage.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public RenderedImage readAsRenderedImage(int imageIndex, ImageReadParam param)
-            throws IOException {
-        return read(imageIndex, param);
-    }
-
-    /**
-     * Returns true if the image format supported by this reader supports
-     * thumbnail preview images.
-     * 
-     * @return true, if the image format supported by this reader supports
-     *         thumbnail preview images, false otherwise.
-     */
-    public boolean readerSupportsThumbnails() {
-        return false; // def
-    }
-
-    /**
-     * Checks if the specified image has thumbnails or not.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @return true, if the specified image has thumbnails, false otherwise.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public boolean hasThumbnails(int imageIndex) throws IOException {
-        return getNumThumbnails(imageIndex) > 0; // def
-    }
-
-    /**
-     * Gets the number of thumbnails for the specified image.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @return the number of thumbnails.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public int getNumThumbnails(int imageIndex) throws IOException {
-        return 0; // def
-    }
-
-    /**
-     * Gets the width of the specified thumbnail for the specified image.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @param thumbnailIndex
-     *            the thumbnail's index.
-     * @return the thumbnail width.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public int getThumbnailWidth(int imageIndex, int thumbnailIndex) throws IOException {
-        return readThumbnail(imageIndex, thumbnailIndex).getWidth(); // def
-    }
-
-    /**
-     * Gets the height of the specified thumbnail for the specified image.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @param thumbnailIndex
-     *            the thumbnail's index.
-     * @return the thumbnail height.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public int getThumbnailHeight(int imageIndex, int thumbnailIndex) throws IOException {
-        return readThumbnail(imageIndex, thumbnailIndex).getHeight(); // def
-    }
-
-    /**
-     * Reads the thumbnail image for the specified image as a BufferedImage.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param thumbnailIndex
-     *            the thumbnail index.
-     * @return the BufferedImage.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public BufferedImage readThumbnail(int imageIndex, int thumbnailIndex) throws IOException {
-        throw new UnsupportedOperationException("Unsupported"); // def
-    }
-
-    /**
-     * Requests an abort operation for current reading operation.
-     */
-    public void abort() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Checks whether or not a request to abort the current read operation has
-     * been made successfully.
-     * 
-     * @return true, if the request to abort the current read operation has been
-     *         made successfully, false otherwise.
-     */
-    protected boolean abortRequested() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Clears all previous abort request, and abortRequested returns false after
-     * calling this method.
-     */
-    protected void clearAbortRequest() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Adds the IIOReadWarningListener.
-     * 
-     * @param listener
-     *            the IIOReadWarningListener.
-     */
-    public void addIIOReadWarningListener(IIOReadWarningListener listener) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Removes the specified IIOReadWarningListener.
-     * 
-     * @param listener
-     *            the IIOReadWarningListener to be removed.
-     */
-    public void removeIIOReadWarningListener(IIOReadWarningListener listener) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Removes all registered IIOReadWarningListeners.
-     */
-    public void removeAllIIOReadWarningListeners() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Adds the IIOReadProgressListener.
-     * 
-     * @param listener
-     *            the IIOReadProgressListener.
-     */
-    public void addIIOReadProgressListener(IIOReadProgressListener listener) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Removes the specified IIOReadProgressListener.
-     * 
-     * @param listener
-     *            the IIOReadProgressListener to be removed.
-     */
-    public void removeIIOReadProgressListener(IIOReadProgressListener listener) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Removes registered IIOReadProgressListeners.
-     */
-    public void removeAllIIOReadProgressListeners() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Adds the IIOReadUpdateListener.
-     * 
-     * @param listener
-     *            the IIOReadUpdateListener.
-     */
-    public void addIIOReadUpdateListener(IIOReadUpdateListener listener) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Removes the specified IIOReadUpdateListener.
-     * 
-     * @param listener
-     *            the IIOReadUpdateListener to be removed.
-     */
-    public void removeIIOReadUpdateListener(IIOReadUpdateListener listener) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Removes registered IIOReadUpdateListeners.
-     */
-    public void removeAllIIOReadUpdateListeners() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the start of an sequence of image reads by calling the
-     * sequenceStarted method on all registered IIOReadProgressListeners.
-     * 
-     * @param minIndex
-     *            the minimum index.
-     */
-    protected void processSequenceStarted(int minIndex) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the completion of an sequence of image reads by calling
-     * sequenceComplete method on all registered IIOReadProgressListeners.
-     */
-    protected void processSequenceComplete() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the start of an image read by calling the imageStarted method
-     * on all registered IIOReadProgressListeners.
-     * 
-     * @param imageIndex
-     *            the image index.
-     */
-    protected void processImageStarted(int imageIndex) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the current percentage of image completion by calling the
-     * imageProgress method on all registered IIOReadProgressListeners.
-     * 
-     * @param percentageDone
-     *            the percentage done.
-     */
-    protected void processImageProgress(float percentageDone) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes image completion by calling the imageComplete method on all
-     * registered IIOReadProgressListeners.
-     */
-    protected void processImageComplete() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the start of a thumbnail read by calling the thumbnailStarted
-     * method on all registered IIOReadProgressListeners.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param thumbnailIndex
-     *            the thumbnail index.
-     */
-    protected void processThumbnailStarted(int imageIndex, int thumbnailIndex) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the current percentage of thumbnail completion by calling the
-     * thumbnailProgress method on all registered IIOReadProgressListeners.
-     * 
-     * @param percentageDone
-     *            the percentage done.
-     */
-    protected void processThumbnailProgress(float percentageDone) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the completion of a thumbnail read by calling the
-     * thumbnailComplete method on all registered IIOReadProgressListeners.
-     */
-    protected void processThumbnailComplete() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes a read aborted event by calling the readAborted method on all
-     * registered IIOReadProgressListeners.
-     */
-    protected void processReadAborted() {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the beginning of a progressive pass by calling the passStarted
-     * method on all registered IIOReadUpdateListeners.
-     * 
-     * @param theImage
-     *            the image to be updated.
-     * @param pass
-     *            the current pass index.
-     * @param minPass
-     *            the minimum pass index.
-     * @param maxPass
-     *            the maximum pass index.
-     * @param minX
-     *            the X coordinate of of the upper left pixel.
-     * @param minY
-     *            the Y coordinate of of the upper left pixel.
-     * @param periodX
-     *            the horizontal separation between pixels.
-     * @param periodY
-     *            the vertical separation between pixels.
-     * @param bands
-     *            the number of affected bands.
-     */
-    protected void processPassStarted(BufferedImage theImage, int pass, int minPass, int maxPass,
-            int minX, int minY, int periodX, int periodY, int[] bands) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the update of a set of samples by calling the imageUpdate
-     * method on all registered IIOReadUpdateListeners.
-     * 
-     * @param theImage
-     *            the image to be updated.
-     * @param minX
-     *            the X coordinate of the upper left pixel.
-     * @param minY
-     *            the Y coordinate of the upper left pixel.
-     * @param width
-     *            the width of updated area.
-     * @param height
-     *            the height of updated area.
-     * @param periodX
-     *            the horizontal separation between pixels.
-     * @param periodY
-     *            the vertical separation between pixels.
-     * @param bands
-     *            the number of affected bands.
-     */
-    protected void processImageUpdate(BufferedImage theImage, int minX, int minY, int width,
-            int height, int periodX, int periodY, int[] bands) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the end of a progressive pass by calling passComplete method of
-     * registered IIOReadUpdateListeners.
-     * 
-     * @param theImage
-     *            the image to be updated.
-     */
-    protected void processPassComplete(BufferedImage theImage) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the beginning of a thumbnail progressive pass by calling the
-     * thumbnailPassStarted method on all registered IIOReadUpdateListeners.
-     * 
-     * @param theThumbnail
-     *            the thumbnail to be updated.
-     * @param pass
-     *            the current pass index.
-     * @param minPass
-     *            the minimum pass index.
-     * @param maxPass
-     *            the maximum pass index.
-     * @param minX
-     *            the X coordinate of the upper left pixel.
-     * @param minY
-     *            the Y coordinate of the upper left pixel.
-     * @param periodX
-     *            the horizontal separation between pixels.
-     * @param periodY
-     *            the vertical separation between pixels.
-     * @param bands
-     *            the number of affected bands.
-     */
-    protected void processThumbnailPassStarted(BufferedImage theThumbnail, int pass, int minPass,
-            int maxPass, int minX, int minY, int periodX, int periodY, int[] bands) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the update of a set of samples in a thumbnail image by calling
-     * the thumbnailUpdate method on all registered IIOReadUpdateListeners.
-     * 
-     * @param theThumbnail
-     *            the thumbnail to be updated.
-     * @param minX
-     *            the X coordinate of the upper left pixel.
-     * @param minY
-     *            the Y coordinate of the upper left pixel.
-     * @param width
-     *            the total width of the updated area.
-     * @param height
-     *            the total height of the updated area.
-     * @param periodX
-     *            the horizontal separation between pixels.
-     * @param periodY
-     *            the vertical separation between pixels.
-     * @param bands
-     *            the number of affected bands.
-     */
-    protected void processThumbnailUpdate(BufferedImage theThumbnail, int minX, int minY,
-            int width, int height, int periodX, int periodY, int[] bands) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes the end of a thumbnail progressive pass by calling the
-     * thumbnailPassComplete method on all registered IIOReadUpdateListeners.
-     * 
-     * @param theThumbnail
-     *            the thumbnail to be updated.
-     */
-    protected void processThumbnailPassComplete(BufferedImage theThumbnail) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes a warning message by calling warningOccurred method of
-     * registered IIOReadWarningListeners.
-     * 
-     * @param warning
-     *            the warning.
-     */
-    protected void processWarningOccurred(String warning) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Processes a warning by calling the warningOccurred method of on all
-     * registered IIOReadWarningListeners.
-     * 
-     * @param baseName
-     *            the base name of ResourceBundles.
-     * @param keyword
-     *            the keyword to index the warning among ResourceBundles.
-     */
-    protected void processWarningOccurred(String baseName, String keyword) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Resets this ImageReader.
-     */
-    public void reset() {
-        // def
-        setInput(null, false);
-        setLocale(null);
-        removeAllIIOReadUpdateListeners();
-        removeAllIIOReadWarningListeners();
-        removeAllIIOReadProgressListeners();
-        clearAbortRequest();
-    }
-
-    /**
-     * Disposes of any resources.
-     */
-    public void dispose() {
-        // do nothing by def
-    }
-
-    /**
-     * Gets the region of source image that should be read with the specified
-     * width, height and ImageReadParam.
-     * 
-     * @param param
-     *            the ImageReadParam object, or null.
-     * @param srcWidth
-     *            the source image's width.
-     * @param srcHeight
-     *            the source image's height.
-     * @return the Rectangle of source region.
-     */
-    protected static Rectangle getSourceRegion(ImageReadParam param, int srcWidth, int srcHeight) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Computes the specified source region and the specified destination region
-     * with the specified the width and height of the source image, an optional
-     * destination image, and an ImageReadParam.
-     * 
-     * @param param
-     *            the an ImageReadParam object, or null.
-     * @param srcWidth
-     *            the source image's width.
-     * @param srcHeight
-     *            the source image's height.
-     * @param image
-     *            the destination image.
-     * @param srcRegion
-     *            the source region.
-     * @param destRegion
-     *            the destination region.
-     */
-    protected static void computeRegions(ImageReadParam param, int srcWidth, int srcHeight,
-            BufferedImage image, Rectangle srcRegion, Rectangle destRegion) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Checks the validity of the source and destination band and is called when
-     * the reader knows the number of bands of the source image and the number
-     * of bands of the destination image.
-     * 
-     * @param param
-     *            the ImageReadParam for reading the Image.
-     * @param numSrcBands
-     *            the number of bands in the source.
-     * @param numDstBands
-     *            the number of bands in the destination.
-     */
-    protected static void checkReadParamBandSettings(ImageReadParam param, int numSrcBands,
-            int numDstBands) {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Gets the destination image where the decoded data is written.
-     * 
-     * @param param
-     *            the ImageReadParam.
-     * @param imageTypes
-     *            the iterator of ImageTypeSpecifier objects.
-     * @param width
-     *            the width of the image being decoded.
-     * @param height
-     *            the height of the image being decoded.
-     * @return the BufferedImage where decoded pixels should be written.
-     * @throws IIOException
-     *             the IIOException is thrown if there is no suitable
-     *             ImageTypeSpecifier.
-     */
-    protected static BufferedImage getDestination(ImageReadParam param,
-            Iterator<ImageTypeSpecifier> imageTypes, int width, int height) throws IIOException {
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-}
diff --git a/awt/javax/imageio/ImageTranscoder.java b/awt/javax/imageio/ImageTranscoder.java
deleted file mode 100644
index 632d890..0000000
--- a/awt/javax/imageio/ImageTranscoder.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio;
-
-import javax.imageio.metadata.IIOMetadata;
-import javax.imageio.ImageTypeSpecifier;
-
-/**
- * The ImageTranscoder interface is to be implemented by classes that perform
- * image transcoding operations, that is, take images written in one format and
- * write them in another format using read/write operations. Some image data can
- * be lost in such processes. The ImageTranscoder interface converts metadata
- * objects (IIOMetadata) of ImageReader to appropriate metadata object for
- * ImageWriter.
- * 
- * @since Android 1.0
- */
-public interface ImageTranscoder {
-
-    /**
-     * Converts the specified IIOMetadata object using the specified
-     * ImageWriteParam for obtaining writer's metadata structure.
-     * 
-     * @param inData
-     *            the IIOMetadata.
-     * @param param
-     *            the ImageWriteParam.
-     * @return the IIOMetadata, or null.
-     */
-    IIOMetadata convertStreamMetadata(IIOMetadata inData, ImageWriteParam param);
-
-    /**
-     * Converts the specified IIOMetadata object using the specified
-     * ImageWriteParam for obtaining writer's metadata structure and
-     * ImageTypeSpecifier object for obtaining the layout and color information
-     * of the image for this metadata.
-     * 
-     * @param inData
-     *            the IIOMetadata.
-     * @param imageType
-     *            the ImageTypeSpecifier.
-     * @param param
-     *            the ImageWriteParam.
-     * @return the IIOMetadata, or null.
-     */
-    IIOMetadata convertImageMetadata(IIOMetadata inData, ImageTypeSpecifier imageType,
-            ImageWriteParam param);
-}
diff --git a/awt/javax/imageio/ImageTypeSpecifier.java b/awt/javax/imageio/ImageTypeSpecifier.java
deleted file mode 100644
index 505b1c4..0000000
--- a/awt/javax/imageio/ImageTypeSpecifier.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio;
-
-import java.awt.image.ColorModel;
-import java.awt.image.SampleModel;
-import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
-import java.awt.color.ColorSpace;
-
-/**
- * The ImageTypeSpecifier class performs conversion operations on the
- * SampleModel and the ColorModel of an image.
- * 
- * @since Android 1.0
- */
-public class ImageTypeSpecifier {
-
-    /**
-     * The ColorModel of this ImageTypeSpecifier.
-     */
-    protected ColorModel colorModel;
-
-    /**
-     * The SampleModel of this ImageTypeSpecifier.
-     */
-    protected SampleModel sampleModel;
-
-    /**
-     * Instantiates a new ImageTypeSpecifier with the specified ColorModel and
-     * SampleModel objects.
-     * 
-     * @param colorModel
-     *            the ColorModel.
-     * @param sampleModel
-     *            the SampleModel.
-     */
-    public ImageTypeSpecifier(ColorModel colorModel, SampleModel sampleModel) {
-        if (colorModel == null) {
-            throw new IllegalArgumentException("color model should not be NULL");
-        }
-        if (sampleModel == null) {
-            throw new IllegalArgumentException("sample model should not be NULL");
-        }
-        if (!colorModel.isCompatibleSampleModel(sampleModel)) {
-            throw new IllegalArgumentException("color and sample models are not compatible");
-        }
-
-        this.colorModel = colorModel;
-        this.sampleModel = sampleModel;
-    }
-
-    /**
-     * Instantiates a new ImageTypeSpecifier using the specified RenderedImage.
-     * 
-     * @param renderedImage
-     *            the RenderedImage.
-     */
-    public ImageTypeSpecifier(RenderedImage renderedImage) {
-        if (renderedImage == null) {
-            throw new IllegalArgumentException("image should not be NULL");
-        }
-        this.colorModel = renderedImage.getColorModel();
-        this.sampleModel = renderedImage.getSampleModel();
-    }
-
-    /**
-     * Creates an ImageTypeSpecifier with the specified DirectColorModel and a
-     * packed SampleModel.
-     * 
-     * @param colorSpace
-     *            the ColorSpace.
-     * @param redMask
-     *            the red mask.
-     * @param greenMask
-     *            the green mask.
-     * @param blueMask
-     *            the blue mask.
-     * @param alphaMask
-     *            the alpha mask.
-     * @param transferType
-     *            the transfer type.
-     * @param isAlphaPremultiplied
-     *            the parameter indicates if the color channel is pre-multiplied
-     *            by alpha.
-     * @return the ImageTypeSpecifier.
-     */
-    public static ImageTypeSpecifier createPacked(ColorSpace colorSpace, int redMask,
-            int greenMask, int blueMask, int alphaMask, int transferType,
-            boolean isAlphaPremultiplied) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Creates an ImageTypeSpecifier with specified ComponentColorModel and a
-     * PixelInterleavedSampleModel.
-     * 
-     * @param colorSpace
-     *            the ColorSpace.
-     * @param bandOffsets
-     *            the band offsets.
-     * @param dataType
-     *            the data type.
-     * @param hasAlpha
-     *            the parameter indicates if alpha channel is needed.
-     * @param isAlphaPremultiplied
-     *            the parameter indicates if the color channel is pre-multiplied
-     *            by alpha.
-     * @return the ImageTypeSpecifier.
-     */
-    public static ImageTypeSpecifier createInterleaved(ColorSpace colorSpace, int[] bandOffsets,
-            int dataType, boolean hasAlpha, boolean isAlphaPremultiplied) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Creates a ImageTypeSpecifier for a image with a BandedSampleModel and a
-     * ComponentColorModel.
-     * 
-     * @param colorSpace
-     *            the ColorSpace.
-     * @param bankIndices
-     *            the bank indices.
-     * @param bandOffsets
-     *            the band offsets.
-     * @param dataType
-     *            the data type.
-     * @param hasAlpha
-     *            the parameter indicates a presence of alpha channel.
-     * @param isAlphaPremultiplied
-     *            the parameter indicates whether or not color channel is alpha
-     *            pre-multiplied.
-     * @return the image type specifier
-     */
-    public static ImageTypeSpecifier createBanded(ColorSpace colorSpace, int[] bankIndices,
-            int[] bandOffsets, int dataType, boolean hasAlpha, boolean isAlphaPremultiplied) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Creates a ImageTypeSpecifier for a grayscale image.
-     * 
-     * @param bits
-     *            the number of bits per gray value.
-     * @param dataType
-     *            the data type.
-     * @param isSigned
-     *            a signed flag.
-     * @return the ImageTypeSpecifier.
-     */
-    public static ImageTypeSpecifier createGrayscale(int bits, int dataType, boolean isSigned) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Creates a ImageTypeSpecifier for a grayscale image.
-     * 
-     * @param bits
-     *            the number of bits per gray value.
-     * @param dataType
-     *            the data type.
-     * @param isSigned
-     *            a signed flag.
-     * @param isAlphaPremultiplied
-     *            the parameter indicates if color channel is pre-multiplied by
-     *            alpha, or not.
-     * @return the ImageTypeSpecifier.
-     */
-    public static ImageTypeSpecifier createGrayscale(int bits, int dataType, boolean isSigned,
-            boolean isAlphaPremultiplied) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Creates a ImageTypeSpecifier with the indexed image format.
-     * 
-     * @param redLUT
-     *            the red values of indices.
-     * @param greenLUT
-     *            the green values of indices.
-     * @param blueLUT
-     *            the blue values of indices.
-     * @param alphaLUT
-     *            the alpha values of indices.
-     * @param bits
-     *            the bits number for each index.
-     * @param dataType
-     *            the data type.
-     * @return the ImageTypeSpecifier.
-     */
-    public static ImageTypeSpecifier createIndexed(byte[] redLUT, byte[] greenLUT, byte[] blueLUT,
-            byte[] alphaLUT, int bits, int dataType) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Creates the ImageTypeSpecifier from the specified buffered image type.
-     * 
-     * @param bufferedImageType
-     *            the buffered image type.
-     * @return the ImageTypeSpecifier.
-     */
-    public static ImageTypeSpecifier createFromBufferedImageType(int bufferedImageType) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Creates the ImageTypeSpecifier from the specified RenderedImage.
-     * 
-     * @param image
-     *            the RenderedImage.
-     * @return the ImageTypeSpecifier.
-     */
-    public static ImageTypeSpecifier createFromRenderedImage(RenderedImage image) {
-        if (null == image) {
-            throw new IllegalArgumentException("image should not be NULL");
-        }
-        return new ImageTypeSpecifier(image);
-    }
-
-    /**
-     * Gets the BufferedImage type.
-     * 
-     * @return the BufferedImage type.
-     */
-    public int getBufferedImageType() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets the number of components.
-     * 
-     * @return the number of components.
-     */
-    public int getNumComponents() {
-        return colorModel.getNumComponents();
-    }
-
-    /**
-     * Gets the number of bands.
-     * 
-     * @return the number of bands.
-     */
-    public int getNumBands() {
-        return sampleModel.getNumBands();
-    }
-
-    /**
-     * Gets the number of bits per the specified band.
-     * 
-     * @param band
-     *            the index of band.
-     * @return the number of bits per the specified band.
-     */
-    public int getBitsPerBand(int band) {
-        if (band < 0 || band >= getNumBands()) {
-            throw new IllegalArgumentException();
-        }
-        return sampleModel.getSampleSize(band);
-    }
-
-    /**
-     * Gets the SampleModel associated with this ImageTypeSpecifier.
-     * 
-     * @return the SampleModel associated with this ImageTypeSpecifier.
-     */
-    public SampleModel getSampleModel() {
-        return sampleModel;
-    }
-
-    /**
-     * Gets a compatible SampleModel with the specified width and height.
-     * 
-     * @param width
-     *            the width.
-     * @param height
-     *            the height.
-     * @return the SampleModel.
-     */
-    public SampleModel getSampleModel(int width, int height) {
-        if ((long)width * height > Integer.MAX_VALUE) {
-            throw new IllegalArgumentException("width * height > Integer.MAX_VALUE");
-        }
-        return sampleModel.createCompatibleSampleModel(width, height);
-    }
-
-    /**
-     * Gets the ColorModel associated with this ImageTypeSpecifier.
-     * 
-     * @return the ColorModel associated with this ImageTypeSpecifier.
-     */
-    public ColorModel getColorModel() {
-        return colorModel;
-    }
-
-    /**
-     * Creates the BufferedImage with the specified width and height and the
-     * ColorMadel and SampleModel which are specified by this
-     * ImageTypeSpecifier.
-     * 
-     * @param width
-     *            the width of the BufferedImage.
-     * @param height
-     *            the height of the BufferedImage.
-     * @return the BufferedImage.
-     */
-    public BufferedImage createBufferedImage(int width, int height) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Compares this ImageTypeSpecifier object with the specified object.
-     * 
-     * @param o
-     *            the Object to be compared.
-     * @return true, if the object is an ImageTypeSpecifier with the same data
-     *         as this ImageTypeSpecifier, false otherwise.
-     */
-    @Override
-    public boolean equals(Object o) {
-        boolean rt = false;
-        if (o instanceof ImageTypeSpecifier) {
-            ImageTypeSpecifier ts = (ImageTypeSpecifier)o;
-            rt = colorModel.equals(ts.colorModel) && sampleModel.equals(ts.sampleModel);
-        }
-        return rt;
-    }
-}
\ No newline at end of file
diff --git a/awt/javax/imageio/ImageWriteParam.java b/awt/javax/imageio/ImageWriteParam.java
deleted file mode 100644
index d661889..0000000
--- a/awt/javax/imageio/ImageWriteParam.java
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio;
-
-import java.util.Locale;
-import java.awt.*;
-
-/**
- * The ImageWriteParam class provides information to an ImageWriter about how an
- * image is to be encoded.
- * 
- * @since Android 1.0
- */
-public class ImageWriteParam extends IIOParam {
-
-    /**
-     * The Constant MODE_DISABLED indicates that stream is not tiled,
-     * progressive, or compressed.
-     */
-    public static final int MODE_DISABLED = 0;
-
-    /**
-     * The Constant MODE_DEFAULT indicates that the stream will be tiled,
-     * progressive, or compressed according to the plug-in's default.
-     */
-    public static final int MODE_DEFAULT = 1;
-
-    /**
-     * The Constant MODE_EXPLICIT indicates that the stream will be tiled,
-     * progressive, or compressed according to current settings which are
-     * defined by set methods.
-     */
-    public static final int MODE_EXPLICIT = 2;
-
-    /**
-     * The Constant MODE_COPY_FROM_METADATA indicates that the stream will be
-     * tiled, progressive, or compressed according to stream or image metadata.
-     */
-    public static final int MODE_COPY_FROM_METADATA = 3;
-
-    /**
-     * Whether the ImageWriter can write tiles.
-     */
-    protected boolean canWriteTiles = false;
-
-    /**
-     * The tiling mode.
-     */
-    protected int tilingMode = MODE_COPY_FROM_METADATA;
-
-    /**
-     * The preferred tile sizes.
-     */
-    protected Dimension[] preferredTileSizes = null;
-
-    /**
-     * The tiling set.
-     */
-    protected boolean tilingSet = false;
-
-    /**
-     * The tile width.
-     */
-    protected int tileWidth = 0;
-
-    /**
-     * The tile height.
-     */
-    protected int tileHeight = 0;
-
-    /**
-     * Whether the ImageWriter can offset tiles.
-     */
-    protected boolean canOffsetTiles = false;
-
-    /**
-     * The tile grid x offset.
-     */
-    protected int tileGridXOffset = 0;
-
-    /**
-     * The tile grid y offset.
-     */
-    protected int tileGridYOffset = 0;
-
-    /**
-     * Whether the ImageWriter can write in progressive mode.
-     */
-    protected boolean canWriteProgressive = false;
-
-    /**
-     * The progressive mode.
-     */
-    protected int progressiveMode = MODE_COPY_FROM_METADATA;
-
-    /**
-     * Whether the ImageWriter can write in compressed mode.
-     */
-    protected boolean canWriteCompressed = false;
-
-    /**
-     * The compression mode.
-     */
-    protected int compressionMode = MODE_COPY_FROM_METADATA;
-
-    /**
-     * The compression types.
-     */
-    protected String[] compressionTypes = null;
-
-    /**
-     * The compression type.
-     */
-    protected String compressionType = null;
-
-    /**
-     * The compression quality.
-     */
-    protected float compressionQuality = 1.0f;
-
-    /**
-     * The locale.
-     */
-    protected Locale locale = null;
-
-    /**
-     * Instantiates a new ImageWriteParam.
-     */
-    protected ImageWriteParam() {
-    }
-
-    /**
-     * Instantiates a new ImageWriteParam with the specified Locale.
-     * 
-     * @param locale
-     *            the Locale.
-     */
-    public ImageWriteParam(Locale locale) {
-        this.locale = locale;
-
-    }
-
-    /**
-     * Gets the mode for writing the stream in a progressive sequence.
-     * 
-     * @return the current progressive mode.
-     */
-    public int getProgressiveMode() {
-        if (canWriteProgressive()) {
-            return progressiveMode;
-        }
-        throw new UnsupportedOperationException("progressive mode is not supported");
-    }
-
-    /**
-     * Returns true if images can be written using increasing quality passes by
-     * progressive.
-     * 
-     * @return true if images can be written using increasing quality passes by
-     *         progressive, false otherwise.
-     */
-    public boolean canWriteProgressive() {
-        return canWriteProgressive;
-    }
-
-    /**
-     * Sets the progressive mode which defines whether the stream contains a
-     * progressive sequence of increasing quality during writing. The
-     * progressive mode should be one of the following values: MODE_DISABLED,
-     * MODE_DEFAULT, or MODE_COPY_FROM_METADATA.
-     * 
-     * @param mode
-     *            the new progressive mode.
-     */
-    public void setProgressiveMode(int mode) {
-        if (canWriteProgressive()) {
-            if (mode < MODE_DISABLED || mode > MODE_COPY_FROM_METADATA || mode == MODE_EXPLICIT) {
-                throw new IllegalArgumentException("mode is not supported");
-            }
-            this.progressiveMode = mode;
-        }
-        throw new UnsupportedOperationException("progressive mode is not supported");
-    }
-
-    /**
-     * Returns true if the writer can use tiles with non zero grid offsets while
-     * writing.
-     * 
-     * @return true, if the writer can use tiles with non zero grid offsets
-     *         while writing, false otherwise.
-     */
-    public boolean canOffsetTiles() {
-        return canOffsetTiles;
-    }
-
-    /**
-     * Returns true if this writer can write images with compression.
-     * 
-     * @return true, if this writer can write images with compression, false
-     *         otherwise.
-     */
-    public boolean canWriteCompressed() {
-        return canWriteCompressed;
-    }
-
-    /**
-     * Returns true if the writer can write tiles.
-     * 
-     * @return true, if the writer can write tiles, false otherwise.
-     */
-    public boolean canWriteTiles() {
-        return canWriteTiles;
-    }
-
-    /**
-     * Check write compressed.
-     */
-    private final void checkWriteCompressed() {
-        if (!canWriteCompressed()) {
-            throw new UnsupportedOperationException("Compression not supported.");
-        }
-    }
-
-    /**
-     * Check compression mode.
-     */
-    private final void checkCompressionMode() {
-        if (getCompressionMode() != MODE_EXPLICIT) {
-            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
-        }
-    }
-
-    /**
-     * Check compression type.
-     */
-    private final void checkCompressionType() {
-        if (getCompressionTypes() != null && getCompressionType() == null) {
-            throw new IllegalStateException("No compression type set!");
-        }
-    }
-
-    /**
-     * Gets the compression mode.
-     * 
-     * @return the compression mode if it's supported.
-     */
-    public int getCompressionMode() {
-        checkWriteCompressed();
-        return compressionMode;
-    }
-
-    /**
-     * Gets the an array of supported compression types.
-     * 
-     * @return the an array of supported compression types.
-     */
-    public String[] getCompressionTypes() {
-        checkWriteCompressed();
-        if (compressionTypes != null) {
-            return compressionTypes.clone();
-        }
-        return null;
-    }
-
-    /**
-     * Gets the current compression type, or returns null.
-     * 
-     * @return the current compression type, or returns null if it is not set.
-     */
-    public String getCompressionType() {
-        checkWriteCompressed();
-        checkCompressionMode();
-        return compressionType;
-    }
-
-    /**
-     * Gets a bit rate which represents an estimate of the number of bits of
-     * output data for each bit of input image data with the specified quality.
-     * 
-     * @param quality
-     *            the quality.
-     * @return an estimate of the bit rate, or -1.0F if there is no estimate.
-     */
-    public float getBitRate(float quality) {
-        checkWriteCompressed();
-        checkCompressionMode();
-        checkCompressionType();
-        if (quality < 0 || quality > 1) {
-            throw new IllegalArgumentException("Quality out-of-bounds!");
-        }
-        return -1.0f;
-    }
-
-    /**
-     * Gets the compression quality.
-     * 
-     * @return the compression quality.
-     */
-    public float getCompressionQuality() {
-        checkWriteCompressed();
-        checkCompressionMode();
-        checkCompressionType();
-        return compressionQuality;
-    }
-
-    /**
-     * Gets the array of compression quality descriptions.
-     * 
-     * @return the string array of compression quality descriptions.
-     */
-    public String[] getCompressionQualityDescriptions() {
-        checkWriteCompressed();
-        checkCompressionMode();
-        checkCompressionType();
-        return null;
-    }
-
-    /**
-     * Gets an array of floats which describes compression quality levels.
-     * 
-     * @return the array of compression quality values.
-     */
-    public float[] getCompressionQualityValues() {
-        checkWriteCompressed();
-        checkCompressionMode();
-        checkCompressionType();
-        return null;
-    }
-
-    /**
-     * Gets the locale of this ImageWriteParam.
-     * 
-     * @return the locale of this ImageWriteParam.
-     */
-    public Locale getLocale() {
-        return locale;
-    }
-
-    /**
-     * Gets the current compression type using the current Locale.
-     * 
-     * @return the current compression type using the current Locale.
-     */
-    public String getLocalizedCompressionTypeName() {
-        checkWriteCompressed();
-        checkCompressionMode();
-
-        String compressionType = getCompressionType();
-        if (compressionType == null) {
-            throw new IllegalStateException("No compression type set!");
-        }
-        return compressionType;
-
-    }
-
-    /**
-     * Check tiling.
-     */
-    private final void checkTiling() {
-        if (!canWriteTiles()) {
-            throw new UnsupportedOperationException("Tiling not supported!");
-        }
-    }
-
-    /**
-     * Check tiling mode.
-     */
-    private final void checkTilingMode() {
-        if (getTilingMode() != MODE_EXPLICIT) {
-            throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
-        }
-    }
-
-    /**
-     * Check tiling params.
-     */
-    private final void checkTilingParams() {
-        if (!tilingSet) {
-            throw new IllegalStateException("Tiling parameters not set!");
-        }
-    }
-
-    /**
-     * Gets the tiling mode if tiling is supported.
-     * 
-     * @return the tiling mode if tiling is supported.
-     */
-    public int getTilingMode() {
-        checkTiling();
-        return tilingMode;
-    }
-
-    /**
-     * Gets an array of Dimensions giving the sizes of the tiles as they are
-     * encoded in the output file or stream.
-     * 
-     * @return the preferred tile sizes.
-     */
-    public Dimension[] getPreferredTileSizes() {
-        checkTiling();
-        if (preferredTileSizes == null) {
-            return null;
-        }
-
-        Dimension[] retval = new Dimension[preferredTileSizes.length];
-        for (int i = 0; i < preferredTileSizes.length; i++) {
-            retval[i] = new Dimension(retval[i]);
-        }
-        return retval;
-    }
-
-    /**
-     * Gets the tile grid X offset for encoding.
-     * 
-     * @return the tile grid X offset for encoding.
-     */
-    public int getTileGridXOffset() {
-        checkTiling();
-        checkTilingMode();
-        checkTilingParams();
-        return tileGridXOffset;
-    }
-
-    /**
-     * Gets the tile grid Y offset for encoding.
-     * 
-     * @return the tile grid Y offset for encoding.
-     */
-    public int getTileGridYOffset() {
-        checkTiling();
-        checkTilingMode();
-        checkTilingParams();
-        return tileGridYOffset;
-    }
-
-    /**
-     * Gets the tile height in an image as it is written to the output stream.
-     * 
-     * @return the tile height in an image as it is written to the output
-     *         stream.
-     */
-    public int getTileHeight() {
-        checkTiling();
-        checkTilingMode();
-        checkTilingParams();
-        return tileHeight;
-    }
-
-    /**
-     * Gets the tile width in an image as it is written to the output stream.
-     * 
-     * @return the tile width in an image as it is written to the output stream.
-     */
-    public int getTileWidth() {
-        checkTiling();
-        checkTilingMode();
-        checkTilingParams();
-        return tileWidth;
-    }
-
-    /**
-     * Checks if the current compression type has lossless compression or not.
-     * 
-     * @return true, if the current compression type has lossless compression,
-     *         false otherwise.
-     */
-    public boolean isCompressionLossless() {
-        checkWriteCompressed();
-        checkCompressionMode();
-        checkCompressionType();
-        return true;
-    }
-
-    /**
-     * Removes current compression type.
-     */
-    public void unsetCompression() {
-        checkWriteCompressed();
-        checkCompressionMode();
-        compressionType = null;
-        compressionQuality = 1;
-    }
-
-    /**
-     * Sets the compression mode to the specified value. The specified mode can
-     * be one of the predefined constants: MODE_DEFAULT, MODE_DISABLED,
-     * MODE_EXPLICIT, or MODE_COPY_FROM_METADATA.
-     * 
-     * @param mode
-     *            the new compression mode to be set.
-     */
-    public void setCompressionMode(int mode) {
-        checkWriteCompressed();
-        switch (mode) {
-            case MODE_EXPLICIT: {
-                compressionMode = mode;
-                unsetCompression();
-                break;
-            }
-            case MODE_COPY_FROM_METADATA:
-            case MODE_DISABLED:
-            case MODE_DEFAULT: {
-                compressionMode = mode;
-                break;
-            }
-            default: {
-                throw new IllegalArgumentException("Illegal value for mode!");
-            }
-        }
-    }
-
-    /**
-     * Sets the compression quality. The value should be between 0 and 1.
-     * 
-     * @param quality
-     *            the new compression quality, float value between 0 and 1.
-     */
-    public void setCompressionQuality(float quality) {
-        checkWriteCompressed();
-        checkCompressionMode();
-        checkCompressionType();
-        if (quality < 0 || quality > 1) {
-            throw new IllegalArgumentException("Quality out-of-bounds!");
-        }
-        compressionQuality = quality;
-    }
-
-    /**
-     * Sets the compression type. The specified string should be one of the
-     * values returned by getCompressionTypes method.
-     * 
-     * @param compressionType
-     *            the new compression type.
-     */
-    public void setCompressionType(String compressionType) {
-        checkWriteCompressed();
-        checkCompressionMode();
-
-        if (compressionType == null) { // Don't check anything
-            this.compressionType = null;
-        } else {
-            String[] compressionTypes = getCompressionTypes();
-            if (compressionTypes == null) {
-                throw new UnsupportedOperationException("No settable compression types");
-            }
-
-            for (int i = 0; i < compressionTypes.length; i++) {
-                if (compressionTypes[i].equals(compressionType)) {
-                    this.compressionType = compressionType;
-                    return;
-                }
-            }
-
-            // Compression type is not in the list.
-            throw new IllegalArgumentException("Unknown compression type!");
-        }
-    }
-
-    /**
-     * Sets the instruction that tiling should be performed for the image in the
-     * output stream with the specified parameters.
-     * 
-     * @param tileWidth
-     *            the tile's width.
-     * @param tileHeight
-     *            the tile's height.
-     * @param tileGridXOffset
-     *            the tile grid's x offset.
-     * @param tileGridYOffset
-     *            the tile grid's y offset.
-     */
-    public void setTiling(int tileWidth, int tileHeight, int tileGridXOffset, int tileGridYOffset) {
-        checkTiling();
-        checkTilingMode();
-
-        if (!canOffsetTiles() && (tileGridXOffset != 0 || tileGridYOffset != 0)) {
-            throw new UnsupportedOperationException("Can't offset tiles!");
-        }
-
-        if (tileWidth <= 0 || tileHeight <= 0) {
-            throw new IllegalArgumentException("tile dimensions are non-positive!");
-        }
-
-        Dimension preferredTileSizes[] = getPreferredTileSizes();
-        if (preferredTileSizes != null) {
-            for (int i = 0; i < preferredTileSizes.length; i += 2) {
-                Dimension minSize = preferredTileSizes[i];
-                Dimension maxSize = preferredTileSizes[i + 1];
-                if (tileWidth < minSize.width || tileWidth > maxSize.width
-                        || tileHeight < minSize.height || tileHeight > maxSize.height) {
-                    throw new IllegalArgumentException("Illegal tile size!");
-                }
-            }
-        }
-
-        tilingSet = true;
-        this.tileWidth = tileWidth;
-        this.tileHeight = tileHeight;
-        this.tileGridXOffset = tileGridXOffset;
-        this.tileGridYOffset = tileGridYOffset;
-    }
-
-    /**
-     * Clears all tiling settings.
-     */
-    public void unsetTiling() {
-        checkTiling();
-        checkTilingMode();
-
-        tilingSet = false;
-        tileWidth = 0;
-        tileHeight = 0;
-        tileGridXOffset = 0;
-        tileGridYOffset = 0;
-    }
-
-    /**
-     * Sets the tiling mode. The specified mode should be one of the following
-     * values: MODE_DISABLED, MODE_DEFAULT, MODE_EXPLICIT, or
-     * MODE_COPY_FROM_METADATA.
-     * 
-     * @param mode
-     *            the new tiling mode.
-     */
-    public void setTilingMode(int mode) {
-        checkTiling();
-
-        switch (mode) {
-            case MODE_EXPLICIT: {
-                tilingMode = mode;
-                unsetTiling();
-                break;
-            }
-            case MODE_COPY_FROM_METADATA:
-            case MODE_DISABLED:
-            case MODE_DEFAULT: {
-                tilingMode = mode;
-                break;
-            }
-            default: {
-                throw new IllegalArgumentException("Illegal value for mode!");
-            }
-        }
-    }
-}
diff --git a/awt/javax/imageio/ImageWriter.java b/awt/javax/imageio/ImageWriter.java
deleted file mode 100644
index 86879e0..0000000
--- a/awt/javax/imageio/ImageWriter.java
+++ /dev/null
@@ -1,1001 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio;
-
-import java.awt.Dimension;
-import java.awt.Rectangle;
-import java.awt.image.BufferedImage;
-import java.awt.image.Raster;
-import java.awt.image.RenderedImage;
-import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-import javax.imageio.event.IIOWriteProgressListener;
-import javax.imageio.event.IIOWriteWarningListener;
-import javax.imageio.metadata.IIOMetadata;
-import javax.imageio.spi.ImageWriterSpi;
-
-/**
- * The ImageWriter class is an abstract class for encoding images. ImageWriter
- * objects are instantiated by the service provider interface, ImageWriterSpi
- * class, for the specific format. ImageWriterSpi class should be registered
- * with the IIORegistry, which uses them for format recognition and presentation
- * of available format readers and writers.
- * 
- * @since Android 1.0
- */
-public abstract class ImageWriter implements ImageTranscoder {
-
-    /**
-     * The available locales.
-     */
-    protected Locale[] availableLocales;
-
-    /**
-     * The locale.
-     */
-    protected Locale locale;
-
-    /**
-     * The originating provider.
-     */
-    protected ImageWriterSpi originatingProvider;
-
-    /**
-     * The output.
-     */
-    protected Object output;
-
-    /**
-     * The progress listeners.
-     */
-    protected List<IIOWriteProgressListener> progressListeners;
-
-    /**
-     * The warning listeners.
-     */
-    protected List<IIOWriteWarningListener> warningListeners;
-
-    /**
-     * The warning locales.
-     */
-    protected List<Locale> warningLocales;
-
-    // Indicates that abort operation is requested
-    // Abort mechanism should be thread-safe
-    /** The aborted. */
-    private boolean aborted;
-
-    /**
-     * Instantiates a new ImageWriter.
-     * 
-     * @param originatingProvider
-     *            the ImageWriterSpi which instantiates this ImageWriter.
-     */
-    protected ImageWriter(ImageWriterSpi originatingProvider) {
-        this.originatingProvider = originatingProvider;
-    }
-
-    public abstract IIOMetadata convertStreamMetadata(IIOMetadata iioMetadata,
-            ImageWriteParam imageWriteParam);
-
-    public abstract IIOMetadata convertImageMetadata(IIOMetadata iioMetadata,
-            ImageTypeSpecifier imageTypeSpecifier, ImageWriteParam imageWriteParam);
-
-    /**
-     * Gets the ImageWriterSpi which instantiated this ImageWriter.
-     * 
-     * @return the ImageWriterSpi.
-     */
-    public ImageWriterSpi getOriginatingProvider() {
-        return originatingProvider;
-    }
-
-    /**
-     * Processes the start of an image read by calling their imageStarted method
-     * of registered IIOWriteProgressListeners.
-     * 
-     * @param imageIndex
-     *            the image index.
-     */
-    protected void processImageStarted(int imageIndex) {
-        if (null != progressListeners) {
-            for (IIOWriteProgressListener listener : progressListeners) {
-                listener.imageStarted(this, imageIndex);
-            }
-        }
-    }
-
-    /**
-     * Processes the current percentage of image completion by calling
-     * imageProgress method of registered IIOWriteProgressListener.
-     * 
-     * @param percentageDone
-     *            the percentage done.
-     */
-    protected void processImageProgress(float percentageDone) {
-        if (null != progressListeners) {
-            for (IIOWriteProgressListener listener : progressListeners) {
-                listener.imageProgress(this, percentageDone);
-            }
-        }
-    }
-
-    /**
-     * Processes image completion by calling imageComplete method of registered
-     * IIOWriteProgressListeners.
-     */
-    protected void processImageComplete() {
-        if (null != progressListeners) {
-            for (IIOWriteProgressListener listener : progressListeners) {
-                listener.imageComplete(this);
-            }
-        }
-    }
-
-    /**
-     * Processes a warning message by calling warningOccurred method of
-     * registered IIOWriteWarningListeners.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param warning
-     *            the warning.
-     */
-    protected void processWarningOccurred(int imageIndex, String warning) {
-        if (null == warning) {
-            throw new NullPointerException("warning message should not be NULL");
-        }
-        if (null != warningListeners) {
-            for (IIOWriteWarningListener listener : warningListeners) {
-                listener.warningOccurred(this, imageIndex, warning);
-            }
-        }
-    }
-
-    /**
-     * Processes a warning message by calling warningOccurred method of
-     * registered IIOWriteWarningListeners with string from ResourceBundle.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param bundle
-     *            the name of ResourceBundle.
-     * @param key
-     *            the keyword.
-     */
-    protected void processWarningOccurred(int imageIndex, String bundle, String key) {
-        if (warningListeners != null) { // Don't check the parameters
-            return;
-        }
-
-        if (bundle == null) {
-            throw new IllegalArgumentException("baseName == null!");
-        }
-        if (key == null) {
-            throw new IllegalArgumentException("keyword == null!");
-        }
-
-        // Get the context class loader and try to locate the bundle with it
-        // first
-        ClassLoader contextClassloader = AccessController
-                .doPrivileged(new PrivilegedAction<ClassLoader>() {
-                    public ClassLoader run() {
-                        return Thread.currentThread().getContextClassLoader();
-                    }
-                });
-
-        // Iterate through both listeners and locales
-        int n = warningListeners.size();
-        for (int i = 0; i < n; i++) {
-            IIOWriteWarningListener listener = warningListeners.get(i);
-            Locale locale = warningLocales.get(i);
-
-            // Now try to get the resource bundle
-            ResourceBundle rb;
-            try {
-                rb = ResourceBundle.getBundle(bundle, locale, contextClassloader);
-            } catch (MissingResourceException e) {
-                try {
-                    rb = ResourceBundle.getBundle(bundle, locale);
-                } catch (MissingResourceException e1) {
-                    throw new IllegalArgumentException("Bundle not found!");
-                }
-            }
-
-            try {
-                String warning = rb.getString(key);
-                listener.warningOccurred(this, imageIndex, warning);
-            } catch (MissingResourceException e) {
-                throw new IllegalArgumentException("Resource is missing!");
-            } catch (ClassCastException e) {
-                throw new IllegalArgumentException("Resource is not a String!");
-            }
-        }
-    }
-
-    /**
-     * Sets the specified Object to the output of this ImageWriter.
-     * 
-     * @param output
-     *            the Object which represents destination, it can be
-     *            ImageOutputStream or other objects.
-     */
-    public void setOutput(Object output) {
-        if (output != null) {
-            ImageWriterSpi spi = getOriginatingProvider();
-            if (null != spi) {
-                Class[] outTypes = spi.getOutputTypes();
-                boolean supported = false;
-                for (Class<?> element : outTypes) {
-                    if (element.isInstance(output)) {
-                        supported = true;
-                        break;
-                    }
-                }
-                if (!supported) {
-                    throw new IllegalArgumentException("output " + output + " is not supported");
-                }
-            }
-        }
-        this.output = output;
-    }
-
-    /**
-     * Writes a completed image stream that contains the specified image,
-     * default metadata, and thumbnails to the output.
-     * 
-     * @param image
-     *            the specified image to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred during writing.
-     */
-    public void write(IIOImage image) throws IOException {
-        write(null, image, null);
-    }
-
-    /**
-     * Writes a completed image stream that contains the specified rendered
-     * image, default metadata, and thumbnails to the output.
-     * 
-     * @param image
-     *            the specified RenderedImage to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred during writing.
-     */
-    public void write(RenderedImage image) throws IOException {
-        write(null, new IIOImage(image, null, null), null);
-    }
-
-    /**
-     * Writes a completed image stream that contains the specified image,
-     * metadata and thumbnails to the output.
-     * 
-     * @param streamMetadata
-     *            the stream metadata, or null.
-     * @param image
-     *            the specified image to be written, if canWriteRaster() method
-     *            returns false, then Image must contain only RenderedImage.
-     * @param param
-     *            the ImageWriteParam, or null.
-     * @throws IOException
-     *             if an error occurs during writing.
-     */
-    public abstract void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param)
-            throws IOException;
-
-    /**
-     * Disposes of any resources.
-     */
-    public void dispose() {
-        // def impl. does nothing according to the spec.
-    }
-
-    /**
-     * Requests an abort operation for current writing operation.
-     */
-    public synchronized void abort() {
-        aborted = true;
-    }
-
-    /**
-     * Checks whether or not a request to abort the current write operation has
-     * been made successfully.
-     * 
-     * @return true, if the request to abort the current write operation has
-     *         been made successfully, false otherwise.
-     */
-    protected synchronized boolean abortRequested() {
-        return aborted;
-    }
-
-    /**
-     * Clears all previous abort request, and abortRequested returns false after
-     * calling this method.
-     */
-    protected synchronized void clearAbortRequest() {
-        aborted = false;
-    }
-
-    /**
-     * Adds the IIOWriteProgressListener listener.
-     * 
-     * @param listener
-     *            the IIOWriteProgressListener listener.
-     */
-    public void addIIOWriteProgressListener(IIOWriteProgressListener listener) {
-        if (listener == null) {
-            return;
-        }
-
-        if (progressListeners == null) {
-            progressListeners = new ArrayList<IIOWriteProgressListener>();
-        }
-
-        progressListeners.add(listener);
-    }
-
-    /**
-     * Adds the IIOWriteWarningListener.
-     * 
-     * @param listener
-     *            the IIOWriteWarningListener listener.
-     */
-    public void addIIOWriteWarningListener(IIOWriteWarningListener listener) {
-        if (listener == null) {
-            return;
-        }
-
-        if (warningListeners == null) {
-            warningListeners = new ArrayList<IIOWriteWarningListener>();
-            warningLocales = new ArrayList<Locale>();
-        }
-
-        warningListeners.add(listener);
-        warningLocales.add(getLocale());
-    }
-
-    /**
-     * Gets the output object that was set by setOutput method.
-     * 
-     * @return the output object such as ImageOutputStream, or null if it is not
-     *         set.
-     */
-    public Object getOutput() {
-        return output;
-    }
-
-    /**
-     * Check output return false.
-     * 
-     * @return true, if successful.
-     */
-    private final boolean checkOutputReturnFalse() {
-        if (getOutput() == null) {
-            throw new IllegalStateException("getOutput() == null!");
-        }
-        return false;
-    }
-
-    /**
-     * Unsupported operation.
-     */
-    private final void unsupportedOperation() {
-        if (getOutput() == null) {
-            throw new IllegalStateException("getOutput() == null!");
-        }
-        throw new UnsupportedOperationException("Unsupported write variant!");
-    }
-
-    /**
-     * Returns true if a new empty image can be inserted at the specified index.
-     * 
-     * @param imageIndex
-     *            the specified index of image.
-     * @return true if a new empty image can be inserted at the specified index,
-     *         false otherwise.
-     * @throws IOException
-     *             Signals that an I/O exception has occurred.
-     */
-    public boolean canInsertEmpty(int imageIndex) throws IOException {
-        return checkOutputReturnFalse();
-    }
-
-    /**
-     * Returns true if a new image can be inserted at the specified index.
-     * 
-     * @param imageIndex
-     *            the specified index of image.
-     * @return true if a new image can be inserted at the specified index, false
-     *         otherwise.
-     * @throws IOException
-     *             Signals that an I/O exception has occurred.
-     */
-    public boolean canInsertImage(int imageIndex) throws IOException {
-        return checkOutputReturnFalse();
-    }
-
-    /**
-     * Returns true if the image with the specified index can be removed.
-     * 
-     * @param imageIndex
-     *            the specified index of image.
-     * @return true if the image with the specified index can be removed, false
-     *         otherwise.
-     * @throws IOException
-     *             Signals that an I/O exception has occurred.
-     */
-    public boolean canRemoveImage(int imageIndex) throws IOException {
-        return checkOutputReturnFalse();
-    }
-
-    /**
-     * Returns true if metadata of the image with the specified index can be
-     * replaced.
-     * 
-     * @param imageIndex
-     *            the specified image index.
-     * @return true if metadata of the image with the specified index can be
-     *         replaced, false otherwise.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public boolean canReplaceImageMetadata(int imageIndex) throws IOException {
-        return checkOutputReturnFalse();
-    }
-
-    /**
-     * Returns true if pixels of the image with the specified index can be
-     * replaced by the replacePixels methods.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @return true if pixels of the image with the specified index can be
-     *         replaced by the replacePixels methods, false otherwise.
-     * @throws IOException
-     *             Signals that an I/O exception has occurred.
-     */
-    public boolean canReplacePixels(int imageIndex) throws IOException {
-        return checkOutputReturnFalse();
-    }
-
-    /**
-     * Returns true if the stream metadata presented in the output can be
-     * removed.
-     * 
-     * @return true if the stream metadata presented in the output can be
-     *         removed, false otherwise.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public boolean canReplaceStreamMetadata() throws IOException {
-        return checkOutputReturnFalse();
-    }
-
-    /**
-     * Returns true if the writing of a complete image stream which contains a
-     * single image is supported with undefined pixel values and associated
-     * metadata and thumbnails to the output.
-     * 
-     * @return true if the writing of a complete image stream which contains a
-     *         single image is supported, false otherwise.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public boolean canWriteEmpty() throws IOException {
-        return checkOutputReturnFalse();
-    }
-
-    /**
-     * Returns true if the methods which taken an IIOImageParameter can deal
-     * with a Raster source image.
-     * 
-     * @return true if the methods which taken an IIOImageParameter can deal
-     *         with a Raster source image, false otherwise.
-     */
-    public boolean canWriteRasters() {
-        return false;
-    }
-
-    /**
-     * Returns true if the writer can add an image to stream that already
-     * contains header information.
-     * 
-     * @return if the writer can add an image to stream that already contains
-     *         header information, false otherwise.
-     */
-    public boolean canWriteSequence() {
-        return false;
-    }
-
-    /**
-     * Ends the insertion of a new image.
-     * 
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void endInsertEmpty() throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Ends the replace pixels operation.
-     * 
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void endReplacePixels() throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Ends an empty write operation.
-     * 
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void endWriteEmpty() throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Ends the sequence of write operations.
-     * 
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void endWriteSequence() throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Gets an array of available locales.
-     * 
-     * @return an of array available locales.
-     */
-    public Locale[] getAvailableLocales() {
-        if (availableLocales == null) {
-            return null;
-        }
-
-        return availableLocales.clone();
-    }
-
-    /**
-     * Gets an IIOMetadata object that contains default values for encoding an
-     * image with the specified type.
-     * 
-     * @param imageType
-     *            the ImageTypeSpecifier.
-     * @param param
-     *            the ImageWriteParam.
-     * @return the IIOMetadata object.
-     */
-    public abstract IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType,
-            ImageWriteParam param);
-
-    /**
-     * Gets an IIOMetadata object that contains default values for encoding a
-     * stream of images.
-     * 
-     * @param param
-     *            the ImageWriteParam.
-     * @return the IIOMetadata object.
-     */
-    public abstract IIOMetadata getDefaultStreamMetadata(ImageWriteParam param);
-
-    /**
-     * Gets the current locale of this ImageWriter.
-     * 
-     * @return the current locale of this ImageWriter.
-     */
-    public Locale getLocale() {
-        return locale;
-    }
-
-    /**
-     * Gets the default write param. Gets a new ImageWriteParam object for this
-     * ImageWriter with the current Locale.
-     * 
-     * @return a new ImageWriteParam object for this ImageWriter.
-     */
-    public ImageWriteParam getDefaultWriteParam() {
-        return new ImageWriteParam(getLocale());
-    }
-
-    /**
-     * Gets the number of thumbnails supported by the format being written with
-     * supported image type, image write parameters, stream, and image metadata
-     * objects.
-     * 
-     * @param imageType
-     *            the ImageTypeSpecifier.
-     * @param param
-     *            the image's parameters.
-     * @param streamMetadata
-     *            the stream metadata.
-     * @param imageMetadata
-     *            the image metadata.
-     * @return the number of thumbnails supported.
-     */
-    public int getNumThumbnailsSupported(ImageTypeSpecifier imageType, ImageWriteParam param,
-            IIOMetadata streamMetadata, IIOMetadata imageMetadata) {
-        return 0;
-    }
-
-    /**
-     * Gets the preferred thumbnail sizes. Gets an array of Dimensions with the
-     * sizes for thumbnail images as they are encoded in the output file or
-     * stream.
-     * 
-     * @param imageType
-     *            the ImageTypeSpecifier.
-     * @param param
-     *            the ImageWriteParam.
-     * @param streamMetadata
-     *            the stream metadata.
-     * @param imageMetadata
-     *            the image metadata.
-     * @return the preferred thumbnail sizes.
-     */
-    public Dimension[] getPreferredThumbnailSizes(ImageTypeSpecifier imageType,
-            ImageWriteParam param, IIOMetadata streamMetadata, IIOMetadata imageMetadata) {
-        return null;
-    }
-
-    /**
-     * Prepares insertion of an empty image by requesting the insertion of a new
-     * image into an existing image stream.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param imageType
-     *            the image type.
-     * @param width
-     *            the width of the image.
-     * @param height
-     *            the height of the image.
-     * @param imageMetadata
-     *            the image metadata, or null.
-     * @param thumbnails
-     *            the array thumbnails for this image, or null.
-     * @param param
-     *            the ImageWriteParam, or null.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void prepareInsertEmpty(int imageIndex, ImageTypeSpecifier imageType, int width,
-            int height, IIOMetadata imageMetadata, List<? extends BufferedImage> thumbnails,
-            ImageWriteParam param) throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Prepares the writer to call the replacePixels method for the specified
-     * region.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @param region
-     *            the specified region.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void prepareReplacePixels(int imageIndex, Rectangle region) throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Prepares the writer for writing an empty image by beginning the process
-     * of writing a complete image stream that contains a single image with
-     * undefined pixel values, metadata and thumbnails, to the output.
-     * 
-     * @param streamMetadata
-     *            the stream metadata.
-     * @param imageType
-     *            the image type.
-     * @param width
-     *            the width of the image.
-     * @param height
-     *            the height of the image.
-     * @param imageMetadata
-     *            the image's metadata, or null.
-     * @param thumbnails
-     *            the image's thumbnails, or null.
-     * @param param
-     *            the image's parameters, or null.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void prepareWriteEmpty(IIOMetadata streamMetadata, ImageTypeSpecifier imageType,
-            int width, int height, IIOMetadata imageMetadata,
-            List<? extends BufferedImage> thumbnails, ImageWriteParam param) throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Prepares a stream to accept calls of writeToSequence method using the
-     * metadata object.
-     * 
-     * @param streamMetadata
-     *            the stream metadata.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void prepareWriteSequence(IIOMetadata streamMetadata) throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Processes the completion of a thumbnail read by calling their
-     * thumbnailComplete method of registered IIOWriteProgressListeners.
-     */
-    protected void processThumbnailComplete() {
-        if (progressListeners != null) {
-            for (IIOWriteProgressListener listener : progressListeners) {
-                listener.thumbnailComplete(this);
-            }
-        }
-    }
-
-    /**
-     * Processes the current percentage of thumbnail completion by calling their
-     * thumbnailProgress method of registered IIOWriteProgressListeners.
-     * 
-     * @param percentageDone
-     *            the percentage done.
-     */
-    protected void processThumbnailProgress(float percentageDone) {
-        if (progressListeners != null) {
-            for (IIOWriteProgressListener listener : progressListeners) {
-                listener.thumbnailProgress(this, percentageDone);
-            }
-        }
-    }
-
-    /**
-     * Processes the start of a thumbnail read by calling thumbnailStarted
-     * method of registered IIOWriteProgressListeners.
-     * 
-     * @param imageIndex
-     *            the image index.
-     * @param thumbnailIndex
-     *            the thumbnail index.
-     */
-    protected void processThumbnailStarted(int imageIndex, int thumbnailIndex) {
-        if (progressListeners != null) {
-            for (IIOWriteProgressListener listener : progressListeners) {
-                listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
-            }
-        }
-    }
-
-    /**
-     * Processes that the writing has been aborted by calling writeAborted
-     * method of registered IIOWriteProgressListeners.
-     */
-    protected void processWriteAborted() {
-        if (progressListeners != null) {
-            for (IIOWriteProgressListener listener : progressListeners) {
-                listener.writeAborted(this);
-            }
-        }
-    }
-
-    /**
-     * Removes the all IIOWriteProgressListener listeners.
-     */
-    public void removeAllIIOWriteProgressListeners() {
-        progressListeners = null;
-    }
-
-    /**
-     * Removes the all IIOWriteWarningListener listeners.
-     */
-    public void removeAllIIOWriteWarningListeners() {
-        warningListeners = null;
-        warningLocales = null;
-    }
-
-    /**
-     * Removes the specified IIOWriteProgressListener listener.
-     * 
-     * @param listener
-     *            the registered IIOWriteProgressListener to be removed.
-     */
-    public void removeIIOWriteProgressListener(IIOWriteProgressListener listener) {
-        if (progressListeners != null && listener != null) {
-            if (progressListeners.remove(listener) && progressListeners.isEmpty()) {
-                progressListeners = null;
-            }
-        }
-    }
-
-    /**
-     * Removes the specified IIOWriteWarningListener listener.
-     * 
-     * @param listener
-     *            the registered IIOWriteWarningListener listener to be removed.
-     */
-    public void removeIIOWriteWarningListener(IIOWriteWarningListener listener) {
-        if (warningListeners == null || listener == null) {
-            return;
-        }
-
-        int idx = warningListeners.indexOf(listener);
-        if (idx > -1) {
-            warningListeners.remove(idx);
-            warningLocales.remove(idx);
-
-            if (warningListeners.isEmpty()) {
-                warningListeners = null;
-                warningLocales = null;
-            }
-        }
-    }
-
-    /**
-     * Removes the image with the specified index from the stream.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void removeImage(int imageIndex) throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Replaces image metadata of the image with specified index.
-     * 
-     * @param imageIndex
-     *            the image's index.
-     * @param imageMetadata
-     *            the image metadata.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void replaceImageMetadata(int imageIndex, IIOMetadata imageMetadata) throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Replaces a part of an image presented in the output with the specified
-     * RenderedImage.
-     * 
-     * @param image
-     *            the RenderedImage.
-     * @param param
-     *            the ImageWriteParam.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void replacePixels(RenderedImage image, ImageWriteParam param) throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Replaces a part of an image presented in the output with the specified
-     * Raster.
-     * 
-     * @param raster
-     *            the Raster.
-     * @param param
-     *            the ImageWriteParam.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void replacePixels(Raster raster, ImageWriteParam param) throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Replaces the stream metadata of the output with new IIOMetadata.
-     * 
-     * @param streamMetadata
-     *            the new stream metadata.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void replaceStreamMetadata(IIOMetadata streamMetadata) throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Sets the locale of this ImageWriter.
-     * 
-     * @param locale
-     *            the new locale.
-     */
-    public void setLocale(Locale locale) {
-        if (locale == null) {
-            this.locale = null;
-            return;
-        }
-
-        Locale[] locales = getAvailableLocales();
-        boolean validLocale = false;
-        if (locales != null) {
-            for (int i = 0; i < locales.length; i++) {
-                if (locale.equals(locales[i])) {
-                    validLocale = true;
-                    break;
-                }
-            }
-        }
-
-        if (validLocale) {
-            this.locale = locale;
-        } else {
-            throw new IllegalArgumentException("Invalid locale!");
-        }
-    }
-
-    /**
-     * Resets this ImageWriter.
-     */
-    public void reset() {
-        setOutput(null);
-        setLocale(null);
-        removeAllIIOWriteWarningListeners();
-        removeAllIIOWriteProgressListeners();
-        clearAbortRequest();
-    }
-
-    /**
-     * Inserts image into existing output stream.
-     * 
-     * @param imageIndex
-     *            the image index where an image will be written.
-     * @param image
-     *            the specified image to be written.
-     * @param param
-     *            the ImageWriteParam, or null.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void writeInsert(int imageIndex, IIOImage image, ImageWriteParam param)
-            throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Writes the specified image to the sequence.
-     * 
-     * @param image
-     *            the image to be written.
-     * @param param
-     *            the ImageWriteParam, or null.
-     * @throws IOException
-     *             if an I/O exception has occurred during writing.
-     */
-    public void writeToSequence(IIOImage image, ImageWriteParam param) throws IOException {
-        unsupportedOperation();
-    }
-}
diff --git a/awt/javax/imageio/event/IIOReadProgressListener.java b/awt/javax/imageio/event/IIOReadProgressListener.java
deleted file mode 100644
index 2944896..0000000
--- a/awt/javax/imageio/event/IIOReadProgressListener.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-package javax.imageio.event;
-
-import java.util.EventListener;
-import javax.imageio.ImageReader;
-
-/**
- * The IIOReadProgressListener interface notifies callers about the progress of
- * the image and thumbnail reading methods.
- * 
- * @since Android 1.0
- */
-public interface IIOReadProgressListener extends EventListener {
-
-    /**
-     * Notifies this listener that the image reading has been completed.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     */
-    void imageComplete(ImageReader source);
-
-    /**
-     * Notifies this listener about the degree of completion of the read call.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param percentageDone
-     *            the percentage of decoding done.
-     */
-    void imageProgress(ImageReader source, float percentageDone);
-
-    /**
-     * Notifies this listener that an image read operation has been started.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param imageIndex
-     *            the index of the image in an input file or stream to be read.
-     */
-    void imageStarted(ImageReader source, int imageIndex);
-
-    /**
-     * Notifies this listener that a read operation has been aborted.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     */
-    void readAborted(ImageReader source);
-
-    /**
-     * Notifies this listener that a sequence of read operations has been
-     * completed.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     */
-    void sequenceComplete(ImageReader source);
-
-    /**
-     * Notifies this listener that a sequence of read operation has been
-     * started.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param minIndex
-     *            the index of the first image to be read.
-     */
-    void sequenceStarted(ImageReader source, int minIndex);
-
-    /**
-     * Notifies that a thumbnail read operation has been completed.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     */
-    void thumbnailComplete(ImageReader source);
-
-    /**
-     * Notifies this listener about the degree of completion of the read call.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param percentageDone
-     *            the percentage of decoding done.
-     */
-    void thumbnailProgress(ImageReader source, float percentageDone);
-
-    /**
-     * Notifies this listener that a thumbnail reading operation has been
-     * started.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param imageIndex
-     *            the index of the image in an input file or stream to be read.
-     * @param thumbnailIndex
-     *            the index of the thumbnail to be read.
-     */
-    void thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex);
-}
diff --git a/awt/javax/imageio/event/IIOReadUpdateListener.java b/awt/javax/imageio/event/IIOReadUpdateListener.java
deleted file mode 100644
index 49bdbcb..0000000
--- a/awt/javax/imageio/event/IIOReadUpdateListener.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-package javax.imageio.event;
-
-import java.awt.image.BufferedImage;
-import java.util.EventListener;
-import javax.imageio.ImageReader;
-
-/*
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-/**
- * The IIOReadUpdateListener interface provides functionality to receive
- * notification of pixel updates during image and thumbnail reading operations.
- * 
- * @since Android 1.0
- */
-public interface IIOReadUpdateListener extends EventListener {
-
-    /**
-     * Notifies this listener that the specified area of the image has been
-     * updated.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param theImage
-     *            the image to be updated.
-     * @param minX
-     *            the minimum X coordinate of the pixels in the updated area.
-     * @param minY
-     *            the minimum Y coordinate of the pixels in the updated area.
-     * @param width
-     *            the width of updated area.
-     * @param height
-     *            the height of updated area.
-     * @param periodX
-     *            the horizontal spacing period between updated pixels, if it
-     *            equals 1, there is no space between pixels.
-     * @param periodY
-     *            the vertical spacing period between updated pixels, if it
-     *            equals 1, there is no space between pixels.
-     * @param bands
-     *            the array of integer values indicating the bands being
-     *            updated.
-     */
-    void imageUpdate(ImageReader source, BufferedImage theImage, int minX, int minY, int width,
-            int height, int periodX, int periodY, int[] bands);
-
-    /**
-     * Notifies this listener that the current read operation has completed a
-     * progressive pass.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param theImage
-     *            the image to be updated.
-     */
-    void passComplete(ImageReader source, BufferedImage theImage);
-
-    /**
-     * Notifies this listener that the current read operation has begun a
-     * progressive pass.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param theImage
-     *            the image to be updated.
-     * @param pass
-     *            the number of the pass.
-     * @param minPass
-     *            the index of the first pass that will be decoded.
-     * @param maxPass
-     *            the index of the last pass that will be decoded.
-     * @param minX
-     *            the minimum X coordinate of the pixels in the updated area.
-     * @param minY
-     *            the minimum Y coordinate of the pixels in the updated area.
-     * @param periodX
-     *            the horizontal spacing period between updated pixels, if it
-     *            equals 1, there is no space between pixels.
-     * @param periodY
-     *            the vertical spacing period between updated pixels, if it
-     *            equals 1, there is no space between pixels.
-     * @param bands
-     *            the array of integer values indicating the bands being
-     *            updated.
-     */
-    void passStarted(ImageReader source, BufferedImage theImage, int pass, int minPass,
-            int maxPass, int minX, int minY, int periodX, int periodY, int[] bands);
-
-    /**
-     * Notifies this listener that the current thumbnail read operation has
-     * completed a progressive pass.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param theImage
-     *            the thumbnail to be updated.
-     */
-    void thumbnailPassComplete(ImageReader source, BufferedImage theImage);
-
-    /**
-     * Notifies this listener that the current thumbnail read operation has
-     * begun a progressive pass.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param theThumbnail
-     *            the thumbnail to be updated.
-     * @param pass
-     *            the number of the pass.
-     * @param minPass
-     *            the index of the first pass that will be decoded.
-     * @param maxPass
-     *            the index of the last pass that will be decoded.
-     * @param minX
-     *            the minimum X coordinate of the pixels in the updated area.
-     * @param minY
-     *            the minimum Y coordinate of the pixels in the updated area.
-     * @param periodX
-     *            the horizontal spacing period between updated pixels, if it
-     *            equals 1, there is no space between pixels.
-     * @param periodY
-     *            the vertical spacing period between updated pixels, if it
-     *            equals 1, there is no space between pixels.
-     * @param bands
-     *            the array of integer values indicating the bands being
-     *            updated.
-     */
-    void thumbnailPassStarted(ImageReader source, BufferedImage theThumbnail, int pass,
-            int minPass, int maxPass, int minX, int minY, int periodX, int periodY, int[] bands);
-
-    /**
-     * Notifies this listener that a specified area of a thumbnail image has
-     * been updated.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param theThumbnail
-     *            the thumbnail to be updated.
-     * @param minX
-     *            the minimum X coordinate of the pixels in the updated area.
-     * @param minY
-     *            the minimum Y coordinate of the pixels in the updated area.
-     * @param width
-     *            the width of updated area.
-     * @param height
-     *            the height of updated area.
-     * @param periodX
-     *            the horizontal spacing period between updated pixels, if it
-     *            equals 1, there is no space between pixels.
-     * @param periodY
-     *            the vertical spacing period between updated pixels, if it
-     *            equals 1, there is no space between pixels.
-     * @param bands
-     *            the array of integer values indicating the bands being
-     *            updated.
-     */
-    void thumbnailUpdate(ImageReader source, BufferedImage theThumbnail, int minX, int minY,
-            int width, int height, int periodX, int periodY, int[] bands);
-}
diff --git a/awt/javax/imageio/event/IIOReadWarningListener.java b/awt/javax/imageio/event/IIOReadWarningListener.java
deleted file mode 100644
index 318a5df..0000000
--- a/awt/javax/imageio/event/IIOReadWarningListener.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-package javax.imageio.event;
-
-import java.util.EventListener;
-import javax.imageio.ImageReader;
-
-/* 
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-/**
- * The IIOReadWarningListener provides methods to receive notification of
- * warning messages generated by image and thumbnail reading methods.
- * 
- * @since Android 1.0
- */
-public interface IIOReadWarningListener extends EventListener {
-
-    /**
-     * Notifies this listener about a warning (non-fatal error) during decoding.
-     * 
-     * @param source
-     *            the ImageReader object which calls this method.
-     * @param warning
-     *            the string describing the warning.
-     */
-    public void warningOccurred(ImageReader source, String warning);
-}
diff --git a/awt/javax/imageio/event/IIOWriteProgressListener.java b/awt/javax/imageio/event/IIOWriteProgressListener.java
deleted file mode 100644
index 4a2c595..0000000
--- a/awt/javax/imageio/event/IIOWriteProgressListener.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.event;
-
-import javax.imageio.ImageWriter;
-import java.util.EventListener;
-
-/**
- * The IIOWriteProgressListener interface provides methods to receive
- * notification about the progress of the image and thumbnail writing methods.
- * 
- * @since Android 1.0
- */
-public interface IIOWriteProgressListener extends EventListener {
-
-    /**
-     * Notifies this listener that an image write operation has been started.
-     * 
-     * @param source
-     *            the ImageWriter object which calls this method.
-     * @param imageIndex
-     *            the index of the image being written.
-     */
-    void imageStarted(ImageWriter source, int imageIndex);
-
-    /**
-     * Notifies this listener about the degree of completion of the write call.
-     * 
-     * @param source
-     *            the ImageWriter object which calls this method.
-     * @param percentageDone
-     *            the percentage of encoding done.
-     */
-    void imageProgress(ImageWriter source, float percentageDone);
-
-    /**
-     * Notifies this listener that the image writing has been completed.
-     * 
-     * @param source
-     *            the ImageWriter object which calls this method.
-     */
-    void imageComplete(ImageWriter source);
-
-    /**
-     * Notifies this listener that a thumbnail write operation has been started.
-     * 
-     * @param source
-     *            the ImageWriter object which calls this method.
-     * @param imageIndex
-     *            the index of the image being written.
-     * @param thumbnailIndex
-     *            the index of the thumbnail being written.
-     */
-    void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex);
-
-    /**
-     * Notifies this listener about the degree of completion of the write call.
-     * 
-     * @param source
-     *            the ImageWriter object which calls this method.
-     * @param percentageDone
-     *            the percentage of encoding done.
-     */
-    void thumbnailProgress(ImageWriter source, float percentageDone);
-
-    /**
-     * Notifies this listener that a thumbnail write operation has been
-     * completed.
-     * 
-     * @param source
-     *            the ImageWriter object which calls this method.
-     */
-    void thumbnailComplete(ImageWriter source);
-
-    /**
-     * Notifies this listener that writing operation has been aborted.
-     * 
-     * @param source
-     *            the ImageWriter object which calls this method.
-     */
-    void writeAborted(ImageWriter source);
-}
diff --git a/awt/javax/imageio/event/IIOWriteWarningListener.java b/awt/javax/imageio/event/IIOWriteWarningListener.java
deleted file mode 100644
index 8ee41cd..0000000
--- a/awt/javax/imageio/event/IIOWriteWarningListener.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.event;
-
-import javax.imageio.ImageWriter;
-import java.util.EventListener;
-
-/**
- * The IIOWriteWarningListener provides methods to receive notification of
- * warnings generated by image and thumbnail writing methods.
- * 
- * @since Android 1.0
- */
-public interface IIOWriteWarningListener extends EventListener {
-
-    /**
-     * Notifies this listener about a warning (non-fatal error) during encoding.
-     * 
-     * @param source
-     *            the ImageWriter object which calls this method.
-     * @param imageIndex
-     *            the index of the image generating the warning.
-     * @param warning
-     *            the string describing the warning.
-     */
-    void warningOccurred(ImageWriter source, int imageIndex, String warning);
-}
diff --git a/awt/javax/imageio/event/package.html b/awt/javax/imageio/event/package.html
deleted file mode 100644
index c2fe39f..0000000
--- a/awt/javax/imageio/event/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package provides interfaces to handle events which can be fired during the reading or writing of images.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/metadata/IIOInvalidTreeException.java b/awt/javax/imageio/metadata/IIOInvalidTreeException.java
deleted file mode 100644
index ba90657..0000000
--- a/awt/javax/imageio/metadata/IIOInvalidTreeException.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.metadata;
-
-import org.w3c.dom.Node;
-import javax.imageio.IIOException;
-
-/**
- * The IIOInvalidTreeException provides notification about fails of
- * IIOMetadataNodes tree parsing by IIOMetadata object.
- * 
- * @since Android 1.0
- */
-public class IIOInvalidTreeException extends IIOException {
-
-    /**
-     * The offending node.
-     */
-    protected Node offendingNode = null;
-
-    /**
-     * Instantiates an IIOInvalidTreeException with the specified detailed
-     * message and specified offending Node.
-     * 
-     * @param message
-     *            the detailed message.
-     * @param offendingNode
-     *            the offending node.
-     */
-    public IIOInvalidTreeException(String message, Node offendingNode) {
-        super(message);
-        this.offendingNode = offendingNode;
-    }
-
-    /**
-     * Instantiates a new IIOInvalidTreeException with the specified detailed
-     * message and specified offending Node.
-     * 
-     * @param message
-     *            the detailed message.
-     * @param cause
-     *            the cause of this exception.
-     * @param offendingNode
-     *            the offending node.
-     */
-    public IIOInvalidTreeException(String message, Throwable cause, Node offendingNode) {
-        super(message, cause);
-        this.offendingNode = offendingNode;
-    }
-
-    /**
-     * Gets the offending node.
-     * 
-     * @return the offending node.
-     */
-    public Node getOffendingNode() {
-        return offendingNode;
-    }
-}
diff --git a/awt/javax/imageio/metadata/IIOMetadata.java b/awt/javax/imageio/metadata/IIOMetadata.java
deleted file mode 100644
index 96cebf9..0000000
--- a/awt/javax/imageio/metadata/IIOMetadata.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.metadata;
-
-import java.util.ArrayList;
-
-import org.apache.harmony.x.imageio.metadata.IIOMetadataUtils;
-import org.w3c.dom.Node;
-
-/**
- * The class IIOMetadata represents the metadata (bundled with an image) as a
- * Dom-type tree.
- * 
- * @since Android 1.0
- */
-public abstract class IIOMetadata {
-
-    /**
-     * Whether the standard metadata format is supported.
-     */
-    protected boolean standardFormatSupported;
-
-    /**
-     * The native metadata format name.
-     */
-    protected String nativeMetadataFormatName;
-
-    /**
-     * The native metadata format class name.
-     */
-    protected String nativeMetadataFormatClassName;
-
-    /**
-     * The extra metadata format names.
-     */
-    protected String[] extraMetadataFormatNames;
-
-    /**
-     * The extra metadata format class names.
-     */
-    protected String[] extraMetadataFormatClassNames;
-
-    /**
-     * The default controller.
-     */
-    protected IIOMetadataController defaultController;
-
-    /**
-     * The controller.
-     */
-    protected IIOMetadataController controller;
-
-    /**
-     * Instantiates a new IIOMetadata with no data set.
-     */
-    protected IIOMetadata() {
-    }
-
-    /**
-     * Instantiates a new IIOMetadata with the specified data parameters.
-     * 
-     * @param standardMetadataFormatSupported
-     *            whether the standard metadata format is supported.
-     * @param nativeMetadataFormatName
-     *            the native metadata format name.
-     * @param nativeMetadataFormatClassName
-     *            the native metadata format class name.
-     * @param extraMetadataFormatNames
-     *            the extra metadata format names.
-     * @param extraMetadataFormatClassNames
-     *            the extra metadata format class names.
-     */
-    protected IIOMetadata(boolean standardMetadataFormatSupported, String nativeMetadataFormatName,
-            String nativeMetadataFormatClassName, String[] extraMetadataFormatNames,
-            String[] extraMetadataFormatClassNames) {
-        standardFormatSupported = standardMetadataFormatSupported;
-        this.nativeMetadataFormatName = nativeMetadataFormatName;
-        this.nativeMetadataFormatClassName = nativeMetadataFormatClassName;
-        if (extraMetadataFormatNames == null) {
-            if (extraMetadataFormatClassNames != null) {
-                throw new IllegalArgumentException(
-                        "extraMetadataFormatNames == null && extraMetadataFormatClassNames != null!");
-            }
-        } else {
-            if (extraMetadataFormatClassNames == null) {
-                throw new IllegalArgumentException(
-                        "extraMetadataFormatNames != null && extraMetadataFormatClassNames == null!");
-            }
-            if (extraMetadataFormatNames.length == 0) {
-                throw new IllegalArgumentException("extraMetadataFormatNames.length == 0!");
-            }
-            if (extraMetadataFormatClassNames.length != extraMetadataFormatNames.length) {
-                throw new IllegalArgumentException(
-                        "extraMetadataFormatClassNames.length != extraMetadataFormatNames.length!");
-            }
-            this.extraMetadataFormatNames = extraMetadataFormatNames.clone();
-            this.extraMetadataFormatClassNames = extraMetadataFormatClassNames.clone();
-        }
-    }
-
-    /**
-     * Gets the metadata as tree-type document.
-     * 
-     * @param formatName
-     *            the format name.
-     * @return the node in tree format.
-     */
-    public abstract Node getAsTree(String formatName);
-
-    /**
-     * Checks if the metadata is read only.
-     * 
-     * @return true, if the metadata is read only.
-     */
-    public abstract boolean isReadOnly();
-
-    /**
-     * Merges the specified tree with this metadata tree.
-     * 
-     * @param formatName
-     *            the format of the specified tree.
-     * @param root
-     *            the root node of the metadata tree.
-     * @throws IIOInvalidTreeException
-     *             if the specified tree is incompatible with the this metadata
-     *             tree.
-     */
-    public abstract void mergeTree(String formatName, Node root) throws IIOInvalidTreeException;
-
-    /**
-     * Resets the controller.
-     */
-    public abstract void reset();
-
-    /**
-     * Gets the controller associated with this metadata document.
-     * 
-     * @return the controller.
-     */
-    public IIOMetadataController getController() {
-        return controller;
-    }
-
-    /**
-     * Checks whether this metadata has a controller.
-     * 
-     * @return true, if this metadata has a controller.
-     */
-    public boolean hasController() {
-        return getController() != null;
-    }
-
-    /**
-     * Activate the controller.
-     * 
-     * @return true, if successful.
-     */
-    public boolean activateController() {
-        if (!hasController()) {
-            throw new IllegalStateException("hasController() == false!");
-        }
-        return getController().activate(this);
-    }
-
-    /**
-     * Gets the default controller.
-     * 
-     * @return the default controller.
-     */
-    public IIOMetadataController getDefaultController() {
-        return defaultController;
-    }
-
-    /**
-     * Gets the extra metadata format names.
-     * 
-     * @return the extra metadata format names.
-     */
-    public String[] getExtraMetadataFormatNames() {
-        return extraMetadataFormatNames == null ? null : extraMetadataFormatNames.clone();
-    }
-
-    /**
-     * Gets the metadata format.
-     * 
-     * @param formatName
-     *            the format name.
-     * @return the metadata format.
-     */
-    public IIOMetadataFormat getMetadataFormat(String formatName) {
-        return IIOMetadataUtils.instantiateMetadataFormat(formatName, standardFormatSupported,
-                nativeMetadataFormatName, nativeMetadataFormatClassName, extraMetadataFormatNames,
-                extraMetadataFormatClassNames);
-    }
-
-    /**
-     * Gets the native metadata format name.
-     * 
-     * @return the native metadata format name.
-     */
-    public String getNativeMetadataFormatName() {
-        return nativeMetadataFormatName;
-    }
-
-    /**
-     * Checks if the standard metadata format is supported.
-     * 
-     * @return true, if the standard metadata format is supported.
-     */
-    public boolean isStandardMetadataFormatSupported() {
-        return standardFormatSupported;
-    }
-
-    /**
-     * Gets the metadata format names.
-     * 
-     * @return the metadata format names.
-     */
-    public String[] getMetadataFormatNames() {
-        ArrayList<String> res = new ArrayList<String>();
-
-        String nativeMetadataFormatName = getNativeMetadataFormatName();
-        boolean standardFormatSupported = isStandardMetadataFormatSupported();
-        String extraMetadataFormatNames[] = getExtraMetadataFormatNames();
-
-        if (standardFormatSupported) {
-            res.add(IIOMetadataFormatImpl.standardMetadataFormatName);
-        }
-        if (nativeMetadataFormatName != null) {
-            res.add(nativeMetadataFormatName);
-        }
-        if (extraMetadataFormatNames != null) {
-            for (String extraMetadataFormatName : extraMetadataFormatNames) {
-                res.add(extraMetadataFormatName);
-            }
-        }
-
-        return res.size() > 0 ? res.toArray(new String[0]) : null;
-    }
-
-    /**
-     * Gets the standard chroma node.
-     * 
-     * @return the standard chroma node.
-     */
-    protected IIOMetadataNode getStandardChromaNode() {
-        return null;
-    }
-
-    /**
-     * Gets the standard compression node.
-     * 
-     * @return the standard compression node.
-     */
-    protected IIOMetadataNode getStandardCompressionNode() {
-        return null;
-    }
-
-    /**
-     * Gets the standard data node.
-     * 
-     * @return the standard data node.
-     */
-    protected IIOMetadataNode getStandardDataNode() {
-        return null;
-    }
-
-    /**
-     * Gets the standard dimension node.
-     * 
-     * @return the standard dimension node.
-     */
-    protected IIOMetadataNode getStandardDimensionNode() {
-        return null;
-    }
-
-    /**
-     * Gets the standard document node.
-     * 
-     * @return the standard document node.
-     */
-    protected IIOMetadataNode getStandardDocumentNode() {
-        return null;
-    }
-
-    /**
-     * Gets the standard text node.
-     * 
-     * @return the standard text node.
-     */
-    protected IIOMetadataNode getStandardTextNode() {
-        return null;
-    }
-
-    /**
-     * Gets the standard tile node.
-     * 
-     * @return the standard tile node.
-     */
-    protected IIOMetadataNode getStandardTileNode() {
-        return null;
-    }
-
-    /**
-     * Gets the standard transparency node.
-     * 
-     * @return the standard transparency node.
-     */
-    protected IIOMetadataNode getStandardTransparencyNode() {
-        return null;
-    }
-
-    /**
-     * Gets the metadata as a tree in standard format.
-     * 
-     * @return the metadata as a tree in standard format.
-     */
-    protected final IIOMetadataNode getStandardTree() {
-        // Create root node
-        IIOMetadataNode root = new IIOMetadataNode(IIOMetadataFormatImpl.standardMetadataFormatName);
-
-        Node node;
-        if ((node = getStandardChromaNode()) != null) {
-            root.appendChild(node);
-        }
-        if ((node = getStandardCompressionNode()) != null) {
-            root.appendChild(node);
-        }
-        if ((node = getStandardDataNode()) != null) {
-            root.appendChild(node);
-        }
-        if ((node = getStandardDimensionNode()) != null) {
-            root.appendChild(node);
-        }
-        if ((node = getStandardDocumentNode()) != null) {
-            root.appendChild(node);
-        }
-        if ((node = getStandardTextNode()) != null) {
-            root.appendChild(node);
-        }
-        if ((node = getStandardTileNode()) != null) {
-            root.appendChild(node);
-        }
-        if ((node = getStandardTransparencyNode()) != null) {
-            root.appendChild(node);
-        }
-
-        return root;
-    }
-
-    /**
-     * Sets the controller.
-     * 
-     * @param controller
-     *            the new controller.
-     */
-    public void setController(IIOMetadataController controller) {
-        this.controller = controller;
-    }
-
-    /**
-     * Sets the from tree.
-     * 
-     * @param formatName
-     *            the name of the metatdata format of the from tree.
-     * @param root
-     *            the root node of the from tree.
-     * @throws IIOInvalidTreeException
-     *             if the tree or its format is not compatible with this
-     *             metadata.
-     */
-    public void setFromTree(String formatName, Node root) throws IIOInvalidTreeException {
-        reset();
-        mergeTree(formatName, root);
-    }
-}
diff --git a/awt/javax/imageio/metadata/IIOMetadataController.java b/awt/javax/imageio/metadata/IIOMetadataController.java
deleted file mode 100644
index 1405948..0000000
--- a/awt/javax/imageio/metadata/IIOMetadataController.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-package javax.imageio.metadata;
-
-/* 
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-/**
- * The IIOMetadataController interface provides a method for implementing
- * objects to activate the controller without defining how the controller
- * obtains values.
- * 
- * @since Android 1.0
- */
-public interface IIOMetadataController {
-
-    /**
-     * Activates a controller.
-     * 
-     * @param metadata
-     *            the metadata to be modified.
-     * @return true, if the IIOMetadata has been modified, false otherwise.
-     */
-    public boolean activate(IIOMetadata metadata);
-}
diff --git a/awt/javax/imageio/metadata/IIOMetadataFormat.java b/awt/javax/imageio/metadata/IIOMetadataFormat.java
deleted file mode 100644
index 0e7e697..0000000
--- a/awt/javax/imageio/metadata/IIOMetadataFormat.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.metadata;
-
-import javax.imageio.ImageTypeSpecifier;
-import java.util.Locale;
-
-/**
- * The Interface IIOMetadataFormat is implemented by classes that describe the
- * rules and allowed elements for a metadata document tree.
- * 
- * @since Android 1.0
- */
-public interface IIOMetadataFormat {
-
-    /**
-     * The CHILD_POLICY_EMPTY.
-     */
-    int CHILD_POLICY_EMPTY = 0;
-
-    /**
-     * The CHILD_POLICY_ALL.
-     */
-    int CHILD_POLICY_ALL = 1;
-
-    /**
-     * The CHILD_POLICY_SOME.
-     */
-    int CHILD_POLICY_SOME = 2;
-
-    /**
-     * The CHILD_POLICY_CHOICE.
-     */
-    int CHILD_POLICY_CHOICE = 3;
-
-    /**
-     * The CHILD_POLICY_SEQUENCE.
-     */
-    int CHILD_POLICY_SEQUENCE = 4;
-
-    /**
-     * The CHILD_POLICY_REPEAT.
-     */
-    int CHILD_POLICY_REPEAT = 5;
-
-    /**
-     * The maximum value for the child policy.
-     */
-    int CHILD_POLICY_MAX = CHILD_POLICY_REPEAT;
-
-    /**
-     * The DATATYPE_STRING.
-     */
-    int DATATYPE_STRING = 0;
-
-    /**
-     * The DATATYPE_BOOLEAN.
-     */
-    int DATATYPE_BOOLEAN = 1;
-
-    /**
-     * The DATATYPE_INTEGER.
-     */
-    int DATATYPE_INTEGER = 2;
-
-    /**
-     * The DATATYPE_FLOAT.
-     */
-    int DATATYPE_FLOAT = 3;
-
-    /**
-     * The DATATYPE_DOUBLE.
-     */
-    int DATATYPE_DOUBLE = 4;
-
-    /**
-     * The VALUE_NONE.
-     */
-    int VALUE_NONE = 0;
-
-    /**
-     * The VALUE_ARBITRARY.
-     */
-    int VALUE_ARBITRARY = 1;
-
-    /**
-     * The VALUE_RANGE.
-     */
-    int VALUE_RANGE = 2;
-
-    /**
-     * The VALUE_RANGE_MIN_INCLUSIVE_MASK.
-     */
-    int VALUE_RANGE_MIN_INCLUSIVE_MASK = 4;
-
-    /**
-     * The VALUE_RANGE_MAX_INCLUSIVE_MASK.
-     */
-    int VALUE_RANGE_MAX_INCLUSIVE_MASK = 8;
-
-    /**
-     * The VALUE_ENUMERATION.
-     */
-    int VALUE_ENUMERATION = 16;
-
-    /**
-     * The VALUE_LIST.
-     */
-    int VALUE_LIST = 32;
-
-    /**
-     * The VALUE_RANGE_MIN_INCLUSIVE.
-     */
-    int VALUE_RANGE_MIN_INCLUSIVE = VALUE_RANGE | VALUE_RANGE_MIN_INCLUSIVE_MASK;
-
-    /**
-     * The VALUE_RANGE_MAX_INCLUSIVE.
-     */
-    int VALUE_RANGE_MAX_INCLUSIVE = VALUE_RANGE | VALUE_RANGE_MAX_INCLUSIVE_MASK;
-
-    /**
-     * The VALUE_RANGE_MIN_MAX_INCLUSIVE.
-     */
-    int VALUE_RANGE_MIN_MAX_INCLUSIVE = VALUE_RANGE | VALUE_RANGE_MIN_INCLUSIVE_MASK
-            | VALUE_RANGE_MAX_INCLUSIVE_MASK;
-
-    /**
-     * Tells whether the specified element is allowed for the specified image
-     * type.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param imageType
-     *            the image type.
-     * @return true, if the specified element is allowed for the specified image
-     *         type.
-     */
-    boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType);
-
-    /**
-     * Gets data type of the specified attribute of the specified element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attrName
-     *            the attribute name.
-     * @return the attribute's data type.
-     */
-    int getAttributeDataType(String elementName, String attrName);
-
-    /**
-     * Gets the default value of the specified attribute of the specified
-     * element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attrName
-     *            the attribute name.
-     * @return the attribute's default value.
-     */
-    String getAttributeDefaultValue(String elementName, String attrName);
-
-    /**
-     * Gets the user-friendly description of the attribute.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attrName
-     *            the attribute name.
-     * @param locale
-     *            the locale giving the desired language for the description.
-     * @return the attribute description.
-     */
-    String getAttributeDescription(String elementName, String attrName, Locale locale);
-
-    /**
-     * Gets the attribute enumerations.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attrName
-     *            the attribute name.
-     * @return the attribute enumerations.
-     */
-    String[] getAttributeEnumerations(String elementName, String attrName);
-
-    /**
-     * Gets the maximum length of the attribute list.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attrName
-     *            the attribute name.
-     * @return the maximum length of the attribute list.
-     */
-    int getAttributeListMaxLength(String elementName, String attrName);
-
-    /**
-     * Gets the minimum length of the attribute list.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attrName
-     *            the attribute name.
-     * @return the minimum length of the attribute list.
-     */
-    int getAttributeListMinLength(String elementName, String attrName);
-
-    /**
-     * Gets the maximum value allowed for the attribute.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attrName
-     *            the attribute name.
-     * @return the maximum value allowed for the attribute.
-     */
-    String getAttributeMaxValue(String elementName, String attrName);
-
-    /**
-     * Gets the minimum value allowed for the attribute.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attrName
-     *            the attribute name.
-     * @return the minimum value allowed for the attribute.
-     */
-    String getAttributeMinValue(String elementName, String attrName);
-
-    /**
-     * Gets the attribute names allowed for the specified element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the attribute names.
-     */
-    String[] getAttributeNames(String elementName);
-
-    /**
-     * Gets the attribute value type.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attrName
-     *            the attribute name.
-     * @return the attribute value type.
-     */
-    int getAttributeValueType(String elementName, String attrName);
-
-    /**
-     * Checks whether the specified attribute is required for the specified
-     * element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attrName
-     *            the attribute name.
-     * @return true, if the specified attribute is required for the specified
-     *         element.
-     */
-    boolean isAttributeRequired(String elementName, String attrName);
-
-    /**
-     * Gets the names of the possible child elements for the given element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the child names.
-     */
-    String[] getChildNames(String elementName);
-
-    /**
-     * Gets the constant describing the element's child policy.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the child policy.
-     */
-    int getChildPolicy(String elementName);
-
-    /**
-     * Gets the user-friendly description of the element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param locale
-     *            the locale giving the desired language for the description.
-     * @return the element description.
-     */
-    String getElementDescription(String elementName, Locale locale);
-
-    /**
-     * Gets the maximum number of children allowed for the element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the maximum number of children allowed for the element.
-     */
-    int getElementMaxChildren(String elementName);
-
-    /**
-     * Gets the minimum number of children allowed for the element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the minimum number of children allowed for the element.
-     */
-    int getElementMinChildren(String elementName);
-
-    /**
-     * Gets the maximum object array length allowed for the element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the maximum object array length allowed for the element.
-     */
-    int getObjectArrayMaxLength(String elementName);
-
-    /**
-     * Gets the minimum object array length allowed for the element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the minimum object array length allowed for the element.
-     */
-    int getObjectArrayMinLength(String elementName);
-
-    /**
-     * Gets the object class corresponding to the specified element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the object class corresponding to the specified element.
-     */
-    Class<?> getObjectClass(String elementName);
-
-    /**
-     * Gets the object default value for the element.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the object default value for the element.
-     */
-    Object getObjectDefaultValue(String elementName);
-
-    /**
-     * Gets the object enumerations.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the object enumerations.
-     */
-    Object[] getObjectEnumerations(String elementName);
-
-    /**
-     * Gets the maximum value allowed for the element's object.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the maximum value allowed for the element's object.
-     */
-    Comparable<?> getObjectMaxValue(String elementName);
-
-    /**
-     * Gets the minimum value allowed for the element's object.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the minimum value allowed for the element's object.
-     */
-    Comparable<?> getObjectMinValue(String elementName);
-
-    /**
-     * Gets the constant that indicates the type of the element's value.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the constant that indicates the type of the element's value.
-     */
-    int getObjectValueType(String elementName);
-
-    /**
-     * Gets the name of the root element.
-     * 
-     * @return the name of the root element.
-     */
-    String getRootName();
-}
diff --git a/awt/javax/imageio/metadata/IIOMetadataFormatImpl.java b/awt/javax/imageio/metadata/IIOMetadataFormatImpl.java
deleted file mode 100644
index 1a6e568..0000000
--- a/awt/javax/imageio/metadata/IIOMetadataFormatImpl.java
+++ /dev/null
@@ -1,1056 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.metadata;
-
-import javax.imageio.ImageTypeSpecifier;
-import java.util.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * The IIOMetadataFormatImpl class provides an implementation of the
- * IIOMetadataFormat interface.
- * 
- * @since Android 1.0
- */
-public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat {
-
-    /**
-     * The Constant standardMetadataFormatName.
-     */
-    @SuppressWarnings( {
-        "ConstantDeclaredInAbstractClass"
-    })
-    public static final String standardMetadataFormatName = "javax_imageio_1.0";
-
-    /**
-     * The standard format.
-     */
-    @SuppressWarnings( {
-        "StaticNonFinalField"
-    })
-    private static IIOMetadataFormatImpl standardFormat;
-
-    /**
-     * The root name.
-     */
-    private String rootName;
-
-    /**
-     * The element hash.
-     */
-    private HashMap<String, Element> elementHash = new HashMap<String, Element>();
-
-    /**
-     * The resource base name.
-     */
-    private String resourceBaseName = getClass().getName() + "Resources";
-
-    /**
-     * Instantiates an IIOMetadataFormatImpl with the specified root name and
-     * child policy (not CHILD_POLICY_REPEAT).
-     * 
-     * @param rootName
-     *            the name of root element.
-     * @param childPolicy
-     *            the child policy defined by one of the CHILD_POLICY_*
-     *            constants (except CHILD_POLICY_REPEAT).
-     */
-    public IIOMetadataFormatImpl(String rootName, int childPolicy) {
-        if (rootName == null) {
-            throw new IllegalArgumentException("rootName is null");
-        }
-        if (childPolicy < CHILD_POLICY_EMPTY || childPolicy > CHILD_POLICY_MAX
-                || childPolicy == CHILD_POLICY_REPEAT) {
-            throw new IllegalArgumentException("childPolicy is not one of the predefined constants");
-        }
-
-        this.rootName = rootName;
-        Element root = new Element();
-        root.name = rootName;
-        root.childPolicy = childPolicy;
-        elementHash.put(rootName, root);
-    }
-
-    /**
-     * Instantiates an IIOMetadataFormatImpl with the specified root name and
-     * CHILD_POLICY_REPEAT child policy.
-     * 
-     * @param rootName
-     *            the name of root element.
-     * @param minChildren
-     *            the minimum number of children.
-     * @param maxChildren
-     *            the maximum number of children
-     */
-    public IIOMetadataFormatImpl(String rootName, int minChildren, int maxChildren) {
-        if (rootName == null) {
-            throw new IllegalArgumentException("rootName is null");
-        }
-        if (minChildren < 0) {
-            throw new IllegalArgumentException("minChildren < 0!");
-        }
-        if (minChildren > maxChildren) {
-            throw new IllegalArgumentException("minChildren > maxChildren!");
-        }
-
-        this.rootName = rootName;
-        Element root = new Element();
-        root.name = rootName;
-        root.minChildren = minChildren;
-        root.maxChildren = maxChildren;
-        root.childPolicy = CHILD_POLICY_REPEAT;
-        elementHash.put(rootName, root);
-    }
-
-    @SuppressWarnings( {
-        "AbstractMethodOverridesAbstractMethod"
-    })
-    public abstract boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType);
-
-    /**
-     * Adds a new attribute to an existing element.
-     * 
-     * @param elementName
-     *            the name of the element to which the new attribute will be
-     *            added.
-     * @param attrName
-     *            the attribute name.
-     * @param dataType
-     *            the data type of the new attribute.
-     * @param required
-     *            the flag which indicates whether this attribute must be
-     *            present.
-     * @param listMinLength
-     *            the minimum legal number of list items.
-     * @param listMaxLength
-     *            the the maximum legal number of list items.
-     */
-    protected void addAttribute(String elementName, String attrName, int dataType,
-            boolean required, int listMinLength, int listMaxLength) {
-        if (attrName == null) {
-            throw new IllegalArgumentException("attrName == null!");
-        }
-        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
-            throw new IllegalArgumentException("Invalid value for dataType!");
-        }
-        if (listMinLength < 0 || listMinLength > listMaxLength) {
-            throw new IllegalArgumentException("Invalid list bounds!");
-        }
-
-        Element element = findElement(elementName);
-        Attlist attr = new Attlist();
-        attr.name = attrName;
-        attr.dataType = dataType;
-        attr.required = required;
-        attr.listMinLength = listMinLength;
-        attr.listMaxLength = listMaxLength;
-        attr.valueType = VALUE_LIST;
-
-        element.attributes.put(attrName, attr);
-    }
-
-    /**
-     * Adds a new attribute to an existing element.
-     * 
-     * @param elementName
-     *            the name of the element to which the new attribute will be
-     *            added.
-     * @param attrName
-     *            the attribute name.
-     * @param dataType
-     *            the data type of the new attribute.
-     * @param required
-     *            the flag which indicates whether this attribute must be
-     *            present.
-     * @param defaultValue
-     *            the default value of the attribute.
-     */
-    protected void addAttribute(String elementName, String attrName, int dataType,
-            boolean required, String defaultValue) {
-        if (attrName == null) {
-            throw new IllegalArgumentException("attrName == null!");
-        }
-        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
-            throw new IllegalArgumentException("Invalid value for dataType!");
-        }
-
-        Element element = findElement(elementName);
-        Attlist attr = new Attlist();
-        attr.name = attrName;
-        attr.dataType = dataType;
-        attr.required = required;
-        attr.defaultValue = defaultValue;
-        attr.valueType = VALUE_ARBITRARY;
-
-        element.attributes.put(attrName, attr);
-    }
-
-    /**
-     * Adds a new attribute to an existing element.
-     * 
-     * @param elementName
-     *            the name of the element to which the new attribute will be
-     *            added.
-     * @param attrName
-     *            the attribute name.
-     * @param dataType
-     *            the data type of the new attribute.
-     * @param required
-     *            the flag which indicates whether this attribute must be
-     *            present.
-     * @param defaultValue
-     *            the default value of the attribute.
-     * @param enumeratedValues
-     *            the legal values for the attribute as a list of strings.
-     */
-    protected void addAttribute(String elementName, String attrName, int dataType,
-            boolean required, String defaultValue, List<String> enumeratedValues) {
-        if (attrName == null) {
-            throw new IllegalArgumentException("attrName == null!");
-        }
-        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
-            throw new IllegalArgumentException("Invalid value for dataType!");
-        }
-        if (enumeratedValues == null || enumeratedValues.isEmpty()) {
-            throw new IllegalArgumentException("enumeratedValues is empty or null");
-        }
-
-        try {
-            for (String enumeratedValue : enumeratedValues) {
-                if (enumeratedValue == null) {
-                    throw new IllegalArgumentException("enumeratedValues contains a null!");
-                }
-            }
-        } catch (ClassCastException e) {
-            throw new IllegalArgumentException("enumeratedValues contains a non-String value!");
-        }
-
-        Element element = findElement(elementName);
-        Attlist attr = new Attlist();
-        attr.name = attrName;
-        attr.dataType = dataType;
-        attr.required = required;
-        attr.defaultValue = defaultValue;
-        attr.enumeratedValues = enumeratedValues;
-        attr.valueType = VALUE_ENUMERATION;
-
-        element.attributes.put(attrName, attr);
-    }
-
-    /**
-     * Adds a new attribute to an existing element.
-     * 
-     * @param elementName
-     *            the name of the element to which the new attribute will be
-     *            added.
-     * @param attrName
-     *            the attribute name.
-     * @param dataType
-     *            the data type of the new attribute.
-     * @param required
-     *            the flag which indicates whether this attribute must be
-     *            present.
-     * @param defaultValue
-     *            the default value of attribute.
-     * @param minValue
-     *            the minimum legal value of an attribute.
-     * @param maxValue
-     *            the maximum legal value of an attribute.
-     * @param minInclusive
-     *            the flag which indicates whether the minValue is inclusive.
-     * @param maxInclusive
-     *            the flag which indicates whether the maxValue is inclusive.
-     */
-    protected void addAttribute(String elementName, String attrName, int dataType,
-            boolean required, String defaultValue, String minValue, String maxValue,
-            boolean minInclusive, boolean maxInclusive) {
-        if (attrName == null) {
-            throw new IllegalArgumentException("attrName == null!");
-        }
-        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
-            throw new IllegalArgumentException("Invalid value for dataType!");
-        }
-
-        Element element = findElement(elementName);
-        Attlist attr = new Attlist();
-        attr.name = attrName;
-        attr.dataType = dataType;
-        attr.required = required;
-        attr.defaultValue = defaultValue;
-        attr.minValue = minValue;
-        attr.maxValue = maxValue;
-        attr.minInclusive = minInclusive;
-        attr.maxInclusive = maxInclusive;
-
-        attr.valueType = VALUE_RANGE;
-        attr.valueType |= minInclusive ? VALUE_RANGE_MIN_INCLUSIVE_MASK : 0;
-        attr.valueType |= maxInclusive ? VALUE_RANGE_MAX_INCLUSIVE_MASK : 0;
-
-        element.attributes.put(attrName, attr);
-    }
-
-    /**
-     * Adds a new attribute with boolean data type to an existing element.
-     * 
-     * @param elementName
-     *            the name of the element to which the new attribute will be
-     *            added.
-     * @param attrName
-     *            the attribute name.
-     * @param hasDefaultValue
-     *            the flag which indicates whether this attribute must have a
-     *            default value.
-     * @param defaultValue
-     *            the default value.
-     */
-    protected void addBooleanAttribute(String elementName, String attrName,
-            boolean hasDefaultValue, boolean defaultValue) {
-        String defaultVal = hasDefaultValue ? (defaultValue ? "TRUE" : "FALSE") : null;
-        ArrayList<String> values = new ArrayList<String>(2);
-        values.add("TRUE");
-        values.add("FALSE");
-
-        addAttribute(elementName, attrName, DATATYPE_BOOLEAN, true, defaultVal, values);
-    }
-
-    /**
-     * Adds an existing element to the list of child elements of the specified
-     * parent element.
-     * 
-     * @param elementName
-     *            the name of the element to be added.
-     * @param parentName
-     *            the parent element name.
-     */
-    protected void addChildElement(String elementName, String parentName) {
-        Element parent = findElement(parentName);
-        Element element = findElement(elementName);
-        parent.children.add(element.name);
-    }
-
-    /**
-     * Adds a new element type to this IIOMetadataFormat with a child policy (if
-     * policy is not CHILD_POLICY_REPEAT).
-     * 
-     * @param elementName
-     *            the name of the element to be added.
-     * @param parentName
-     *            the parent element name.
-     * @param childPolicy
-     *            one of the CHILD_POLICY_* constants defined by
-     *            IIOMetadataFormat.
-     */
-    protected void addElement(String elementName, String parentName, int childPolicy) {
-        if (childPolicy < CHILD_POLICY_EMPTY || childPolicy > CHILD_POLICY_MAX
-                || childPolicy == CHILD_POLICY_REPEAT) {
-            throw new IllegalArgumentException("childPolicy is not one of the predefined constants");
-        }
-
-        Element parent = findElement(parentName);
-        Element element = new Element();
-        element.name = elementName;
-        element.childPolicy = childPolicy;
-        elementHash.put(elementName, element);
-        parent.children.add(elementName);
-    }
-
-    /**
-     * Adds a new element type to this IIOMetadataFormat with
-     * CHILD_POLICY_REPEAT and the specified minimum and maximum number of child
-     * elements.
-     * 
-     * @param elementName
-     *            the element name to be added.
-     * @param parentName
-     *            the parent element name.
-     * @param minChildren
-     *            the minimum number of child elements.
-     * @param maxChildren
-     *            the maximum number of child elements.
-     */
-    protected void addElement(String elementName, String parentName, int minChildren,
-            int maxChildren) {
-        if (minChildren < 0) {
-            throw new IllegalArgumentException("minChildren < 0!");
-        }
-        if (minChildren > maxChildren) {
-            throw new IllegalArgumentException("minChildren > maxChildren!");
-        }
-
-        Element parent = findElement(parentName);
-        Element element = new Element();
-        element.name = elementName;
-        element.childPolicy = CHILD_POLICY_REPEAT;
-        element.minChildren = minChildren;
-        element.maxChildren = maxChildren;
-        elementHash.put(elementName, element);
-        parent.children.add(elementName);
-    }
-
-    /**
-     * Adds an Object reference with the specified class type to be stored as
-     * element's value.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param classType
-     *            the class indicates the legal types for the object's value.
-     * @param arrayMinLength
-     *            the minimum legal length for the array.
-     * @param arrayMaxLength
-     *            the maximum legal length for the array.
-     */
-    protected void addObjectValue(String elementName, Class<?> classType, int arrayMinLength,
-            int arrayMaxLength) {
-        Element element = findElement(elementName);
-
-        ObjectValue objVal = new ObjectValue();
-        objVal.classType = classType;
-        objVal.arrayMaxLength = arrayMaxLength;
-        objVal.arrayMinLength = arrayMinLength;
-        objVal.valueType = VALUE_LIST;
-
-        element.objectValue = objVal;
-    }
-
-    /**
-     * Adds an Object reference with the specified class type to be stored as an
-     * element's value.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param classType
-     *            the class indicates the legal types for the object's value.
-     * @param required
-     *            a flag indicated that this object value must be present.
-     * @param defaultValue
-     *            the default value, or null.
-     */
-    protected <T> void addObjectValue(String elementName, Class<T> classType, boolean required,
-            T defaultValue) {
-        // note: reqired is an unused parameter
-        Element element = findElement(elementName);
-
-        ObjectValue<T> objVal = new ObjectValue<T>();
-        objVal.classType = classType;
-        objVal.defaultValue = defaultValue;
-        objVal.valueType = VALUE_ARBITRARY;
-
-        element.objectValue = objVal;
-    }
-
-    /**
-     * Adds an Object reference with the specified class type to be stored as
-     * the element's value.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param classType
-     *            the class indicates the legal types for the object value.
-     * @param required
-     *            a flag indicated that this object value must be present.
-     * @param defaultValue
-     *            the default value, or null.
-     * @param enumeratedValues
-     *            the list of legal values for the object.
-     */
-    protected <T> void addObjectValue(String elementName, Class<T> classType, boolean required,
-            T defaultValue, List<? extends T> enumeratedValues) {
-        // note: reqired is an unused parameter
-        if (enumeratedValues == null || enumeratedValues.isEmpty()) {
-            throw new IllegalArgumentException("enumeratedValues is empty or null");
-        }
-
-        try {
-            for (T enumeratedValue : enumeratedValues) {
-                if (enumeratedValue == null) {
-                    throw new IllegalArgumentException("enumeratedValues contains a null!");
-                }
-            }
-        } catch (ClassCastException e) {
-            throw new IllegalArgumentException(
-                    "enumeratedValues contains a value not of class classType!");
-        }
-
-        Element element = findElement(elementName);
-
-        ObjectValue<T> objVal = new ObjectValue<T>();
-        objVal.classType = classType;
-        objVal.defaultValue = defaultValue;
-        objVal.enumeratedValues = enumeratedValues;
-        objVal.valueType = VALUE_ENUMERATION;
-
-        element.objectValue = objVal;
-    }
-
-    /**
-     * Adds an Object reference with the specified class type to be stored as
-     * the element's value.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param classType
-     *            the class indicates the legal types for the object value.
-     * @param defaultValue
-     *            the default value, or null.
-     * @param minValue
-     *            the minimum legal value for the object value.
-     * @param maxValue
-     *            the maximum legal value for the object value.
-     * @param minInclusive
-     *            the flag which indicates whether the minValue is inclusive.
-     * @param maxInclusive
-     *            the flag which indicates whether the maxValue is inclusive.
-     */
-    protected <T extends Object & Comparable<? super T>> void addObjectValue(String elementName,
-            Class<T> classType, T defaultValue, Comparable<? super T> minValue,
-            Comparable<? super T> maxValue, boolean minInclusive, boolean maxInclusive) {
-        Element element = findElement(elementName);
-
-        ObjectValue<T> objVal = new ObjectValue<T>();
-        objVal.classType = classType;
-        objVal.defaultValue = defaultValue;
-        objVal.minValue = minValue;
-        objVal.maxValue = maxValue;
-        objVal.minInclusive = minInclusive;
-        objVal.maxInclusive = maxInclusive;
-
-        objVal.valueType = VALUE_RANGE;
-        objVal.valueType |= minInclusive ? VALUE_RANGE_MIN_INCLUSIVE_MASK : 0;
-        objVal.valueType |= maxInclusive ? VALUE_RANGE_MAX_INCLUSIVE_MASK : 0;
-
-        element.objectValue = objVal;
-    }
-
-    public int getAttributeDataType(String elementName, String attrName) {
-        Attlist attr = findAttribute(elementName, attrName);
-        return attr.dataType;
-    }
-
-    public String getAttributeDefaultValue(String elementName, String attrName) {
-        Attlist attr = findAttribute(elementName, attrName);
-        return attr.defaultValue;
-    }
-
-    public String getAttributeDescription(String elementName, String attrName, Locale locale) {
-        findAttribute(elementName, attrName);
-        return getResourceString(elementName + "/" + attrName, locale);
-    }
-
-    public String[] getAttributeEnumerations(String elementName, String attrName) {
-        Attlist attr = findAttribute(elementName, attrName);
-        if (attr.valueType != VALUE_ENUMERATION) {
-            throw new IllegalArgumentException("Attribute is not an enumeration!");
-        }
-
-        return attr.enumeratedValues.toArray(new String[attr.enumeratedValues.size()]);
-    }
-
-    public int getAttributeListMaxLength(String elementName, String attrName) {
-        Attlist attr = findAttribute(elementName, attrName);
-        if (attr.valueType != VALUE_LIST) {
-            throw new IllegalArgumentException("Attribute is not a list!");
-        }
-        return attr.listMaxLength;
-    }
-
-    public int getAttributeListMinLength(String elementName, String attrName) {
-        Attlist attr = findAttribute(elementName, attrName);
-        if (attr.valueType != VALUE_LIST) {
-            throw new IllegalArgumentException("Attribute is not a list!");
-        }
-        return attr.listMinLength;
-    }
-
-    public String getAttributeMaxValue(String elementName, String attrName) {
-        Attlist attr = findAttribute(elementName, attrName);
-        if ((attr.valueType & VALUE_RANGE) == 0) {
-            throw new IllegalArgumentException("Attribute is not a range!");
-        }
-        return attr.maxValue;
-    }
-
-    public String getAttributeMinValue(String elementName, String attrName) {
-        Attlist attr = findAttribute(elementName, attrName);
-        if ((attr.valueType & VALUE_RANGE) == 0) {
-            throw new IllegalArgumentException("Attribute is not a range!");
-        }
-        return attr.minValue;
-    }
-
-    public String[] getAttributeNames(String elementName) {
-        Element element = findElement(elementName);
-        return element.attributes.keySet().toArray(new String[element.attributes.size()]);
-    }
-
-    public int getAttributeValueType(String elementName, String attrName) {
-        Attlist attr = findAttribute(elementName, attrName);
-        return attr.valueType;
-    }
-
-    public String[] getChildNames(String elementName) {
-        Element element = findElement(elementName);
-        if (element.childPolicy == CHILD_POLICY_EMPTY) { // Element cannot have
-            // children
-            return null;
-        }
-        return element.children.toArray(new String[element.children.size()]);
-    }
-
-    public int getChildPolicy(String elementName) {
-        Element element = findElement(elementName);
-        return element.childPolicy;
-    }
-
-    public String getElementDescription(String elementName, Locale locale) {
-        findElement(elementName); // Check if there is such element
-        return getResourceString(elementName, locale);
-    }
-
-    public int getElementMaxChildren(String elementName) {
-        Element element = findElement(elementName);
-        if (element.childPolicy != CHILD_POLICY_REPEAT) {
-            throw new IllegalArgumentException("Child policy is not CHILD_POLICY_REPEAT!");
-        }
-        return element.maxChildren;
-    }
-
-    public int getElementMinChildren(String elementName) {
-        Element element = findElement(elementName);
-        if (element.childPolicy != CHILD_POLICY_REPEAT) {
-            throw new IllegalArgumentException("Child policy is not CHILD_POLICY_REPEAT!");
-        }
-        return element.minChildren;
-    }
-
-    public int getObjectArrayMaxLength(String elementName) {
-        Element element = findElement(elementName);
-        ObjectValue v = element.objectValue;
-        if (v == null || v.valueType != VALUE_LIST) {
-            throw new IllegalArgumentException("Not a list!");
-        }
-        return v.arrayMaxLength;
-    }
-
-    public int getObjectArrayMinLength(String elementName) {
-        Element element = findElement(elementName);
-        ObjectValue v = element.objectValue;
-        if (v == null || v.valueType != VALUE_LIST) {
-            throw new IllegalArgumentException("Not a list!");
-        }
-        return v.arrayMinLength;
-    }
-
-    public Class<?> getObjectClass(String elementName) {
-        ObjectValue v = findObjectValue(elementName);
-        return v.classType;
-    }
-
-    public Object getObjectDefaultValue(String elementName) {
-        ObjectValue v = findObjectValue(elementName);
-        return v.defaultValue;
-    }
-
-    public Object[] getObjectEnumerations(String elementName) {
-        Element element = findElement(elementName);
-        ObjectValue v = element.objectValue;
-        if (v == null || v.valueType != VALUE_ENUMERATION) {
-            throw new IllegalArgumentException("Not an enumeration!");
-        }
-        return v.enumeratedValues.toArray();
-    }
-
-    public Comparable<?> getObjectMaxValue(String elementName) {
-        Element element = findElement(elementName);
-        ObjectValue v = element.objectValue;
-        if (v == null || (v.valueType & VALUE_RANGE) == 0) {
-            throw new IllegalArgumentException("Not a range!");
-        }
-        return v.maxValue;
-    }
-
-    public Comparable<?> getObjectMinValue(String elementName) {
-        Element element = findElement(elementName);
-        ObjectValue v = element.objectValue;
-        if (v == null || (v.valueType & VALUE_RANGE) == 0) {
-            throw new IllegalArgumentException("Not a range!");
-        }
-        return v.minValue;
-    }
-
-    public int getObjectValueType(String elementName) {
-        Element element = findElement(elementName);
-        if (element.objectValue == null) {
-            return VALUE_NONE;
-        }
-        return element.objectValue.valueType;
-    }
-
-    /**
-     * Gets the resource base name for locating ResourceBundles.
-     * 
-     * @return the current resource base name.
-     */
-    protected String getResourceBaseName() {
-        return resourceBaseName;
-    }
-
-    public String getRootName() {
-        return rootName;
-    }
-
-    /**
-     * Gets the standard format instance.
-     * 
-     * @return the IIOMetadataFormat instance.
-     */
-    public static IIOMetadataFormat getStandardFormatInstance() {
-        if (standardFormat == null) {
-            standardFormat = new IIOStandardMetadataFormat();
-        }
-
-        return standardFormat;
-    }
-
-    public boolean isAttributeRequired(String elementName, String attrName) {
-        return findAttribute(elementName, attrName).required;
-    }
-
-    /**
-     * Removes the specified attribute from the specified element.
-     * 
-     * @param elementName
-     *            the specified element name.
-     * @param attrName
-     *            the specified attribute name.
-     */
-    protected void removeAttribute(String elementName, String attrName) {
-        Element element = findElement(elementName);
-        element.attributes.remove(attrName);
-    }
-
-    /**
-     * Removes the specified element from this format.
-     * 
-     * @param elementName
-     *            the specified element name.
-     */
-    protected void removeElement(String elementName) {
-        Element element;
-        if ((element = elementHash.get(elementName)) != null) {
-            elementHash.remove(elementName);
-            for (Element e : elementHash.values()) {
-                e.children.remove(element.name);
-            }
-        }
-    }
-
-    /**
-     * Removes the object value from the specified element.
-     * 
-     * @param elementName
-     *            the element name.
-     */
-    protected void removeObjectValue(String elementName) {
-        Element element = findElement(elementName);
-        element.objectValue = null;
-    }
-
-    /**
-     * Sets a new base name for ResourceBundles containing descriptions of
-     * elements and attributes for this format.
-     * 
-     * @param resourceBaseName
-     *            the new resource base name.
-     */
-    protected void setResourceBaseName(String resourceBaseName) {
-        if (resourceBaseName == null) {
-            throw new IllegalArgumentException("resourceBaseName == null!");
-        }
-        this.resourceBaseName = resourceBaseName;
-    }
-
-    /**
-     * The Class Element.
-     */
-    @SuppressWarnings( {
-        "ClassWithoutConstructor"
-    })
-    private class Element {
-
-        /**
-         * The name.
-         */
-        String name;
-
-        /**
-         * The children.
-         */
-        ArrayList<String> children = new ArrayList<String>();
-
-        /**
-         * The attributes.
-         */
-        HashMap<String, Attlist> attributes = new HashMap<String, Attlist>();
-
-        /**
-         * The min children.
-         */
-        int minChildren;
-
-        /**
-         * The max children.
-         */
-        int maxChildren;
-
-        /**
-         * The child policy.
-         */
-        int childPolicy;
-
-        /**
-         * The object value.
-         */
-        ObjectValue objectValue;
-    }
-
-    /**
-     * The Class Attlist.
-     */
-    @SuppressWarnings( {
-        "ClassWithoutConstructor"
-    })
-    private class Attlist {
-
-        /**
-         * The name.
-         */
-        String name;
-
-        /**
-         * The data type.
-         */
-        int dataType;
-
-        /**
-         * The required.
-         */
-        boolean required;
-
-        /**
-         * The list min length.
-         */
-        int listMinLength;
-
-        /**
-         * The list max length.
-         */
-        int listMaxLength;
-
-        /**
-         * The default value.
-         */
-        String defaultValue;
-
-        /**
-         * The enumerated values.
-         */
-        List<String> enumeratedValues;
-
-        /**
-         * The min value.
-         */
-        String minValue;
-
-        /**
-         * The max value.
-         */
-        String maxValue;
-
-        /**
-         * The min inclusive.
-         */
-        boolean minInclusive;
-
-        /**
-         * The max inclusive.
-         */
-        boolean maxInclusive;
-
-        /**
-         * The value type.
-         */
-        int valueType;
-    }
-
-    /**
-     * The Class ObjectValue.
-     */
-    @SuppressWarnings( {
-        "ClassWithoutConstructor"
-    })
-    private class ObjectValue<T> {
-
-        /**
-         * The class type.
-         */
-        Class<T> classType;
-
-        /**
-         * The array min length.
-         */
-        int arrayMinLength;
-
-        /**
-         * The array max length.
-         */
-        int arrayMaxLength;
-
-        /**
-         * The default value.
-         */
-        T defaultValue;
-
-        /**
-         * The enumerated values.
-         */
-        List<? extends T> enumeratedValues;
-
-        /**
-         * The min value.
-         */
-        Comparable<? super T> minValue;
-
-        /**
-         * The max value.
-         */
-        Comparable<? super T> maxValue;
-
-        /**
-         * The min inclusive.
-         */
-        boolean minInclusive;
-
-        /**
-         * The max inclusive.
-         */
-        boolean maxInclusive;
-
-        /**
-         * The value type.
-         */
-        int valueType;
-    }
-
-    /**
-     * Find element.
-     * 
-     * @param name
-     *            the name.
-     * @return the element.
-     */
-    private Element findElement(String name) {
-        Element element;
-        if ((element = elementHash.get(name)) == null) {
-            throw new IllegalArgumentException("element name is null or no such element: " + name);
-        }
-
-        return element;
-    }
-
-    /**
-     * Find attribute.
-     * 
-     * @param elementName
-     *            the element name.
-     * @param attributeName
-     *            the attribute name.
-     * @return the attlist.
-     */
-    private Attlist findAttribute(String elementName, String attributeName) {
-        Element element = findElement(elementName);
-        Attlist attribute;
-        if ((attribute = element.attributes.get(attributeName)) == null) {
-            throw new IllegalArgumentException("attribute name is null or no such attribute: "
-                    + attributeName);
-        }
-
-        return attribute;
-    }
-
-    /**
-     * Find object value.
-     * 
-     * @param elementName
-     *            the element name.
-     * @return the object value.
-     */
-    private ObjectValue findObjectValue(String elementName) {
-        Element element = findElement(elementName);
-        ObjectValue v = element.objectValue;
-        if (v == null) {
-            throw new IllegalArgumentException("No object within element");
-        }
-        return v;
-    }
-
-    /**
-     * Gets the resource string.
-     * 
-     * @param key
-     *            the key.
-     * @param locale
-     *            the locale.
-     * @return the resource string.
-     */
-    private String getResourceString(String key, Locale locale) {
-        if (locale == null) {
-            locale = Locale.getDefault();
-        }
-
-        // Get the context class loader and try to locate the bundle with it
-        // first
-        ClassLoader contextClassloader = AccessController
-                .doPrivileged(new PrivilegedAction<ClassLoader>() {
-                    public ClassLoader run() {
-                        return Thread.currentThread().getContextClassLoader();
-                    }
-                });
-
-        // Now try to get the resource bundle
-        ResourceBundle rb;
-        try {
-            rb = ResourceBundle.getBundle(resourceBaseName, locale, contextClassloader);
-        } catch (MissingResourceException e) {
-            try {
-                rb = ResourceBundle.getBundle(resourceBaseName, locale);
-            } catch (MissingResourceException e1) {
-                return null;
-            }
-        }
-
-        try {
-            return rb.getString(key);
-        } catch (MissingResourceException e) {
-            return null;
-        } catch (ClassCastException e) {
-            return null; // Not a string resource
-        }
-    }
-}
diff --git a/awt/javax/imageio/metadata/IIOMetadataNode.java b/awt/javax/imageio/metadata/IIOMetadataNode.java
deleted file mode 100644
index efbaae8..0000000
--- a/awt/javax/imageio/metadata/IIOMetadataNode.java
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.metadata;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.TypeInfo;
-import org.w3c.dom.UserDataHandler;
-
-//???AWT
-//import org.w3c.dom.TypeInfo;
-//import org.w3c.dom.UserDataHandler;
-
-/**
- * The Class IIOMetadataNode represents a node of the (DOM-style) metadata tree.
- * 
- * @since Android 1.0
- */
-public class IIOMetadataNode implements Element, NodeList {
-
-    /**
-     * The node name.
-     */
-    private String nodeName;
-
-    /**
-     * The node value.
-     */
-    private String nodeValue;
-
-    /**
-     * The attributes.
-     */
-    private IIOMetadataNodeList attrs = new IIOMetadataNodeList(new ArrayList<IIOMetadataNode>());
-
-    /**
-     * The parent node.
-     */
-    private IIOMetadataNode parent;
-
-    /**
-     * The first child node.
-     */
-    private IIOMetadataNode firstChild;
-
-    /**
-     * The last child node.
-     */
-    private IIOMetadataNode lastChild;
-
-    /**
-     * The previous sibling.
-     */
-    private IIOMetadataNode previousSibling;
-
-    /**
-     * The next sibling.
-     */
-    private IIOMetadataNode nextSibling;
-
-    /**
-     * The number of children.
-     */
-    private int nChildren;
-
-    /**
-     * The user object associated with this node.
-     */
-    private Object userObject;
-
-    /**
-     * The text content of this node.
-     */
-    private String textContent;
-
-    /**
-     * Instantiates a new empty node.
-     */
-    public IIOMetadataNode() {
-    }
-
-    /**
-     * Instantiates a new empty node with the specified name.
-     * 
-     * @param nodeName
-     *            the node name.
-     */
-    public IIOMetadataNode(String nodeName) {
-        this.nodeName = nodeName;
-    }
-
-    /**
-     * Instantiates a new IIOMetadataNode with the specified name and value.
-     * 
-     * @param nodeName
-     *            the node name.
-     * @param nodeValue
-     *            the node value.
-     */
-    private IIOMetadataNode(String nodeName, String nodeValue) {
-        this.nodeName = nodeName;
-        this.nodeValue = nodeValue;
-    }
-
-    public String getTagName() {
-        return nodeName;
-    }
-
-    public String getAttribute(String name) {
-        Attr attrNode = (Attr)attrs.getNamedItem(name);
-        return (attrNode == null) ? "" : attrNode.getValue();
-    }
-
-    public void setAttribute(String name, String value) throws DOMException {
-        Attr attr = (Attr)attrs.getNamedItem(name);
-        if (attr != null) {
-            attr.setValue(value);
-        } else {
-            attrs.list.add(new IIOMetadataAttr(name, value, this));
-        }
-    }
-
-    public void removeAttribute(String name) throws DOMException {
-        IIOMetadataAttr attr = (IIOMetadataAttr)attrs.getNamedItem(name);
-        if (attr != null) {
-            attr.setOwnerElement(null);
-            attrs.list.remove(attr);
-        }
-    }
-
-    public Attr getAttributeNode(String name) {
-        return (Attr)attrs.getNamedItem(name);
-    }
-
-    public Attr setAttributeNode(Attr newAttr) throws DOMException {
-        // Check if this attribute is already in use.
-        Element owner = newAttr.getOwnerElement();
-        if (owner != null) {
-            if (owner == this) { // Replacing an attribute node by itself has no
-                // effect
-                return null;
-            } else {
-                throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR,
-                        "Attribute is already in use");
-            }
-        }
-
-        String name = newAttr.getName();
-        Attr oldAttr = getAttributeNode(name);
-        if (oldAttr != null) {
-            removeAttributeNode(oldAttr);
-        }
-
-        IIOMetadataAttr iioAttr;
-        if (newAttr instanceof IIOMetadataAttr) {
-            iioAttr = (IIOMetadataAttr)newAttr;
-            iioAttr.setOwnerElement(this);
-        } else {
-            iioAttr = new IIOMetadataAttr(name, newAttr.getValue(), this);
-        }
-
-        attrs.list.add(iioAttr);
-
-        return oldAttr;
-    }
-
-    public Attr removeAttributeNode(Attr oldAttr) throws DOMException {
-        if (!attrs.list.remove(oldAttr)) { // Not found
-            throw new DOMException(DOMException.NOT_FOUND_ERR, "No such attribute!");
-        }
-
-        ((IIOMetadataAttr)oldAttr).setOwnerElement(null);
-
-        return oldAttr;
-    }
-
-    public NodeList getElementsByTagName(String name) {
-        ArrayList<IIOMetadataNode> nodes = new ArrayList<IIOMetadataNode>();
-
-        // Non-recursive tree walk
-        Node pos = this;
-
-        while (pos != null) {
-            if (pos.getNodeName().equals(name)) {
-                nodes.add((IIOMetadataNode)pos);
-            }
-
-            Node nextNode = pos.getFirstChild();
-
-            while (nextNode == null) {
-                if (pos == this) {
-                    break;
-                }
-
-                nextNode = pos.getNextSibling();
-
-                if (nextNode == null) {
-                    pos = pos.getParentNode();
-
-                    if (pos == null || pos == this) {
-                        nextNode = null;
-                        break;
-                    }
-                }
-            }
-            pos = nextNode;
-        }
-
-        return new IIOMetadataNodeList(nodes);
-    }
-
-    public String getAttributeNS(String namespaceURI, String localName) throws DOMException {
-        return getAttribute(localName);
-    }
-
-    public void setAttributeNS(String namespaceURI, String qualifiedName, String value)
-            throws DOMException {
-        setAttribute(qualifiedName, value);
-    }
-
-    public void removeAttributeNS(String namespaceURI, String localName) throws DOMException {
-        removeAttribute(localName);
-    }
-
-    public Attr getAttributeNodeNS(String namespaceURI, String localName) throws DOMException {
-        return getAttributeNode(localName);
-    }
-
-    public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
-        return setAttributeNode(newAttr);
-    }
-
-    public NodeList getElementsByTagNameNS(String namespaceURI, String localName)
-            throws DOMException {
-        return getElementsByTagName(localName);
-    }
-
-    public boolean hasAttribute(String name) {
-        return attrs.getNamedItem(name) != null;
-    }
-
-    public boolean hasAttributeNS(String namespaceURI, String localName) throws DOMException {
-        return hasAttribute(localName);
-    }
-
-    // ???AWT
-    /*
-     * public TypeInfo getSchemaTypeInfo() { throw new
-     * DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported"); }
-     */
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Element (DOM Level
-     * 3)</i>
-     * <p>
-     * If the parameter isId is true, this method declares the specified
-     * attribute to be a user-determined ID attribute . This affects the value
-     * of Attr.isId and the behavior of Document.getElementById, but does not
-     * change any schema that may be in use, in particular this does not affect
-     * the Attr.schemaTypeInfo of the specified Attr node. Use the value false
-     * for the parameter isId to undeclare an attribute for being a
-     * user-determined ID attribute. To specify an attribute by local name and
-     * namespace URI, use the setIdAttributeNS method.
-     * </p>
-     * 
-     * @param name
-     *            the name of the attribute.
-     * @param isId
-     *            the flag which determines whether this attribute is of type
-     *            ID.
-     * @throws DOMException
-     *             if a DOM error occurred while setting the attribute type.
-     *             <p>
-     *             NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *             <br>
-     *             NOT_FOUND_ERR: Raised if the specified node is not an
-     *             attribute of this element.
-     *             </p>
-     */
-    public void setIdAttribute(String name, boolean isId) throws DOMException {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Element (DOM Level
-     * 3)</i>
-     * <p>
-     * If the parameter isId is true, this method declares the specified
-     * attribute to be a user-determined ID attribute . This affects the value
-     * of Attr.isId and the behavior of Document.getElementById, but does not
-     * change any schema that may be in use, in particular this does not affect
-     * the Attr.schemaTypeInfo of the specified Attr node. Use the value false
-     * for the parameter isId to undeclare an attribute for being a
-     * user-determined ID attribute.
-     * </p>
-     * 
-     * @param namespaceURI
-     *            the namespace URI of the attribute.
-     * @param localName
-     *            the local name of the attribute.
-     * @param isId
-     *            the flag which determines whether this attribute is of type
-     *            ID.
-     * @throws DOMException
-     *             if a DOM error occurred while setting the attribute type.
-     *             <p>
-     *             NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *             <br>
-     *             NOT_FOUND_ERR: Raised if the specified node is not an
-     *             attribute of this element.
-     *             </p>
-     */
-    public void setIdAttributeNS(String namespaceURI, String localName, boolean isId)
-            throws DOMException {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Element (DOM Level
-     * 3)</i>
-     * <p>
-     * If the parameter isId is true, this method declares the specified
-     * attribute to be a user-determined ID attribute . This affects the value
-     * of Attr.isId and the behavior of Document.getElementById, but does not
-     * change any schema that may be in use, in particular this does not affect
-     * the Attr.schemaTypeInfo of the specified Attr node. Use the value false
-     * for the parameter isId to undeclare an attribute for being a
-     * user-determined ID attribute.
-     * </p>
-     * 
-     * @param idAttr
-     *            the attribute node.
-     * @param isId
-     *            the flag which determines whether this attribute is of type
-     *            ID.
-     * @throws DOMException
-     *             if a DOM error occurred while setting the attribute type.
-     *             <p>
-     *             NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *             <br>
-     *             NOT_FOUND_ERR: Raised if the specified node is not an
-     *             attribute of this element.
-     *             </p>
-     */
-    public void setIdAttributeNode(Attr idAttr, boolean isId) throws DOMException {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    public String getNodeName() {
-        return nodeName;
-    }
-
-    public String getNodeValue() throws DOMException {
-        return nodeValue;
-    }
-
-    public void setNodeValue(String nodeValue) throws DOMException {
-        this.nodeValue = nodeValue;
-    }
-
-    public short getNodeType() {
-        return ELEMENT_NODE;
-    }
-
-    public Node getParentNode() {
-        return parent;
-    }
-
-    public NodeList getChildNodes() {
-        return this;
-    }
-
-    public Node getFirstChild() {
-        return firstChild;
-    }
-
-    public Node getLastChild() {
-        return lastChild;
-    }
-
-    public Node getPreviousSibling() {
-        return previousSibling;
-    }
-
-    public Node getNextSibling() {
-        return nextSibling;
-    }
-
-    public NamedNodeMap getAttributes() {
-        return attrs;
-    }
-
-    public Document getOwnerDocument() {
-        return null;
-    }
-
-    public Node insertBefore(Node newChild, Node refChild) throws DOMException {
-        if (newChild == null) {
-            throw new IllegalArgumentException("newChild == null!");
-        }
-
-        IIOMetadataNode newIIOChild = (IIOMetadataNode)newChild;
-        IIOMetadataNode refIIOChild = (IIOMetadataNode)refChild;
-
-        newIIOChild.parent = this;
-
-        if (refIIOChild == null) {
-            newIIOChild.nextSibling = null;
-            newIIOChild.previousSibling = lastChild;
-
-            // Fix this node
-            lastChild = newIIOChild;
-            if (firstChild == null) {
-                firstChild = newIIOChild;
-            }
-        } else {
-            newIIOChild.nextSibling = refIIOChild;
-            newIIOChild.previousSibling = refIIOChild.previousSibling;
-
-            // Fix this node
-            if (firstChild == refIIOChild) {
-                firstChild = newIIOChild;
-            }
-
-            // Fix next node
-            if (refIIOChild != null) {
-                refIIOChild.previousSibling = newIIOChild;
-            }
-        }
-
-        // Fix prev node
-        if (newIIOChild.previousSibling != null) {
-            newIIOChild.previousSibling.nextSibling = newIIOChild;
-        }
-
-        nChildren++;
-
-        return newIIOChild;
-    }
-
-    public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
-        if (newChild == null) {
-            throw new IllegalArgumentException("newChild == null!");
-        }
-
-        IIOMetadataNode newIIOChild = (IIOMetadataNode)newChild;
-        IIOMetadataNode oldIIOChild = (IIOMetadataNode)oldChild;
-
-        IIOMetadataNode next = oldIIOChild.nextSibling;
-        IIOMetadataNode previous = oldIIOChild.previousSibling;
-
-        // Fix new node
-        newIIOChild.parent = this;
-        newIIOChild.nextSibling = next;
-        newIIOChild.previousSibling = previous;
-
-        // Fix this node
-        if (lastChild == oldIIOChild) {
-            lastChild = newIIOChild;
-        }
-        if (firstChild == oldIIOChild) {
-            firstChild = newIIOChild;
-        }
-
-        // Fix siblings
-        if (next != null) {
-            next.previousSibling = newIIOChild;
-        }
-        if (previous != null) {
-            previous.nextSibling = newIIOChild;
-        }
-
-        // Fix old child
-        oldIIOChild.parent = null;
-        oldIIOChild.nextSibling = next;
-        oldIIOChild.previousSibling = previous;
-
-        return oldIIOChild;
-    }
-
-    public Node removeChild(Node oldChild) throws DOMException {
-        if (oldChild == null) {
-            throw new IllegalArgumentException("oldChild == null!");
-        }
-
-        IIOMetadataNode oldIIOChild = (IIOMetadataNode)oldChild;
-
-        // Fix next and previous
-        IIOMetadataNode previous = oldIIOChild.previousSibling;
-        IIOMetadataNode next = oldIIOChild.nextSibling;
-
-        if (previous != null) {
-            previous.nextSibling = next;
-        }
-        if (next != null) {
-            next.previousSibling = previous;
-        }
-
-        // Fix this node
-        if (lastChild == oldIIOChild) {
-            lastChild = previous;
-        }
-        if (firstChild == oldIIOChild) {
-            firstChild = next;
-        }
-        nChildren--;
-
-        // Fix old child
-        oldIIOChild.parent = null;
-        oldIIOChild.previousSibling = null;
-        oldIIOChild.nextSibling = null;
-
-        return oldIIOChild;
-    }
-
-    public Node appendChild(Node newChild) throws DOMException {
-        return insertBefore(newChild, null);
-    }
-
-    public boolean hasChildNodes() {
-        return nChildren != 0;
-    }
-
-    public Node cloneNode(boolean deep) {
-        IIOMetadataNode cloned = new IIOMetadataNode(nodeName);
-        cloned.setUserObject(getUserObject());
-
-        if (deep) { // Clone recursively
-            IIOMetadataNode c = firstChild;
-            while (c != null) {
-                cloned.insertBefore(c.cloneNode(true), null);
-                c = c.nextSibling;
-            }
-        }
-
-        return cloned; // To change body of implemented methods use File |
-        // Settings | File Templates.
-    }
-
-    public void normalize() {
-        // Do nothing
-    }
-
-    public boolean isSupported(String feature, String version) {
-        return false;
-    }
-
-    public String getNamespaceURI() {
-        return null;
-    }
-
-    public String getPrefix() {
-        return null;
-    }
-
-    public void setPrefix(String prefix) throws DOMException {
-        // Do nothing
-    }
-
-    public String getLocalName() {
-        return nodeName;
-    }
-
-    public boolean hasAttributes() {
-        return attrs.list.size() > 0;
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * The absolute base URI of this node or null if the implementation wasn't
-     * able to obtain an absolute URI. This value is computed as described in.
-     * However, when the Document supports the feature "HTML" [DOM Level 2
-     * HTML], the base URI is computed using first the value of the href
-     * attribute of the HTML BASE element if any, and the value of the
-     * documentURI attribute from the Document interface otherwise.
-     * </p>
-     * 
-     * @return the string representation of the absolute base URI.
-     */
-    public String getBaseURI() {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Compares the reference node, i.e. the node on which this method is being
-     * called, with a node, i.e. the one passed as a parameter, with regard to
-     * their position in the document and according to the document order.
-     * </p>
-     * 
-     * @param other
-     *            the node to compare against the reference node.
-     * @return Returns how the node is positioned relatively to the reference
-     *         node.
-     * @throws DOMException
-     *             NOT_SUPPORTED_ERR: when the compared nodes are from different
-     *             DOM implementations that do not coordinate to return
-     *             consistent implementation-specific results.
-     */
-    public short compareDocumentPosition(Node other) throws DOMException {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * This attribute returns the text content of this node and its descendants.
-     * When it is defined to be null, setting it has no effect. On setting, any
-     * possible children this node may have are removed and, if it the new
-     * string is not empty or null, replaced by a single Text node containing
-     * the string this attribute is set to. On getting, no serialization is
-     * performed, the returned string does not contain any markup. No whitespace
-     * normalization is performed and the returned string does not contain the
-     * white spaces in element content (see the attribute
-     * Text.isElementContentWhitespace). Similarly, on setting, no parsing is
-     * performed either, the input string is taken as pure textual content. The
-     * string returned is made of the text content of this node depending on its
-     * type, as defined below:
-     * <table>
-     * <tr>
-     * <td><strong>Node type</strong></td>
-     * <td><strong>Content</strong></td>
-     * </tr>
-     * <tr>
-     * <td>ELEMENT_NODE, ATTRIBUTE_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
-     * DOCUMENT_FRAGMENT_NODE</td>
-     * <td>concatenation of the textContent attribute value of every child node,
-     * excluding COMMENT_NODE and PROCESSING_INSTRUCTION_NODE nodes. This is the
-     * empty string if the node has no children.</td>
-     * </tr>
-     * <tr>
-     * <td>TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
-     * PROCESSING_INSTRUCTION_NODE</td>
-     * <td>nodeValue</td>
-     * </tr>
-     * <tr>
-     * <td>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
-     * <td>null</td>
-     * </tr>
-     * </table>
-     * </p>
-     * 
-     * @return the text content depending on the type of this node.
-     * @throws DOMException
-     *             DOMSTRING_SIZE_ERR: Raised when it would return more
-     *             characters than fit in a DOMString variable on the
-     *             implementation platform.
-     */
-    public String getTextContent() throws DOMException {
-        return textContent;
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * This attribute returns the text content of this node and its descendants.
-     * When it is defined to be null, setting it has no effect. On setting, any
-     * possible children this node may have are removed and, if it the new
-     * string is not empty or null, replaced by a single Text node containing
-     * the string this attribute is set to. On getting, no serialization is
-     * performed, the returned string does not contain any markup. No whitespace
-     * normalization is performed and the returned string does not contain the
-     * white spaces in element content (see the attribute
-     * Text.isElementContentWhitespace). Similarly, on setting, no parsing is
-     * performed either, the input string is taken as pure textual content. The
-     * string returned is made of the text content of this node depending on its
-     * type, as defined below:
-     * <table>
-     * <tr>
-     * <td><strong>Node type</strong></td>
-     * <td><strong>Content</strong></td>
-     * </tr>
-     * <tr>
-     * <td>ELEMENT_NODE, ATTRIBUTE_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
-     * DOCUMENT_FRAGMENT_NODE</td>
-     * <td>concatenation of the textContent attribute value of every child node,
-     * excluding COMMENT_NODE and PROCESSING_INSTRUCTION_NODE nodes. This is the
-     * empty string if the node has no children.</td>
-     * </tr>
-     * <tr>
-     * <td>TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
-     * PROCESSING_INSTRUCTION_NODE</td>
-     * <td>nodeValue</td>
-     * </tr>
-     * <tr>
-     * <td>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
-     * <td>null</td>
-     * </tr>
-     * </table>
-     * </p>
-     * 
-     * @param textContent
-     *            the text content for this node.
-     * @throws DOMException
-     *             NO_MODIFICATION_ALLOWED_ERR: Raised when the node is
-     *             readonly.
-     */
-    public void setTextContent(String textContent) throws DOMException {
-        this.textContent = textContent;
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Returns whether this node is the same node as the given one. This method
-     * provides a way to determine whether two Node references returned by the
-     * implementation reference the same object. When two Node references are
-     * references to the same object, even if through a proxy, the references
-     * may be used completely interchangeably, such that all attributes have the
-     * same values and calling the same DOM method on either reference always
-     * has exactly the same effect.
-     * </p>
-     * 
-     * @param other
-     *            the node to test against.
-     * @return true, if the nodes are the same, false otherwise.
-     */
-    public boolean isSameNode(Node other) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Look up the prefix associated to the given namespace URI, starting from
-     * this node. The default namespace declarations are ignored by this method.
-     * See for details on the algorithm used by this method.
-     * </p>
-     * 
-     * @param namespaceURI
-     *            the namespace URI to look for.
-     * @return the associated namespace prefix if found or null if none is
-     *         found. If more than one prefix are associated to the namespace
-     *         prefix, the returned namespace prefix is implementation
-     *         dependent.
-     */
-    public String lookupPrefix(String namespaceURI) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * This method checks if the specified namespaceURI is the default namespace
-     * or not.
-     * </p>
-     * 
-     * @param namespaceURI
-     *            the namespace URI to look for.
-     * @return true, if the specified namespaceURI is the default namespace,
-     *         false otherwise.
-     */
-    public boolean isDefaultNamespace(String namespaceURI) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Look up the namespace URI associated to the given prefix, starting from
-     * this node. See for details on the algorithm used by this method.
-     * </p>
-     * 
-     * @param prefix
-     *            the prefix to look for. If this parameter is null, the method
-     *            will return the default namespace URI if any.
-     * @return the associated namespace URI or null if none is found.
-     */
-    public String lookupNamespaceURI(String prefix) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Tests whether two nodes are equal. This method tests for equality of
-     * nodes, not sameness (i.e., whether the two nodes are references to the
-     * same object) which can be tested with Node.isSameNode(). All nodes that
-     * are the same will also be equal, though the reverse may not be true. Two
-     * nodes are equal if and only if the following conditions are satisfied:
-     * <p>
-     * <li>The two nodes are of the same type.</li>
-     * <li>The following string attributes are equal: nodeName, localName,
-     * namespaceURI, prefix, nodeValue . This is: they are both null, or they
-     * have the same length and are character for character identical.</li>
-     * <li>The attributes NamedNodeMaps are equal. This is: they are both null,
-     * or they have the same length and for each node that exists in one map
-     * there is a node that exists in the other map and is equal, although not
-     * necessarily at the same index.</li>
-     * <li>The childNodes NodeLists are equal. This is: they are both null, or
-     * they have the same length and contain equal nodes at the same index. Note
-     * that normalization can affect equality; to avoid this, nodes should be
-     * normalized before being compared.</li>
-     * </p>
-     * For two DocumentType nodes to be equal, the following conditions must
-     * also be satisfied:
-     * <p>
-     * <li>The following string attributes are equal: publicId, systemId,
-     * internalSubset.</li>
-     * <li>The entities NamedNodeMaps are equal.</li>
-     * <li>The notations NamedNodeMaps are equal.</li>
-     * </p>
-     * On the other hand, the following do not affect equality: the
-     * ownerDocument, baseURI, and parentNode attributes, the specified
-     * attribute for Attr nodes, the schemaTypeInfo attribute for Attr and
-     * Element nodes, the Text.isElementContentWhitespace attribute for Text
-     * nodes, as well as any user data or event listeners registered on the
-     * nodes. </p>
-     * <p>
-     * Note: As a general rule, anything not mentioned in the description above
-     * is not significant in consideration of equality checking. Note that
-     * future versions of this specification may take into account more
-     * attributes and implementations conform to this specification are expected
-     * to be updated accordingly.
-     * </p>
-     * 
-     * @param arg
-     *            the node to compare equality with.
-     * @return true, if the nodes are equal, false otherwise.
-     */
-    public boolean isEqualNode(Node arg) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * This method returns a specialized object which implements the specialized
-     * APIs of the specified feature and version, as specified in. The
-     * specialized object may also be obtained by using binding-specific casting
-     * methods but is not necessarily expected to, as discussed in. This method
-     * also allow the implementation to provide specialized objects which do not
-     * support the Node interface.
-     * </p>
-     * 
-     * @param feature
-     *            the name of the feature requested. Note that any plus sign "+"
-     *            prepended to the name of the feature will be ignored since it
-     *            is not significant in the context of this method.
-     * @param version
-     *            this is the version number of the feature to test.
-     * @return the object which implements the specialized APIs of the specified
-     *         feature and version, if any, or null if there is no object which
-     *         implements interfaces associated with that feature. If the
-     *         DOMObject returned by this method implements the Node interface,
-     *         it must delegate to the primary core Node and not return results
-     *         inconsistent with the primary core Node such as attributes,
-     *         childNodes, etc.
-     */
-    public Object getFeature(String feature, String version) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    // ???AWT
-    /*
-     * public Object setUserData(String key, Object data, UserDataHandler
-     * handler) { throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
-     * "Method not supported"); }
-     */
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Retrieves the object associated to a key on a this node. The object must
-     * first have been set to this node by calling setUserData with the same
-     * key.
-     * </p>
-     * 
-     * @param key
-     *            the key the object is associated to.
-     * @return the DOMUserData associated to the given key on this node, or null
-     *         if there was none.
-     */
-    public Object getUserData(String key) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    public Node item(int index) {
-        if (index < 0 || index >= nChildren) {
-            return null;
-        }
-
-        Node n;
-        for (n = getFirstChild(); index > 0; index--) {
-            n = n.getNextSibling();
-        }
-
-        return n;
-    }
-
-    public int getLength() {
-        return nChildren;
-    }
-
-    /**
-     * Gets the user object associated with this node.
-     * 
-     * @return the user object associated with this node.
-     */
-    public Object getUserObject() {
-        return userObject;
-    }
-
-    public TypeInfo getSchemaTypeInfo() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object setUserData(String key, Object data, UserDataHandler handler) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Sets the user object associated with this node.
-     * 
-     * @param userObject
-     *            the new user object associated with this node.
-     */
-    public void setUserObject(Object userObject) {
-        this.userObject = userObject;
-    }
-
-    /**
-     * The Class IIOMetadataAttr.
-     */
-    private class IIOMetadataAttr extends IIOMetadataNode implements Attr {
-
-        /**
-         * The owner element.
-         */
-        private Element ownerElement;
-
-        /**
-         * Instantiates a new iIO metadata attr.
-         * 
-         * @param name
-         *            the name.
-         * @param value
-         *            the value.
-         * @param owner
-         *            the owner.
-         */
-        public IIOMetadataAttr(String name, String value, Element owner) {
-            super(name, value);
-            this.ownerElement = owner;
-        }
-
-        public String getName() {
-            return getNodeName();
-        }
-
-        public boolean getSpecified() {
-            return true;
-        }
-
-        public String getValue() {
-            return nodeValue;
-        }
-
-        public void setValue(String value) throws DOMException {
-            nodeValue = value;
-        }
-
-        public Element getOwnerElement() {
-            return ownerElement;
-        }
-
-        /**
-         * Sets the owner element.
-         * 
-         * @param ownerElement
-         *            the new owner element.
-         */
-        public void setOwnerElement(Element ownerElement) {
-            this.ownerElement = ownerElement;
-        }
-
-        /**
-         * @return
-         */
-        public boolean isId() {
-            throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-        }
-
-        @Override
-        public short getNodeType() {
-            return ATTRIBUTE_NODE;
-        }
-    }
-
-    /**
-     * The Class IIOMetadataNodeList.
-     */
-    private class IIOMetadataNodeList implements NodeList, NamedNodeMap {
-
-        /**
-         * The list.
-         */
-        private List<IIOMetadataNode> list;
-
-        /**
-         * Instantiates a new iIO metadata node list.
-         * 
-         * @param list
-         *            the list.
-         */
-        IIOMetadataNodeList(List<IIOMetadataNode> list) {
-            this.list = list;
-        }
-
-        public Node item(int index) {
-            try {
-                return list.get(index);
-            } catch (IndexOutOfBoundsException e) {
-                return null;
-            }
-        }
-
-        public int getLength() {
-            return list.size();
-        }
-
-        public Node getNamedItem(String name) {
-            for (IIOMetadataNode node : list) {
-                if (name.equals(node.getNodeName())) {
-                    return node;
-                }
-            }
-            return null;
-        }
-
-        public Node setNamedItem(Node arg) throws DOMException {
-            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                    "This NamedNodeMap is read-only!");
-        }
-
-        public Node removeNamedItem(String name) throws DOMException {
-            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                    "This NamedNodeMap is read-only!");
-        }
-
-        public Node getNamedItemNS(String namespaceURI, String localName) throws DOMException {
-            return getNamedItem(localName);
-        }
-
-        public Node setNamedItemNS(Node arg) throws DOMException {
-            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                    "This NamedNodeMap is read-only!");
-        }
-
-        public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException {
-            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                    "This NamedNodeMap is read-only!");
-        }
-    }
-}
diff --git a/awt/javax/imageio/metadata/IIOStandardMetadataFormat.java b/awt/javax/imageio/metadata/IIOStandardMetadataFormat.java
deleted file mode 100644
index 706cb2f..0000000
--- a/awt/javax/imageio/metadata/IIOStandardMetadataFormat.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.metadata;
-
-import javax.imageio.ImageTypeSpecifier;
-import java.util.ArrayList;
-
-/**
- * The class IIOStandardMetadataFormat describes the rules of the standard
- * metadata format.
- * 
- * @since Android 1.0
- */
-class IIOStandardMetadataFormat extends IIOMetadataFormatImpl {
-
-    /**
-     * Instantiates a new IIOStandardMetadataFormat.
-     */
-    public IIOStandardMetadataFormat() {
-        super(standardMetadataFormatName, CHILD_POLICY_SOME);
-        buildDTD();
-    }
-
-    @Override
-    public boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType) {
-        return true;
-    }
-
-    /**
-     * Builds the DTD that describes the standard metadata format.
-     */
-    private void buildDTD() {
-        // CHROMA
-        addElement("Chroma", standardMetadataFormatName, CHILD_POLICY_SOME);
-
-        addElement("ColorSpaceType", "Chroma", CHILD_POLICY_EMPTY);
-
-        ArrayList<String> values = new ArrayList<String>(27);
-        values.add("XYZ");
-        values.add("Lab");
-        values.add("Luv");
-        values.add("YCbCr");
-        values.add("Yxy");
-        values.add("YCCK");
-        values.add("PhotoYCC");
-        values.add("RGB");
-        values.add("GRAY");
-        values.add("HSV");
-        values.add("HLS");
-        values.add("CMYK");
-        values.add("CMY");
-        values.add("2CLR");
-        values.add("3CLR");
-        values.add("4CLR");
-        values.add("5CLR");
-        values.add("6CLR");
-        values.add("7CLR");
-        values.add("8CLR");
-        values.add("9CLR");
-        values.add("ACLR");
-        values.add("BCLR");
-        values.add("CCLR");
-        values.add("DCLR");
-        values.add("ECLR");
-        values.add("FCLR");
-        addAttribute("ColorSpaceType", "name", DATATYPE_STRING, true, null, values);
-
-        addElement("NumChannels", "Chroma", CHILD_POLICY_EMPTY);
-        addAttribute("NumChannels", "value", DATATYPE_INTEGER, true, 0, Integer.MAX_VALUE); // list
-        // -
-        // why
-        // ?
-
-        addElement("Gamma", "Chroma", CHILD_POLICY_EMPTY);
-        addAttribute("Gamma", "value", DATATYPE_FLOAT, true, null);
-
-        addElement("BlackIsZero", "Chroma", CHILD_POLICY_EMPTY);
-        addBooleanAttribute("BlackIsZero", "value", true, true);
-
-        addElement("Palette", "Chroma", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
-        addElement("PaletteEntry", "Palette", CHILD_POLICY_EMPTY);
-        addAttribute("PaletteEntry", "index", DATATYPE_INTEGER, true, null);
-        addAttribute("PaletteEntry", "red", DATATYPE_INTEGER, true, null);
-        addAttribute("PaletteEntry", "green", DATATYPE_INTEGER, true, null);
-        addAttribute("PaletteEntry", "blue", DATATYPE_INTEGER, true, null);
-        addAttribute("PaletteEntry", "alpha", DATATYPE_INTEGER, false, "255");
-
-        addElement("BackgroundIndex", "Chroma", CHILD_POLICY_EMPTY);
-        addAttribute("BackgroundIndex", "value", DATATYPE_INTEGER, true, null);
-
-        addElement("BackgroundColor", "Chroma", CHILD_POLICY_EMPTY);
-        addAttribute("BackgroundColor", "red", DATATYPE_INTEGER, true, null);
-        addAttribute("BackgroundColor", "green", DATATYPE_INTEGER, true, null);
-        addAttribute("BackgroundColor", "blue", DATATYPE_INTEGER, true, null);
-
-        // COMPRESSION
-        addElement("Compression", standardMetadataFormatName, CHILD_POLICY_SOME);
-
-        addElement("CompressionTypeName", "Compression", CHILD_POLICY_EMPTY);
-        addAttribute("CompressionTypeName", "value", DATATYPE_STRING, true, null);
-
-        addElement("Lossless", "Compression", CHILD_POLICY_EMPTY);
-        addBooleanAttribute("Lossless", "value", true, true);
-
-        addElement("NumProgressiveScans", "Compression", CHILD_POLICY_EMPTY);
-        addAttribute("NumProgressiveScans", "value", DATATYPE_INTEGER, true, null);
-
-        addElement("BitRate", "Compression", CHILD_POLICY_EMPTY);
-        addAttribute("BitRate", "value", DATATYPE_FLOAT, true, null);
-
-        // DATA
-        addElement("Data", standardMetadataFormatName, CHILD_POLICY_SOME);
-
-        addElement("PlanarConfiguration", "Data", CHILD_POLICY_EMPTY);
-        values = new ArrayList<String>(4);
-        values.add("PixelInterleaved");
-        values.add("PlaneInterleaved");
-        values.add("LineInterleaved");
-        values.add("TileInterleaved");
-        addAttribute("PlanarConfiguration", "value", DATATYPE_STRING, true, null, values);
-
-        addElement("SampleFormat", "Data", CHILD_POLICY_EMPTY);
-        values = new ArrayList<String>(4);
-        values.add("SignedIntegral");
-        values.add("UnsignedIntegral");
-        values.add("Real");
-        values.add("Index");
-        addAttribute("SampleFormat", "value", DATATYPE_STRING, true, null, values);
-
-        addElement("BitsPerSample", "Data", CHILD_POLICY_EMPTY);
-        addAttribute("BitsPerSample", "value", DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE); // list
-
-        addElement("SignificantBitsPerSample", "Data", CHILD_POLICY_EMPTY);
-        addAttribute("SignificantBitsPerSample", "value", DATATYPE_INTEGER, true, 1,
-                Integer.MAX_VALUE); // list
-
-        addElement("SampleMSB", "Data", CHILD_POLICY_EMPTY);
-        addAttribute("SampleMSB", "value", DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE); // list
-
-        // DIMENSION
-        addElement("Dimension", standardMetadataFormatName, CHILD_POLICY_SOME);
-
-        addElement("PixelAspectRatio", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("PixelAspectRatio", "value", DATATYPE_FLOAT, true, null);
-
-        addElement("ImageOrientation", "Dimension", CHILD_POLICY_EMPTY);
-        values = new ArrayList<String>(8);
-        values.add("Normal");
-        values.add("Rotate90");
-        values.add("Rotate180");
-        values.add("Rotate270");
-        values.add("FlipH");
-        values.add("FlipV");
-        values.add("FlipHRotate90");
-        values.add("FlipVRotate90");
-        addAttribute("ImageOrientation", "value", DATATYPE_STRING, true, null, values);
-
-        addElement("HorizontalPixelSize", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("HorizontalPixelSize", "value", DATATYPE_FLOAT, true, null);
-
-        addElement("VerticalPixelSize", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("VerticalPixelSize", "value", DATATYPE_FLOAT, true, null);
-
-        addElement("HorizontalPhysicalPixelSpacing", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("HorizontalPhysicalPixelSpacing", "value", DATATYPE_FLOAT, true, null);
-
-        addElement("VerticalPhysicalPixelSpacing", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("VerticalPhysicalPixelSpacing", "value", DATATYPE_FLOAT, true, null);
-
-        addElement("HorizontalPosition", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("HorizontalPosition", "value", DATATYPE_FLOAT, true, null);
-
-        addElement("VerticalPosition", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("VerticalPosition", "value", DATATYPE_FLOAT, true, null);
-
-        addElement("HorizontalPixelOffset", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("HorizontalPixelOffset", "value", DATATYPE_INTEGER, true, null);
-
-        addElement("VerticalPixelOffset", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("VerticalPixelOffset", "value", DATATYPE_INTEGER, true, null);
-
-        addElement("HorizontalScreenSize", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("HorizontalScreenSize", "value", DATATYPE_INTEGER, true, null);
-
-        addElement("VerticalScreenSize", "Dimension", CHILD_POLICY_EMPTY);
-        addAttribute("VerticalScreenSize", "value", DATATYPE_INTEGER, true, null);
-
-        // DOCUMENT
-        addElement("Document", standardMetadataFormatName, CHILD_POLICY_SOME);
-
-        addElement("FormatVersion", "Document", CHILD_POLICY_EMPTY);
-        addAttribute("FormatVersion", "value", DATATYPE_STRING, true, null);
-
-        addElement("SubimageInterpretation", "Document", CHILD_POLICY_EMPTY);
-        values = new ArrayList<String>(14);
-        values.add("Standalone");
-        values.add("SinglePage");
-        values.add("FullResolution");
-        values.add("ReducedResolution");
-        values.add("PyramidLayer");
-        values.add("Preview");
-        values.add("VolumeSlice");
-        values.add("ObjectView");
-        values.add("Panorama");
-        values.add("AnimationFrame");
-        values.add("TransparencyMask");
-        values.add("CompositingLayer");
-        values.add("SpectralSlice");
-        values.add("Unknown");
-        addAttribute("SubimageInterpretation", "value", DATATYPE_STRING, true, null, values);
-
-        addElement("ImageCreationTime", "Document", CHILD_POLICY_EMPTY);
-        addAttribute("ImageCreationTime", "year", DATATYPE_INTEGER, true, null);
-        addAttribute("ImageCreationTime", "month", DATATYPE_INTEGER, true, null, "1", "12", true,
-                true);
-        addAttribute("ImageCreationTime", "day", DATATYPE_INTEGER, true, null, "1", "31", true,
-                true);
-        addAttribute("ImageCreationTime", "hour", DATATYPE_INTEGER, false, "0", "0", "23", true,
-                true);
-        addAttribute("ImageCreationTime", "minute", DATATYPE_INTEGER, false, "0", "0", "59", true,
-                true);
-        addAttribute("ImageCreationTime", "second", DATATYPE_INTEGER, false, "0", "0", "60", true,
-                true);
-
-        addElement("ImageModificationTime", "Document", CHILD_POLICY_EMPTY);
-        addAttribute("ImageModificationTime", "year", DATATYPE_INTEGER, true, null);
-        addAttribute("ImageModificationTime", "month", DATATYPE_INTEGER, true, null, "1", "12",
-                true, true);
-        addAttribute("ImageModificationTime", "day", DATATYPE_INTEGER, true, null, "1", "31", true,
-                true);
-        addAttribute("ImageModificationTime", "hour", DATATYPE_INTEGER, false, "0", "0", "23",
-                true, true);
-        addAttribute("ImageModificationTime", "minute", DATATYPE_INTEGER, false, "0", "0", "59",
-                true, true);
-        addAttribute("ImageModificationTime", "second", DATATYPE_INTEGER, false, "0", "0", "60",
-                true, true);
-
-        // TEXT
-        addElement("Text", standardMetadataFormatName, 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
-
-        addElement("TextEntry", "Text", CHILD_POLICY_EMPTY);
-        addAttribute("TextEntry", "keyword", DATATYPE_STRING, false, null);
-        addAttribute("TextEntry", "value", DATATYPE_STRING, true, null);
-        addAttribute("TextEntry", "language", DATATYPE_STRING, false, null);
-        addAttribute("TextEntry", "encoding", DATATYPE_STRING, false, null);
-        values = new ArrayList<String>(5);
-        values.add("none");
-        values.add("lzw");
-        values.add("zip");
-        values.add("bzip");
-        values.add("other");
-        addAttribute("TextEntry", "compression", DATATYPE_STRING, false, "none", values);
-
-        // TRANSPARENCY
-        addElement("Transparency", standardMetadataFormatName, CHILD_POLICY_SOME);
-
-        addElement("Alpha", "Transparency", CHILD_POLICY_EMPTY);
-        values = new ArrayList<String>(3);
-        values.add("none");
-        values.add("premultiplied");
-        values.add("nonpremultiplied");
-        addAttribute("Alpha", "value", DATATYPE_STRING, false, "none", values);
-
-        addElement("TransparentIndex", "Transparency", CHILD_POLICY_EMPTY);
-        addAttribute("TransparentIndex", "value", DATATYPE_INTEGER, true, null);
-
-        addElement("TransparentColor", "Transparency", CHILD_POLICY_EMPTY);
-        addAttribute("TransparentColor", "value", DATATYPE_INTEGER, true, 0, Integer.MAX_VALUE);
-
-        addElement("TileTransparencies", "Transparency", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
-
-        addElement("TransparentTile", "TileTransparencies", CHILD_POLICY_EMPTY);
-        addAttribute("TransparentTile", "x", DATATYPE_INTEGER, true, null);
-        addAttribute("TransparentTile", "y", DATATYPE_INTEGER, true, null);
-
-        addElement("TileOpacities", "Transparency", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
-
-        addElement("OpaqueTile", "TileOpacities", CHILD_POLICY_EMPTY);
-        addAttribute("OpaqueTile", "x", DATATYPE_INTEGER, true, null);
-        addAttribute("OpaqueTile", "y", DATATYPE_INTEGER, true, null);
-    }
-}
diff --git a/awt/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties b/awt/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties
deleted file mode 100644
index d185808..0000000
--- a/awt/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties
+++ /dev/null
@@ -1,133 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-# Descriptions of elements and attributes of the plugin neutral metadata format
-# (see IIOStandardMetadataFormat)
-
-# Messages for EN locale
-Chroma=Chroma (color) information
-ColorSpaceType=The raw color space of the image
-ColorSpaceType/name=The raw color space of the image
-NumChannels=The number of channels in the raw image, including alpha
-NumChannels/value=The number of channels in the raw image, including alpha
-Gamma=The image gamma
-Gamma/value=The image gamma
-BlackIsZero=True if smaller values represent darker shades
-BlackIsZero/value=True if smaller values represent darker shades
-Palette=Palette-color information
-PaletteEntry=A palette entry
-PaletteEntry/index=The index of the palette entry
-PaletteEntry/red=The red value for the palette entry
-PaletteEntry/green=The green value for the palette entry
-PaletteEntry/blue=The blue value for the palette entry
-PaletteEntry/alpha=The alpha value for the palette entry
-BackgroundIndex=A palette index to be used as a background
-BackgroundIndex/value=A palette index to be used as a background
-BackgroundColor=An RGB triple to be used as a background
-BackgroundColor/red=The red background value
-BackgroundColor/green=The green background value
-BackgroundColor/blue=The blue background value
-
-Compression=Compression information
-CompressionTypeName=The name of the compression scheme in use
-CompressionTypeName/value=The name of the compression scheme in use
-Lossless=True if the compression scheme is lossless
-Lossless/value=True if the compression scheme is lossless
-NumProgressiveScans=The number of progressive scans used in the image encoding
-NumProgressiveScans/value=The number of progressive scans used in the image encoding
-BitRate=The estimated bit rate of the compression scheme
-BitRate/value=The estimated bit rate of the compression scheme
-
-Data=Information on the image layout
-PlanarConfiguration=The organization of image samples in the stream
-PlanarConfiguration/value=The organization of image samples in the stream
-SampleFormat=The numeric format of image samples
-SampleFormat/value=The numeric format of image samples
-BitsPerSample=The number of bits per sample
-BitsPerSample/value=A list of integers, one per channel
-SignificantBitsPerSample=The number of significant bits per sample
-SignificantBitsPerSample/value=A list of integers, one per channel
-SampleMSB=The position of the most significant bit of each sample
-SampleMSB/value=A list of integers, one per channel
-
-Dimension=Dimension information
-PixelAspectRatio=The width of a pixel divided by its height
-PixelAspectRatio/value=The width of a pixel divided by its height
-ImageOrientation=The desired orientation of the image in terms of flips and counter-clockwise rotations
-ImageOrientation/value=The desired orientation of the image in terms of flips and counter-clockwise rotations
-HorizontalPixelSize=The width of a pixel, in millimeters, as it should be rendered on media
-HorizontalPixelSize/value=The width of a pixel, in millimeters, as it should be rendered on media
-VerticalPixelSize=The height of a pixel, in millimeters, as it should be rendered on media
-VerticalPixelSize/value=The height of a pixel, in millimeters, as it should be rendered on media
-HorizontalPhysicalPixelSpacing=The horizontal distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
-HorizontalPhysicalPixelSpacing/value=The horizontal distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
-VerticalPhysicalPixelSpacing=The vertical distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
-VerticalPhysicalPixelSpacing/value=The vertical distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
-HorizontalPosition=The horizontal position, in millimeters, where the image should be rendered on media
-HorizontalPosition/value=The horizontal position, in millimeters, where the image should be rendered on media
-VerticalPosition=The vertical position, in millimeters, where the image should be rendered on media
-VerticalPosition/value=The vertical position, in millimeters, where the image should be rendered on media
-HorizontalPixelOffset=The horizonal position, in pixels, where the image should be rendered onto a raster display
-HorizontalPixelOffset/value=The horizonal position, in pixels, where the image should be rendered onto a raster display
-VerticalPixelOffset=The vertical position, in pixels, where the image should be rendered onto a raster display
-VerticalPixelOffset/value=The vertical position, in pixels, where the image should be rendered onto a raster display
-HorizontalScreenSize=The width, in pixels, of the raster display into which the image should be rendered
-HorizontalScreenSize/value=The width, in pixels, of the raster display into which the image should be rendered
-VerticalScreenSize=The height, in pixels, of the raster display into which the image should be rendered
-VerticalScreenSize/value=The height, in pixels, of the raster display into which the image should be rendered
-
-Document=Document information
-FormatVersion=The version of the format used by the stream
-FormatVersion/value=The version of the format used by the stream
-SubimageInterpretation=The interpretation of this image in relation to the other images stored in the same stream
-SubimageInterpretation/value=The interpretation of this image in relation to the other images stored in the same stream
-ImageCreationTime=The time of image creation
-ImageCreationTime/year=The full year (e.g., 1967, not 67)
-ImageCreationTime/month=The month, with January = 1
-ImageCreationTime/day=The day of the month
-ImageCreationTime/hour=The hour from 0 to 23
-ImageCreationTime/minute=The minute from 0 to 59
-ImageCreationTime/second=The second from 0 to 60 (60 = leap second)
-ImageModificationTime=The time of the last image modification
-ImageModificationTime/year=The full year (e.g., 1967, not 67)
-ImageModificationTime/month=The month, with January = 1
-ImageModificationTime/day=The day of the month
-ImageModificationTime/hour=The hour from 0 to 23
-ImageModificationTime/minute=The minute from 0 to 59
-ImageModificationTime/second=The second from 0 to 60 (60 = leap second)
-
-Text=Text information
-TextEntry=A text entry
-TextEntry/keyword=A keyword associated with the text entry
-TextEntry/value=the text entry
-TextEntry/language=The language of the text
-TextEntry/encoding=The encoding of the text
-TextEntry/compression=The method used to compress the text
-
-Transparency=Transparency information
-Alpha=The type of alpha information contained in the image
-Alpha/value=The type of alpha information contained in the image
-TransparentIndex=A palette index to be treated as transparent
-TransparentIndex/value=A palette index to be treated as transparent
-TransparentColor=An RGB color to be treated as transparent
-TransparentColor/value=An RGB color to be treated as transparent
-TileTransparencies=A list of completely transparent tiles
-TransparentTile=The index of a completely transparent tile
-TransparentTile/x=The tile's X index
-TransparentTile/y=The tile's Y index
-TileOpacities=A list of completely opaque tiles
-OpaqueTile=The index of a completely opaque tile
-OpaqueTile/x=The tile's X index
-OpaqueTile/y=The tile's Y index
diff --git a/awt/javax/imageio/metadata/package.html b/awt/javax/imageio/metadata/package.html
deleted file mode 100644
index 29bd51b..0000000
--- a/awt/javax/imageio/metadata/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes which allows to read and write describing metadata of image files.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/package.html b/awt/javax/imageio/package.html
deleted file mode 100644
index 2fd6148..0000000
--- a/awt/javax/imageio/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes and interfaces which provides an Image I/O API. The contained classes and interfaces allow reading and writing image files of different formats.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java b/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java
deleted file mode 100644
index ecfb20a..0000000
--- a/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.plugins.bmp;
-
-import javax.imageio.ImageWriteParam;
-import java.util.Locale;
-
-/**
- * The BMPImageWriteParam class allows encoding an image in BMP format.
- * 
- * @since Android 1.0
- */
-public class BMPImageWriteParam extends ImageWriteParam {
-
-    /**
-     * The top down.
-     */
-    private boolean topDown; // Default is bottom-up
-
-    /**
-     * Instantiates a new BMPImageWriteParam with default values of all
-     * parameters.
-     */
-    public BMPImageWriteParam() {
-        this(null);
-    }
-
-    /**
-     * Instantiates a new BMPImageWriteParam with the specified Locale.
-     * 
-     * @param locale
-     *            the specified Locale.
-     */
-    public BMPImageWriteParam(Locale locale) {
-        super(locale);
-
-        // Set the compression
-        canWriteCompressed = true;
-        compressionTypes = new String[] {
-                "BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS"
-        };
-        compressionType = compressionTypes[0];
-    }
-
-    /**
-     * Sets true if the data will be written in a top-down order, false
-     * otherwise.
-     * 
-     * @param topDown
-     *            the new top-down value.
-     */
-    public void setTopDown(boolean topDown) {
-        this.topDown = topDown;
-    }
-
-    /**
-     * Returns true if the data is written in top-down order, false otherwise.
-     * 
-     * @return true if the data is written in top-down order, false otherwise.
-     */
-    public boolean isTopDown() {
-        return topDown;
-    }
-}
diff --git a/awt/javax/imageio/plugins/bmp/package.html b/awt/javax/imageio/plugins/bmp/package.html
deleted file mode 100644
index 9494a102..0000000
--- a/awt/javax/imageio/plugins/bmp/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains auxiliary classes for the built-in BMP image plug-in.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java b/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
deleted file mode 100644
index 67b504b..0000000
--- a/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.plugins.jpeg;
-
-/**
- * The JPEGHuffmanTable class represents a single JPEG Huffman table. It
- * contains the standard tables from the JPEG specification.
- * 
- * @since Android 1.0
- */
-public class JPEGHuffmanTable {
-
-    /**
-     * The standard DC luminance Huffman table .
-     */
-    public static final JPEGHuffmanTable StdDCLuminance = new JPEGHuffmanTable(new short[] {
-            0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
-    }, new short[] {
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0A, 0x0B
-    }, false);
-
-    /**
-     * The standard DC chrominance Huffman table.
-     */
-    public static final JPEGHuffmanTable StdDCChrominance = new JPEGHuffmanTable(new short[] {
-            0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
-    }, new short[] {
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0A, 0x0B
-    }, false);
-
-    /**
-     * The standard AC luminance Huffman table.
-     */
-    public static final JPEGHuffmanTable StdACLuminance = new JPEGHuffmanTable(new short[] {
-            0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7D
-    }, new short[] {
-            0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51,
-            0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1,
-            0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18,
-            0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-            0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,
-            0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75,
-            0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92,
-            0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
-            0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3,
-            0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
-            0xD9, 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2,
-            0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
-    }, false);
-
-    /**
-     * The standard AC chrominance Huffman table.
-     */
-    public static final JPEGHuffmanTable StdACChrominance = new JPEGHuffmanTable(new short[] {
-            0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
-    }, new short[] {
-            0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07,
-            0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09,
-            0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
-            0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38,
-            0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
-            0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74,
-            0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
-            0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5,
-            0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA,
-            0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
-            0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2,
-            0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
-    }, false);
-
-    /**
-     * The lengths.
-     */
-    private short lengths[];
-
-    /**
-     * The values.
-     */
-    private short values[];
-
-    /**
-     * Instantiates a new jPEG huffman table.
-     * 
-     * @param lengths
-     *            the lengths
-     * @param values
-     *            the values
-     * @param copy
-     *            the copy
-     */
-    JPEGHuffmanTable(short[] lengths, short[] values, boolean copy) {
-        // Construction of standard tables without checks
-        // The third param is dummy
-        // Could be also used for copying of the existing tables
-        this.lengths = lengths;
-        this.values = values;
-    }
-
-    /**
-     * Instantiates a new JPEGHuffmanTable.
-     * 
-     * @param lengths
-     *            the array of shorts lengths.
-     * @param values
-     *            the array of shorts containing the values in order of
-     *            increasing code length.
-     */
-    public JPEGHuffmanTable(short[] lengths, short[] values) {
-        if (lengths == null) {
-            throw new IllegalArgumentException("lengths array is null!");
-        }
-        if (values == null) {
-            throw new IllegalArgumentException("values array is null!");
-        }
-        if (lengths.length > 16) { // According to the spec
-            throw new IllegalArgumentException("lengths array is too long!");
-        }
-        if (values.length > 256) { // According to the spec
-            throw new IllegalArgumentException("values array is too long");
-        }
-        for (short length : lengths) {
-            if (length < 0) {
-                throw new IllegalArgumentException("Values in lengths array must be non-negative.");
-            }
-        }
-        for (short value : values) {
-            if (value < 0) {
-                throw new IllegalArgumentException("Values in values array must be non-negative.");
-            }
-        }
-
-        checkHuffmanTable(lengths, values);
-
-        this.lengths = new short[lengths.length];
-        this.values = new short[values.length];
-        System.arraycopy(lengths, 0, this.lengths, 0, lengths.length);
-        System.arraycopy(values, 0, this.values, 0, values.length);
-    }
-
-    /**
-     * Gets an array of lengths in the Huffman table.
-     * 
-     * @return the array of short values representing the length values in the
-     *         Huffman table.
-     */
-    public short[] getLengths() {
-        short newLengths[] = new short[lengths.length];
-        System.arraycopy(lengths, 0, newLengths, 0, lengths.length);
-        return newLengths;
-    }
-
-    /**
-     * Gets an array of values represented by increasing length of their codes.
-     * 
-     * @return the array of values.
-     */
-    public short[] getValues() {
-        short newValues[] = new short[values.length];
-        System.arraycopy(values, 0, newValues, 0, values.length);
-        return newValues;
-    }
-
-    /**
-     * Check huffman table.
-     * 
-     * @param lengths
-     *            the lengths.
-     * @param values
-     *            the values.
-     */
-    private static void checkHuffmanTable(short[] lengths, short[] values) {
-        int numLeaves = 0;
-        int possibleLeaves = 2;
-        for (short length : lengths) {
-            numLeaves += length;
-            possibleLeaves -= length;
-            if (possibleLeaves < 0) {
-                throw new IllegalArgumentException(
-                        "Invalid Huffman table provided, lengths are incorrect.");
-            }
-            possibleLeaves <<= 1;
-        }
-
-        if (values.length != numLeaves) {
-            throw new IllegalArgumentException(
-                    "Invalid Huffman table provided, sum of lengths != values.");
-        }
-    }
-
-    /**
-     * Returns the string representation of this JPEGHuffmanTable object.
-     * 
-     * @return the string representation of this JPEGHuffmanTable object.
-     */
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-
-        sb.append("JPEGHuffmanTable:\nlengths:");
-        for (short length : lengths) {
-            sb.append(' ').append(length);
-        }
-
-        sb.append("\nvalues:");
-        for (short value : values) {
-            sb.append(' ').append(value);
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGImageReadParam.java b/awt/javax/imageio/plugins/jpeg/JPEGImageReadParam.java
deleted file mode 100644
index 2f3a9a8..0000000
--- a/awt/javax/imageio/plugins/jpeg/JPEGImageReadParam.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.plugins.jpeg;
-
-import javax.imageio.ImageReadParam;
-
-/**
- * The JPEGImageReadParam class provides functionality to set Huffman tables and
- * quantization tables when using the JPEG reader plug-in.
- * 
- * @since Android 1.0
- */
-public class JPEGImageReadParam extends ImageReadParam {
-
-    /**
-     * The q tables.
-     */
-    private JPEGQTable qTables[];
-
-    /**
-     * The dc huffman tables.
-     */
-    private JPEGHuffmanTable dcHuffmanTables[];
-
-    /**
-     * The ac huffman tables.
-     */
-    private JPEGHuffmanTable acHuffmanTables[];
-
-    /**
-     * Instantiates a new JPEGImageReadParam.
-     */
-    public JPEGImageReadParam() {
-    }
-
-    /**
-     * Returns true if tables are set, false otherwise.
-     * 
-     * @return true, if tables are set, false otherwise.
-     */
-    public boolean areTablesSet() {
-        return qTables != null;
-    }
-
-    /**
-     * Sets the quantization and Huffman tables for using in decoding streams.
-     * 
-     * @param qTables
-     *            the quantization tables.
-     * @param DCHuffmanTables
-     *            the standart DC Huffman tables.
-     * @param ACHuffmanTables
-     *            the standart AC huffman tables.
-     */
-    public void setDecodeTables(JPEGQTable[] qTables, JPEGHuffmanTable[] DCHuffmanTables,
-            JPEGHuffmanTable[] ACHuffmanTables) {
-        if (qTables == null || DCHuffmanTables == null || ACHuffmanTables == null) {
-            throw new IllegalArgumentException("Invalid JPEG table arrays");
-        }
-        if (DCHuffmanTables.length != ACHuffmanTables.length) {
-            throw new IllegalArgumentException("Invalid JPEG table arrays");
-        }
-        if (qTables.length > 4 || DCHuffmanTables.length > 4) {
-            throw new IllegalArgumentException("Invalid JPEG table arrays");
-        }
-
-        // Do the shallow copy, it should be enough
-        this.qTables = qTables.clone();
-        dcHuffmanTables = DCHuffmanTables.clone();
-        acHuffmanTables = ACHuffmanTables.clone();
-    }
-
-    /**
-     * Unset all decoded tables.
-     */
-    public void unsetDecodeTables() {
-        qTables = null;
-        dcHuffmanTables = null;
-        acHuffmanTables = null;
-    }
-
-    /**
-     * Gets the quantization tables.
-     * 
-     * @return the quantization tables, or null.
-     */
-    public JPEGQTable[] getQTables() {
-        return qTables == null ? null : qTables.clone();
-    }
-
-    /**
-     * Gets the DC Huffman tables.
-     * 
-     * @return the DC Huffman tables which are set, or null.
-     */
-    public JPEGHuffmanTable[] getDCHuffmanTables() {
-        return dcHuffmanTables == null ? null : dcHuffmanTables.clone();
-    }
-
-    /**
-     * Gets the AC Huffman tables.
-     * 
-     * @return the AC Huffman tables which are set, or null.
-     */
-    public JPEGHuffmanTable[] getACHuffmanTables() {
-        return acHuffmanTables == null ? null : acHuffmanTables.clone();
-    }
-}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java b/awt/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java
deleted file mode 100644
index b979911..0000000
--- a/awt/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.plugins.jpeg;
-
-import org.apache.harmony.x.imageio.plugins.jpeg.JPEGConsts;
-
-import javax.imageio.ImageWriteParam;
-import java.util.Locale;
-
-/**
- * The JPEGImageWriteParam class allows to set JPEG Huffman tables and
- * quantization when using the JPEG writer plug-in.
- * 
- * @since Android 1.0
- */
-public class JPEGImageWriteParam extends ImageWriteParam {
-
-    /**
-     * The Constant COMP_QUALITY_VALUES.
-     */
-    private static final float[] COMP_QUALITY_VALUES = {
-            0.05f, 0.75f, 0.95f
-    };
-
-    /**
-     * The Constant COMP_QUALITY_DESCRIPTIONS.
-     */
-    private static final String[] COMP_QUALITY_DESCRIPTIONS = {
-            "Minimum useful", "Visually lossless", "Maximum useful"
-    };
-
-    /**
-     * The q tables.
-     */
-    private JPEGQTable[] qTables;
-
-    /**
-     * The dc huffman tables.
-     */
-    private JPEGHuffmanTable[] dcHuffmanTables;
-
-    /**
-     * The ac huffman tables.
-     */
-    private JPEGHuffmanTable[] acHuffmanTables;
-
-    /**
-     * The optimize huffman tables.
-     */
-    private boolean optimizeHuffmanTables;
-
-    /**
-     * Instantiates a new JPEGImageWriteParam object with the specified Locale.
-     * 
-     * @param locale
-     *            the Locale.
-     */
-    public JPEGImageWriteParam(Locale locale) {
-        super(locale);
-
-        canWriteProgressive = true;
-        progressiveMode = ImageWriteParam.MODE_DISABLED;
-
-        canWriteCompressed = true;
-        compressionTypes = new String[] {
-            "JPEG"
-        };
-        compressionType = compressionTypes[0];
-        compressionQuality = JPEGConsts.DEFAULT_JPEG_COMPRESSION_QUALITY;
-    }
-
-    /**
-     * Returns true if tables are set, false otherwise.
-     * 
-     * @return true, if tables are set, false otherwise.
-     */
-    public boolean areTablesSet() {
-        return qTables != null;
-    }
-
-    /**
-     * Sets the quantization and Huffman tables for using in encoding streams.
-     * 
-     * @param qTables
-     *            the quantization tables.
-     * @param DCHuffmanTables
-     *            the standart DC Huffman tables.
-     * @param ACHuffmanTables
-     *            the standart AC huffman tables.
-     */
-    public void setEncodeTables(JPEGQTable[] qTables, JPEGHuffmanTable[] DCHuffmanTables,
-            JPEGHuffmanTable[] ACHuffmanTables) {
-        if (qTables == null || DCHuffmanTables == null || ACHuffmanTables == null) {
-            throw new IllegalArgumentException("Invalid JPEG table arrays");
-        }
-        if (DCHuffmanTables.length != ACHuffmanTables.length) {
-            throw new IllegalArgumentException("Invalid JPEG table arrays");
-        }
-        if (qTables.length > 4 || DCHuffmanTables.length > 4) {
-            throw new IllegalArgumentException("Invalid JPEG table arrays");
-        }
-
-        // Do the shallow copy, it should be enough
-        this.qTables = qTables.clone();
-        dcHuffmanTables = DCHuffmanTables.clone();
-        acHuffmanTables = ACHuffmanTables.clone();
-    }
-
-    /**
-     * Unset all encoded tables.
-     */
-    public void unsetEncodeTables() {
-        qTables = null;
-        dcHuffmanTables = null;
-        acHuffmanTables = null;
-    }
-
-    /**
-     * Gets the DC Huffman tables.
-     * 
-     * @return the DC Huffman tables which are set, or null.
-     */
-    public JPEGHuffmanTable[] getDCHuffmanTables() {
-        return dcHuffmanTables == null ? null : dcHuffmanTables.clone();
-    }
-
-    /**
-     * Gets the AC Huffman tables.
-     * 
-     * @return the AC Huffman tables which are set, or null.
-     */
-    public JPEGHuffmanTable[] getACHuffmanTables() {
-        return acHuffmanTables == null ? null : acHuffmanTables.clone();
-    }
-
-    /**
-     * Gets the quantization tables.
-     * 
-     * @return the quantization tables, or null.
-     */
-    public JPEGQTable[] getQTables() {
-        return qTables == null ? null : qTables.clone();
-    }
-
-    @Override
-    public String[] getCompressionQualityDescriptions() {
-        super.getCompressionQualityDescriptions();
-        return COMP_QUALITY_DESCRIPTIONS.clone();
-    }
-
-    @Override
-    public float[] getCompressionQualityValues() {
-        super.getCompressionQualityValues();
-        return COMP_QUALITY_VALUES.clone();
-    }
-
-    /**
-     * Sets the flag indicated that the writer will generate optimized Huffman
-     * tables for the image as part of the writing process.
-     * 
-     * @param optimize
-     *            the flag of optimizing huffman tables.
-     */
-    public void setOptimizeHuffmanTables(boolean optimize) {
-        optimizeHuffmanTables = optimize;
-    }
-
-    /**
-     * Returns true if the writer generates optimized Huffman tables, false
-     * otherwise.
-     * 
-     * @return true, if the writer generates optimized Huffman tables, false
-     *         otherwise.
-     */
-    public boolean getOptimizeHuffmanTables() {
-        return optimizeHuffmanTables;
-    }
-
-    @Override
-    public boolean isCompressionLossless() {
-        if (getCompressionMode() != MODE_EXPLICIT) {
-            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
-        }
-        return false;
-    }
-
-    @Override
-    public void unsetCompression() {
-        if (getCompressionMode() != MODE_EXPLICIT) {
-            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
-        }
-        compressionQuality = JPEGConsts.DEFAULT_JPEG_COMPRESSION_QUALITY;
-    }
-}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGQTable.java b/awt/javax/imageio/plugins/jpeg/JPEGQTable.java
deleted file mode 100644
index 3461d46..0000000
--- a/awt/javax/imageio/plugins/jpeg/JPEGQTable.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.plugins.jpeg;
-
-/**
- * The JPEGQTable class represents a single JPEG quantization table and provides
- * for the standard tables taken from the JPEG specification.
- * 
- * @since Android 1.0
- */
-public class JPEGQTable {
-
-    /**
-     * The Constant SIZE.
-     */
-    private final static int SIZE = 64;
-
-    /**
-     * The Constant BASELINE_MAX.
-     */
-    private final static int BASELINE_MAX = 255;
-
-    /**
-     * The Constant MAX.
-     */
-    private final static int MAX = 32767;
-
-    /**
-     * The table.
-     */
-    private int[] theTable;
-
-    /*
-     * K1 & K2 tables can be found in the JPEG format specification at
-     * http://www.w3.org/Graphics/JPEG/itu-t81.pdf
-     */
-
-    /**
-     * The Constant K1LumTable.
-     */
-    private static final int[] K1LumTable = new int[] {
-            16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57,
-            69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55,
-            64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100,
-            103, 99
-    };
-
-    /**
-     * The Constant K2ChrTable.
-     */
-    private static final int[] K2ChrTable = new int[] {
-            17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99,
-            99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-            99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99
-    };
-
-    /**
-     * The K1Luminance indicates standard table K.1 from JPEG specification and
-     * produces "good" quality output.
-     */
-    public static final JPEGQTable K1Luminance = new JPEGQTable(K1LumTable);
-
-    /**
-     * The K1Div2Luminance indicates K.1 table from JPEG specification with all
-     * elements divided by 2 and produces "very good" quality output.
-     */
-    public static final JPEGQTable K1Div2Luminance = K1Luminance.getScaledInstance(0.5f, true);
-
-    /**
-     * The K2Chrominance indicates K.2 table from JPEG specification and
-     * produces "good" quality output.
-     */
-    public static final JPEGQTable K2Chrominance = new JPEGQTable(K2ChrTable);
-
-    /**
-     * The Constant K2Div2Chrominance indicates K.2 table from JPEG
-     * specification with all elements divided by 2 and produces "very good"
-     * quality output.
-     */
-    public static final JPEGQTable K2Div2Chrominance = K2Chrominance.getScaledInstance(0.5f, true);;
-
-    /**
-     * Instantiates a new JPEGQTable from the array, which should contain 64
-     * elements in natural order.
-     * 
-     * @param table
-     *            the quantization table.
-     */
-    public JPEGQTable(int[] table) {
-        if (table == null) {
-            throw new IllegalArgumentException("table should not be NULL");
-        }
-        if (table.length != SIZE) {
-            throw new IllegalArgumentException("illegal table size: " + table.length);
-        }
-        theTable = table.clone();
-    }
-
-    /**
-     * Gets the current quantization table as an array of integer values.
-     * 
-     * @return the current quantization table as an array of integer values.
-     */
-    public int[] getTable() {
-        return theTable.clone();
-    }
-
-    /**
-     * Gets the scaled instance as quantization table where the values are
-     * multiplied by the scaleFactor and then clamped if forceBaseline is true.
-     * 
-     * @param scaleFactor
-     *            the scale factor of table.
-     * @param forceBaseline
-     *            the force baseline flag, the values should be clamped if true.
-     * @return the new quantization table.
-     */
-    public JPEGQTable getScaledInstance(float scaleFactor, boolean forceBaseline) {
-        int table[] = new int[SIZE];
-
-        int maxValue = forceBaseline ? BASELINE_MAX : MAX;
-
-        for (int i = 0; i < theTable.length; i++) {
-            int rounded = Math.round(theTable[i] * scaleFactor);
-            if (rounded < 1) {
-                rounded = 1;
-            }
-            if (rounded > maxValue) {
-                rounded = maxValue;
-            }
-            table[i] = rounded;
-        }
-        return new JPEGQTable(table);
-    }
-
-    /**
-     * Returns the string representation of this JPEGQTable object.
-     * 
-     * @return the string representation of this JPEGQTable object.
-     */
-    @Override
-    public String toString() {
-        // -- TODO more informative info
-        return "JPEGQTable";
-    }
-}
diff --git a/awt/javax/imageio/plugins/jpeg/package.html b/awt/javax/imageio/plugins/jpeg/package.html
deleted file mode 100644
index 14575c4..0000000
--- a/awt/javax/imageio/plugins/jpeg/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains auxiliary classes for the built-in JPEG image plug-in.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/spi/IIORegistry.java b/awt/javax/imageio/spi/IIORegistry.java
deleted file mode 100644
index 01ddeaa..0000000
--- a/awt/javax/imageio/spi/IIORegistry.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.spi;
-
-import java.util.Arrays;
-
-import org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReaderSpi;
-import org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriterSpi;
-import org.apache.harmony.x.imageio.plugins.png.PNGImageReaderSpi;
-import org.apache.harmony.x.imageio.plugins.png.PNGImageWriterSpi;
-import org.apache.harmony.x.imageio.spi.FileIISSpi;
-import org.apache.harmony.x.imageio.spi.FileIOSSpi;
-import org.apache.harmony.x.imageio.spi.InputStreamIISSpi;
-import org.apache.harmony.x.imageio.spi.OutputStreamIOSSpi;
-import org.apache.harmony.x.imageio.spi.RAFIISSpi;
-import org.apache.harmony.x.imageio.spi.RAFIOSSpi;
-
-/*
- * @author Rustem V. Rafikov, Viskov Nikolay
- * @version $Revision: 1.3 $
- */
-
-/**
- * The IIORegistry class registers service provider instances (SPI). Service
- * provider instances are recognized by specific meta-information in the JAR
- * files containing them. The JAR files with SPI classes are loaded from the
- * application class path.
- * 
- * @since Android 1.0
- */
-public final class IIORegistry extends ServiceRegistry {
-
-    /**
-     * The instance.
-     */
-    private static IIORegistry instance;
-
-    /**
-     * The Constant CATEGORIES.
-     */
-    private static final Class[] CATEGORIES = new Class[] {
-            javax.imageio.spi.ImageWriterSpi.class, javax.imageio.spi.ImageReaderSpi.class,
-            javax.imageio.spi.ImageInputStreamSpi.class,
-            // javax.imageio.spi.ImageTranscoderSpi.class,
-            javax.imageio.spi.ImageOutputStreamSpi.class
-    };
-
-    /**
-     * Instantiates a new IIO registry.
-     */
-    private IIORegistry() {
-        super(Arrays.<Class<?>> asList(CATEGORIES).iterator());
-        registerBuiltinSpis();
-        registerApplicationClasspathSpis();
-    }
-
-    /**
-     * Register built-in SPIs.
-     */
-    private void registerBuiltinSpis() {
-        registerServiceProvider(new JPEGImageWriterSpi());
-        registerServiceProvider(new JPEGImageReaderSpi());
-        registerServiceProvider(new PNGImageReaderSpi());
-        registerServiceProvider(new PNGImageWriterSpi());
-        registerServiceProvider(new FileIOSSpi());
-        registerServiceProvider(new FileIISSpi());
-        registerServiceProvider(new RAFIOSSpi());
-        registerServiceProvider(new RAFIISSpi());
-        registerServiceProvider(new OutputStreamIOSSpi());
-        registerServiceProvider(new InputStreamIISSpi());
-        // -- TODO implement
-    }
-
-    /**
-     * Gets the default IIORegistry instance.
-     * 
-     * @return the default IIORegistry instance.
-     */
-    public static IIORegistry getDefaultInstance() {
-        // TODO implement own instance for each ThreadGroup (see also
-        // ThreadLocal)
-        synchronized (IIORegistry.class) {
-            if (instance == null) {
-                instance = new IIORegistry();
-            }
-            return instance;
-        }
-    }
-
-    /**
-     * Registers all service providers from the application class path.
-     */
-    public void registerApplicationClasspathSpis() {
-        // -- TODO implement for non-builtin plugins
-    }
-}
diff --git a/awt/javax/imageio/spi/IIOServiceProvider.java b/awt/javax/imageio/spi/IIOServiceProvider.java
deleted file mode 100644
index e947677..0000000
--- a/awt/javax/imageio/spi/IIOServiceProvider.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.spi;
-
-import java.util.Locale;
-
-/**
- * The IIOServiceProvider abstract class provides base functionality for ImageIO
- * service provider interfaces (SPIs).
- * 
- * @since Android 1.0
- */
-public abstract class IIOServiceProvider implements RegisterableService {
-
-    /**
-     * The vendor name of this service provider.
-     */
-    protected String vendorName;
-
-    /**
-     * The version of this service provider.
-     */
-    protected String version;
-
-    /**
-     * Instantiates a new IIOServiceProvider.
-     * 
-     * @param vendorName
-     *            the vendor name of service provider.
-     * @param version
-     *            the version of service provider.
-     */
-    public IIOServiceProvider(String vendorName, String version) {
-        if (vendorName == null) {
-            throw new NullPointerException("vendor name cannot be NULL");
-        }
-        if (version == null) {
-            throw new NullPointerException("version name cannot be NULL");
-        }
-        this.vendorName = vendorName;
-        this.version = version;
-    }
-
-    /**
-     * Instantiates a new IIOServiceProvider.
-     */
-    public IIOServiceProvider() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    public void onRegistration(ServiceRegistry registry, Class<?> category) {
-        // the default impl. does nothing
-    }
-
-    public void onDeregistration(ServiceRegistry registry, Class<?> category) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets the vendor name of this service provider.
-     * 
-     * @return the vendor name of this service provider.
-     */
-    public String getVendorName() {
-        return vendorName;
-    }
-
-    /**
-     * Gets the version of this service provider.
-     * 
-     * @return the version of this service provider.
-     */
-    public String getVersion() {
-        return version;
-    }
-
-    /**
-     * Gets a description of this service provider. The result string should be
-     * localized for the specified Locale.
-     * 
-     * @param locale
-     *            the specified Locale.
-     * @return the description of this service provider.
-     */
-    public abstract String getDescription(Locale locale);
-}
diff --git a/awt/javax/imageio/spi/ImageInputStreamSpi.java b/awt/javax/imageio/spi/ImageInputStreamSpi.java
deleted file mode 100644
index fc859a8..0000000
--- a/awt/javax/imageio/spi/ImageInputStreamSpi.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.spi;
-
-import java.io.File;
-import java.io.IOException;
-import javax.imageio.stream.ImageInputStream;
-
-/**
- * The ImageInputStreamSpi abstract class is a service provider interface (SPI)
- * for ImageInputStreams.
- * 
- * @since Android 1.0
- */
-public abstract class ImageInputStreamSpi extends IIOServiceProvider implements RegisterableService {
-
-    /**
-     * The input class.
-     */
-    protected Class<?> inputClass;
-
-    /**
-     * Instantiates a new ImageInputStreamSpi.
-     */
-    protected ImageInputStreamSpi() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Instantiates a new ImageInputStreamSpi.
-     * 
-     * @param vendorName
-     *            the vendor name.
-     * @param version
-     *            the version.
-     * @param inputClass
-     *            the input class.
-     */
-    public ImageInputStreamSpi(String vendorName, String version, Class<?> inputClass) {
-        super(vendorName, version);
-        this.inputClass = inputClass;
-    }
-
-    /**
-     * Gets an input Class object that represents class or interface that must
-     * be implemented by an input source.
-     * 
-     * @return the input class.
-     */
-    public Class<?> getInputClass() {
-        return inputClass;
-    }
-
-    /**
-     * Returns true if the ImageInputStream can use a cache file. If this method
-     * returns false, the value of the useCache parameter of
-     * createInputStreamInstance will be ignored. The default implementation
-     * returns false.
-     * 
-     * @return true, if the ImageInputStream can use a cache file, false
-     *         otherwise.
-     */
-    public boolean canUseCacheFile() {
-        return false; // -- def
-    }
-
-    /**
-     * Returns true if the ImageInputStream implementation requires the use of a
-     * cache file. The default implementation returns false.
-     * 
-     * @return true, if the ImageInputStream implementation requires the use of
-     *         a cache file, false otherwise.
-     */
-    public boolean needsCacheFile() {
-        return false; // def
-    }
-
-    /**
-     * Creates the ImageInputStream associated with this service provider. The
-     * input object should be an instance of the class returned by the
-     * getInputClass method. This method uses the specified directory for the
-     * cache file if the useCache parameter is true.
-     * 
-     * @param input
-     *            the input Object.
-     * @param useCache
-     *            the flag indicating if a cache file is needed or not.
-     * @param cacheDir
-     *            the cache directory.
-     * @return the ImageInputStream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract ImageInputStream createInputStreamInstance(Object input, boolean useCache,
-            File cacheDir) throws IOException;
-
-    /**
-     * Creates the ImageInputStream associated with this service provider. The
-     * input object should be an instance of the class returned by getInputClass
-     * method. This method uses the default system directory for the cache file,
-     * if it is needed.
-     * 
-     * @param input
-     *            the input Object.
-     * @return the ImageInputStream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public ImageInputStream createInputStreamInstance(Object input) throws IOException {
-        return createInputStreamInstance(input, true, null);
-    }
-}
diff --git a/awt/javax/imageio/spi/ImageOutputStreamSpi.java b/awt/javax/imageio/spi/ImageOutputStreamSpi.java
deleted file mode 100644
index b7a9a5c..0000000
--- a/awt/javax/imageio/spi/ImageOutputStreamSpi.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.spi;
-
-import javax.imageio.stream.ImageOutputStream;
-import java.io.IOException;
-import java.io.File;
-
-/**
- * The ImageOutputStreamSpi abstract class is a service provider interface (SPI)
- * for ImageOutputStreams.
- * 
- * @since Android 1.0
- */
-public abstract class ImageOutputStreamSpi extends IIOServiceProvider implements
-        RegisterableService {
-
-    /**
-     * The output class.
-     */
-    protected Class<?> outputClass;
-
-    /**
-     * Instantiates a new ImageOutputStreamSpi.
-     */
-    protected ImageOutputStreamSpi() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Instantiates a new ImageOutputStreamSpi.
-     * 
-     * @param vendorName
-     *            the vendor name.
-     * @param version
-     *            the version.
-     * @param outputClass
-     *            the output class.
-     */
-    public ImageOutputStreamSpi(String vendorName, String version, Class<?> outputClass) {
-        super(vendorName, version);
-        this.outputClass = outputClass;
-    }
-
-    /**
-     * Gets an output Class object that represents the class or interface that
-     * must be implemented by an output source.
-     * 
-     * @return the output class.
-     */
-    public Class<?> getOutputClass() {
-        return outputClass;
-    }
-
-    /**
-     * Returns true if the ImageOutputStream can use a cache file. If this
-     * method returns false, the value of the useCache parameter of
-     * createOutputStreamInstance will be ignored. The default implementation
-     * returns false.
-     * 
-     * @return true, if the ImageOutputStream can use a cache file, false
-     *         otherwise.
-     */
-    public boolean canUseCacheFile() {
-        return false; // def
-    }
-
-    /**
-     * Returns true if the ImageOutputStream implementation requires the use of
-     * a cache file. The default implementation returns false.
-     * 
-     * @return true, if the ImageOutputStream implementation requires the use of
-     *         a cache file, false otherwise.
-     */
-    public boolean needsCacheFile() {
-        return false; // def
-    }
-
-    /**
-     * Creates the ImageOutputStream associated with this service provider. The
-     * output object should be an instance of the class returned by
-     * getOutputClass method. This method uses the default system directory for
-     * the cache file, if it is needed.
-     * 
-     * @param output
-     *            the output Object.
-     * @return the ImageOutputStream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public ImageOutputStream createOutputStreamInstance(Object output) throws IOException {
-        return createOutputStreamInstance(output, true, null);
-    }
-
-    /**
-     * Creates the ImageOutputStream associated with this service provider. The
-     * output object should be an instance of the class returned by
-     * getInputClass method. This method uses the specified directory for the
-     * cache file, if the useCache parameter is true.
-     * 
-     * @param output
-     *            the output Object.
-     * @param useCache
-     *            the flag indicating if cache file is needed or not.
-     * @param cacheDir
-     *            the cache directory.
-     * @return the ImageOutputStream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract ImageOutputStream createOutputStreamInstance(Object output, boolean useCache,
-            File cacheDir) throws IOException;
-}
diff --git a/awt/javax/imageio/spi/ImageReaderSpi.java b/awt/javax/imageio/spi/ImageReaderSpi.java
deleted file mode 100644
index 0528d25..0000000
--- a/awt/javax/imageio/spi/ImageReaderSpi.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.spi;
-
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.ImageReader;
-import java.io.IOException;
-
-/**
- * The ImageReaderSpi abstract class is a service provider interface (SPI) for
- * ImageReaders.
- * 
- * @since Android 1.0
- */
-public abstract class ImageReaderSpi extends ImageReaderWriterSpi {
-
-    /**
-     * The STANDARD_INPUT_TYPE contains ImageInputStream.class.
-     */
-    public static final Class[] STANDARD_INPUT_TYPE = new Class[] {
-        ImageInputStream.class
-    };
-
-    /**
-     * The input types.
-     */
-    protected Class[] inputTypes;
-
-    /**
-     * The writer SPI names.
-     */
-    protected String[] writerSpiNames;
-
-    /**
-     * Instantiates a new ImageReaderSpi.
-     */
-    protected ImageReaderSpi() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Instantiates a new ImageReaderSpi.
-     * 
-     * @param vendorName
-     *            the vendor name.
-     * @param version
-     *            the version.
-     * @param names
-     *            the format names.
-     * @param suffixes
-     *            the array of strings representing the file suffixes.
-     * @param MIMETypes
-     *            the an array of strings representing MIME types.
-     * @param pluginClassName
-     *            the plug-in class name.
-     * @param inputTypes
-     *            the input types.
-     * @param writerSpiNames
-     *            the array of strings with class names of all associated
-     *            ImageWriters.
-     * @param supportsStandardStreamMetadataFormat
-     *            the value indicating if stream metadata can be described by
-     *            standard metadata format.
-     * @param nativeStreamMetadataFormatName
-     *            the native stream metadata format name, returned by
-     *            getNativeStreamMetadataFormatName.
-     * @param nativeStreamMetadataFormatClassName
-     *            the native stream metadata format class name, returned by
-     *            getNativeStreamMetadataFormat.
-     * @param extraStreamMetadataFormatNames
-     *            the extra stream metadata format names, returned by
-     *            getExtraStreamMetadataFormatNames.
-     * @param extraStreamMetadataFormatClassNames
-     *            the extra stream metadata format class names, returned by
-     *            getStreamMetadataFormat.
-     * @param supportsStandardImageMetadataFormat
-     *            the value indicating if image metadata can be described by
-     *            standard metadata format.
-     * @param nativeImageMetadataFormatName
-     *            the native image metadata format name, returned by
-     *            getNativeImageMetadataFormatName.
-     * @param nativeImageMetadataFormatClassName
-     *            the native image metadata format class name, returned by
-     *            getNativeImageMetadataFormat.
-     * @param extraImageMetadataFormatNames
-     *            the extra image metadata format names, returned by
-     *            getExtraImageMetadataFormatNames.
-     * @param extraImageMetadataFormatClassNames
-     *            the extra image metadata format class names, returned by
-     *            getImageMetadataFormat.
-     */
-    public ImageReaderSpi(String vendorName, String version, String[] names, String[] suffixes,
-            String[] MIMETypes, String pluginClassName, Class[] inputTypes,
-            String[] writerSpiNames, boolean supportsStandardStreamMetadataFormat,
-            String nativeStreamMetadataFormatName, String nativeStreamMetadataFormatClassName,
-            String[] extraStreamMetadataFormatNames, String[] extraStreamMetadataFormatClassNames,
-            boolean supportsStandardImageMetadataFormat, String nativeImageMetadataFormatName,
-            String nativeImageMetadataFormatClassName, String[] extraImageMetadataFormatNames,
-            String[] extraImageMetadataFormatClassNames) {
-        super(vendorName, version, names, suffixes, MIMETypes, pluginClassName,
-                supportsStandardStreamMetadataFormat, nativeStreamMetadataFormatName,
-                nativeStreamMetadataFormatClassName, extraStreamMetadataFormatNames,
-                extraStreamMetadataFormatClassNames, supportsStandardImageMetadataFormat,
-                nativeImageMetadataFormatName, nativeImageMetadataFormatClassName,
-                extraImageMetadataFormatNames, extraImageMetadataFormatClassNames);
-
-        if (inputTypes == null || inputTypes.length == 0) {
-            throw new NullPointerException("input types array cannot be NULL or empty");
-        }
-        this.inputTypes = inputTypes;
-        this.writerSpiNames = writerSpiNames;
-    }
-
-    /**
-     * Gets an array of Class objects whose types can be used as input for this
-     * reader.
-     * 
-     * @return the input types.
-     */
-    public Class[] getInputTypes() {
-        return inputTypes;
-    }
-
-    /**
-     * Returns true if the format of source object is supported by this reader.
-     * 
-     * @param source
-     *            the source object to be decoded (for example an
-     *            ImageInputStream).
-     * @return true, if the format of source object is supported by this reader,
-     *         false otherwise.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract boolean canDecodeInput(Object source) throws IOException;
-
-    /**
-     * Returns an instance of the ImageReader implementation for this service
-     * provider.
-     * 
-     * @return the ImageReader.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public ImageReader createReaderInstance() throws IOException {
-        return createReaderInstance(null);
-    }
-
-    /**
-     * Returns an instance of the ImageReader implementation for this service
-     * provider.
-     * 
-     * @param extension
-     *            the a plug-in specific extension object, or null.
-     * @return the ImageReader.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract ImageReader createReaderInstance(Object extension) throws IOException;
-
-    /**
-     * Checks whether or not the specified ImageReader object is an instance of
-     * the ImageReader associated with this service provider or not.
-     * 
-     * @param reader
-     *            the ImageReader.
-     * @return true, if the specified ImageReader object is an instance of the
-     *         ImageReader associated with this service provider, false
-     *         otherwise.
-     */
-    public boolean isOwnReader(ImageReader reader) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets an array of strings with names of the ImageWriterSpi classes that
-     * support the internal metadata representation used by the ImageReader of
-     * this service provider, or null if there are no such ImageWriters.
-     * 
-     * @return the array of strings with names of the ImageWriterSpi classes.
-     */
-    public String[] getImageWriterSpiNames() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-}
diff --git a/awt/javax/imageio/spi/ImageReaderWriterSpi.java b/awt/javax/imageio/spi/ImageReaderWriterSpi.java
deleted file mode 100644
index 9ca08b5..0000000
--- a/awt/javax/imageio/spi/ImageReaderWriterSpi.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.spi;
-
-import org.apache.harmony.x.imageio.metadata.IIOMetadataUtils;
-
-import javax.imageio.metadata.IIOMetadataFormat;
-
-/**
- * The ImageReaderWriterSpi class is a superclass for the ImageReaderSpi and
- * ImageWriterSpi SPIs.
- * 
- * @since Android 1.0
- */
-public abstract class ImageReaderWriterSpi extends IIOServiceProvider implements
-        RegisterableService {
-
-    /**
-     * The names.
-     */
-    protected String[] names;
-
-    /**
-     * The suffixes.
-     */
-    protected String[] suffixes;
-
-    /**
-     * The MIME types.
-     */
-    protected String[] MIMETypes;
-
-    /**
-     * The plug-in class name.
-     */
-    protected String pluginClassName;
-
-    /**
-     * Whether the reader/writer supports standard stream metadata format.
-     */
-    protected boolean supportsStandardStreamMetadataFormat;
-
-    /**
-     * The native stream metadata format name.
-     */
-    protected String nativeStreamMetadataFormatName;
-
-    /**
-     * The native stream metadata format class name.
-     */
-    protected String nativeStreamMetadataFormatClassName;
-
-    /**
-     * The extra stream metadata format names.
-     */
-    protected String[] extraStreamMetadataFormatNames;
-
-    /**
-     * The extra stream metadata format class names.
-     */
-    protected String[] extraStreamMetadataFormatClassNames;
-
-    /**
-     * Whether the reader/writer supports standard image metadata format.
-     */
-    protected boolean supportsStandardImageMetadataFormat;
-
-    /**
-     * The native image metadata format name.
-     */
-    protected String nativeImageMetadataFormatName;
-
-    /**
-     * The native image metadata format class name.
-     */
-    protected String nativeImageMetadataFormatClassName;
-
-    /**
-     * The extra image metadata format names.
-     */
-    protected String[] extraImageMetadataFormatNames;
-
-    /**
-     * The extra image metadata format class names.
-     */
-    protected String[] extraImageMetadataFormatClassNames;
-
-    /**
-     * Instantiates a new ImageReaderWriterSpi.
-     * 
-     * @param vendorName
-     *            the vendor name.
-     * @param version
-     *            the version.
-     * @param names
-     *            the format names.
-     * @param suffixes
-     *            the array of strings representing the file suffixes.
-     * @param MIMETypes
-     *            the an array of strings representing MIME types.
-     * @param pluginClassName
-     *            the plug-in class name.
-     * @param supportsStandardStreamMetadataFormat
-     *            the value indicating if stream metadata can be described by
-     *            standard metadata format.
-     * @param nativeStreamMetadataFormatName
-     *            the native stream metadata format name, returned by
-     *            getNativeStreamMetadataFormatName.
-     * @param nativeStreamMetadataFormatClassName
-     *            the native stream metadata format class name, returned by
-     *            getNativeStreamMetadataFormat.
-     * @param extraStreamMetadataFormatNames
-     *            the extra stream metadata format names, returned by
-     *            getExtraStreamMetadataFormatNames.
-     * @param extraStreamMetadataFormatClassNames
-     *            the extra stream metadata format class names, returned by
-     *            getStreamMetadataFormat.
-     * @param supportsStandardImageMetadataFormat
-     *            the value indicating if image metadata can be described by
-     *            standard metadata format.
-     * @param nativeImageMetadataFormatName
-     *            the native image metadata format name, returned by
-     *            getNativeImageMetadataFormatName.
-     * @param nativeImageMetadataFormatClassName
-     *            the native image metadata format class name, returned by
-     *            getNativeImageMetadataFormat.
-     * @param extraImageMetadataFormatNames
-     *            the extra image metadata format names, returned by
-     *            getExtraImageMetadataFormatNames.
-     * @param extraImageMetadataFormatClassNames
-     *            the extra image metadata format class names, returned by
-     *            getImageMetadataFormat.
-     */
-    public ImageReaderWriterSpi(String vendorName, String version, String[] names,
-            String[] suffixes, String[] MIMETypes, String pluginClassName,
-            boolean supportsStandardStreamMetadataFormat, String nativeStreamMetadataFormatName,
-            String nativeStreamMetadataFormatClassName, String[] extraStreamMetadataFormatNames,
-            String[] extraStreamMetadataFormatClassNames,
-            boolean supportsStandardImageMetadataFormat, String nativeImageMetadataFormatName,
-            String nativeImageMetadataFormatClassName, String[] extraImageMetadataFormatNames,
-            String[] extraImageMetadataFormatClassNames) {
-        super(vendorName, version);
-
-        if (names == null || names.length == 0) {
-            throw new NullPointerException("format names array cannot be NULL or empty");
-        }
-
-        if (pluginClassName == null) {
-            throw new NullPointerException("Plugin class name cannot be NULL");
-        }
-
-        // We clone all the arrays to be consistent with the fact that
-        // some methods of this class must return clones of the arrays
-        // as it is stated in the spec.
-        this.names = names.clone();
-        this.suffixes = suffixes == null ? null : suffixes.clone();
-        this.MIMETypes = MIMETypes == null ? null : MIMETypes.clone();
-        this.pluginClassName = pluginClassName;
-        this.supportsStandardStreamMetadataFormat = supportsStandardStreamMetadataFormat;
-        this.nativeStreamMetadataFormatName = nativeStreamMetadataFormatName;
-        this.nativeStreamMetadataFormatClassName = nativeStreamMetadataFormatClassName;
-
-        this.extraStreamMetadataFormatNames = extraStreamMetadataFormatNames == null ? null
-                : extraStreamMetadataFormatNames.clone();
-
-        this.extraStreamMetadataFormatClassNames = extraStreamMetadataFormatClassNames == null ? null
-                : extraStreamMetadataFormatClassNames.clone();
-
-        this.supportsStandardImageMetadataFormat = supportsStandardImageMetadataFormat;
-        this.nativeImageMetadataFormatName = nativeImageMetadataFormatName;
-        this.nativeImageMetadataFormatClassName = nativeImageMetadataFormatClassName;
-
-        this.extraImageMetadataFormatNames = extraImageMetadataFormatNames == null ? null
-                : extraImageMetadataFormatNames.clone();
-
-        this.extraImageMetadataFormatClassNames = extraImageMetadataFormatClassNames == null ? null
-                : extraImageMetadataFormatClassNames.clone();
-    }
-
-    /**
-     * Instantiates a new ImageReaderWriterSpi.
-     */
-    public ImageReaderWriterSpi() {
-    }
-
-    /**
-     * Gets an array of strings representing names of the formats that can be
-     * used by the ImageReader or ImageWriter implementation associated with
-     * this service provider.
-     * 
-     * @return the array of supported format names.
-     */
-    public String[] getFormatNames() {
-        return names.clone();
-    }
-
-    /**
-     * Gets an array of strings representing file suffixes associated with the
-     * formats that can be used by the ImageReader or ImageWriter implementation
-     * of this service provider.
-     * 
-     * @return the array of file suffixes.
-     */
-    public String[] getFileSuffixes() {
-        return suffixes == null ? null : suffixes.clone();
-    }
-
-    /**
-     * Gets an array of strings with the names of additional formats of the
-     * image metadata objects produced or consumed by this plug-in.
-     * 
-     * @return the array of extra image metadata format names.
-     */
-    public String[] getExtraImageMetadataFormatNames() {
-        return extraImageMetadataFormatNames == null ? null : extraImageMetadataFormatNames.clone();
-    }
-
-    /**
-     * Gets an array of strings with the names of additional formats of the
-     * stream metadata objects produced or consumed by this plug-in.
-     * 
-     * @return the array of extra stream metadata format names.
-     */
-    public String[] getExtraStreamMetadataFormatNames() {
-        return extraStreamMetadataFormatNames == null ? null : extraStreamMetadataFormatNames
-                .clone();
-    }
-
-    /**
-     * Gets an IIOMetadataFormat object for the specified image metadata format
-     * name.
-     * 
-     * @param formatName
-     *            the format name.
-     * @return the IIOMetadataFormat, or null.
-     */
-    public IIOMetadataFormat getImageMetadataFormat(String formatName) {
-        return IIOMetadataUtils.instantiateMetadataFormat(formatName,
-                supportsStandardImageMetadataFormat, nativeImageMetadataFormatName,
-                nativeImageMetadataFormatClassName, extraImageMetadataFormatNames,
-                extraImageMetadataFormatClassNames);
-    }
-
-    /**
-     * Gets an IIOMetadataFormat object for the specified stream metadata format
-     * name.
-     * 
-     * @param formatName
-     *            the format name.
-     * @return the IIOMetadataFormat, or null.
-     */
-    public IIOMetadataFormat getStreamMetadataFormat(String formatName) {
-        return IIOMetadataUtils.instantiateMetadataFormat(formatName,
-                supportsStandardStreamMetadataFormat, nativeStreamMetadataFormatName,
-                nativeStreamMetadataFormatClassName, extraStreamMetadataFormatNames,
-                extraStreamMetadataFormatClassNames);
-    }
-
-    /**
-     * Gets an array of strings representing the MIME types of the formats that
-     * are supported by the ImageReader or ImageWriter implementation of this
-     * service provider.
-     * 
-     * @return the array MIME types.
-     */
-    public String[] getMIMETypes() {
-        return MIMETypes == null ? null : MIMETypes.clone();
-    }
-
-    /**
-     * Gets the name of the native image metadata format for this reader/writer,
-     * which allows for lossless encoding or decoding of the image metadata with
-     * the format.
-     * 
-     * @return the string with native image metadata format name, or null.
-     */
-    public String getNativeImageMetadataFormatName() {
-        return nativeImageMetadataFormatName;
-    }
-
-    /**
-     * Gets the name of the native stream metadata format for this
-     * reader/writer, which allows for lossless encoding or decoding of the
-     * stream metadata with the format.
-     * 
-     * @return the string with native stream metadata format name, or null.
-     */
-    public String getNativeStreamMetadataFormatName() {
-        return nativeStreamMetadataFormatName;
-    }
-
-    /**
-     * Gets the class name of the ImageReader or ImageWriter associated with
-     * this service provider.
-     * 
-     * @return the class name.
-     */
-    public String getPluginClassName() {
-        return pluginClassName;
-    }
-
-    /**
-     * Checks if the standard metadata format is supported by the getAsTree and
-     * setFromTree methods for the image metadata objects produced or consumed
-     * by this reader or writer.
-     * 
-     * @return true, if standard image metadata format is supported, false
-     *         otherwise.
-     */
-    public boolean isStandardImageMetadataFormatSupported() {
-        return supportsStandardImageMetadataFormat;
-    }
-
-    /**
-     * Checks if the standard metadata format is supported by the getAsTree and
-     * setFromTree methods for the stream metadata objects produced or consumed
-     * by this reader or writer.
-     * 
-     * @return true, if standard stream metadata format is supported, false
-     *         otherwise.
-     */
-    public boolean isStandardStreamMetadataFormatSupported() {
-        return supportsStandardStreamMetadataFormat;
-    }
-}
diff --git a/awt/javax/imageio/spi/ImageTranscoderSpi.java b/awt/javax/imageio/spi/ImageTranscoderSpi.java
deleted file mode 100644
index 742af19..0000000
--- a/awt/javax/imageio/spi/ImageTranscoderSpi.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.spi;
-
-import javax.imageio.ImageTranscoder;
-
-/**
- * The ImageTranscoderSpi class is a service provider interface (SPI) for
- * ImageTranscoders.
- * 
- * @since Android 1.0
- */
-public abstract class ImageTranscoderSpi extends IIOServiceProvider implements RegisterableService {
-
-    /**
-     * Instantiates a new ImageTranscoderSpi.
-     */
-    protected ImageTranscoderSpi() {
-    }
-
-    /**
-     * Instantiates a new ImageTranscoderSpi with the specified vendor name and
-     * version.
-     * 
-     * @param vendorName
-     *            the vendor name.
-     * @param version
-     *            the version.
-     */
-    public ImageTranscoderSpi(String vendorName, String version) {
-        super(vendorName, version);
-    }
-
-    /**
-     * Gets the class name of an ImageReaderSpi that produces IIOMetadata
-     * objects that can be used as input to this transcoder.
-     * 
-     * @return the class name of an ImageReaderSpi.
-     */
-    public abstract String getReaderServiceProviderName();
-
-    /**
-     * Gets the class name of an ImageWriterSpi that produces IIOMetadata
-     * objects that can be used as input to this transcoder.
-     * 
-     * @return the class name of an ImageWriterSpi.
-     */
-    public abstract String getWriterServiceProviderName();
-
-    /**
-     * Creates an instance of the ImageTranscoder associated with this service
-     * provider.
-     * 
-     * @return the ImageTranscoder instance.
-     */
-    public abstract ImageTranscoder createTranscoderInstance();
-}
diff --git a/awt/javax/imageio/spi/ImageWriterSpi.java b/awt/javax/imageio/spi/ImageWriterSpi.java
deleted file mode 100644
index bf25455..0000000
--- a/awt/javax/imageio/spi/ImageWriterSpi.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.spi;
-
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.ImageTypeSpecifier;
-import javax.imageio.ImageWriter;
-import java.awt.image.RenderedImage;
-import java.io.IOException;
-
-/**
- * The ImageWriterSpi abstract class is a service provider interface (SPI) for
- * ImageWriters.
- * 
- * @since Android 1.0
- */
-public abstract class ImageWriterSpi extends ImageReaderWriterSpi {
-
-    /**
-     * The STANDARD_OUTPUT_TYPE contains ImageInputStream.class.
-     */
-    public static final Class[] STANDARD_OUTPUT_TYPE = new Class[] {
-        ImageInputStream.class
-    };
-
-    /**
-     * The output types.
-     */
-    protected Class[] outputTypes;
-
-    /**
-     * The reader SPI names.
-     */
-    protected String[] readerSpiNames;
-
-    /**
-     * Instantiates a new ImageWriterSpi.
-     */
-    protected ImageWriterSpi() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Instantiates a new ImageWriterSpi with the specified parameters.
-     * 
-     * @param vendorName
-     *            the vendor name.
-     * @param version
-     *            the version.
-     * @param names
-     *            the format names.
-     * @param suffixes
-     *            the array of strings representing the file suffixes.
-     * @param MIMETypes
-     *            the an array of strings representing MIME types.
-     * @param pluginClassName
-     *            the plug-in class name.
-     * @param outputTypes
-     *            the output types.
-     * @param readerSpiNames
-     *            the array of strings with class names of all associated
-     *            ImageReaders.
-     * @param supportsStandardStreamMetadataFormat
-     *            the value indicating if stream metadata can be described by
-     *            standard metadata format.
-     * @param nativeStreamMetadataFormatName
-     *            the native stream metadata format name, returned by
-     *            getNativeStreamMetadataFormatName.
-     * @param nativeStreamMetadataFormatClassName
-     *            the native stream metadata format class name, returned by
-     *            getNativeStreamMetadataFormat.
-     * @param extraStreamMetadataFormatNames
-     *            the extra stream metadata format names, returned by
-     *            getExtraStreamMetadataFormatNames.
-     * @param extraStreamMetadataFormatClassNames
-     *            the extra stream metadata format class names, returned by
-     *            getStreamMetadataFormat.
-     * @param supportsStandardImageMetadataFormat
-     *            the value indicating if image metadata can be described by
-     *            standard metadata format.
-     * @param nativeImageMetadataFormatName
-     *            the native image metadata format name, returned by
-     *            getNativeImageMetadataFormatName.
-     * @param nativeImageMetadataFormatClassName
-     *            the native image metadata format class name, returned by
-     *            getNativeImageMetadataFormat.
-     * @param extraImageMetadataFormatNames
-     *            the extra image metadata format names, returned by
-     *            getExtraImageMetadataFormatNames.
-     * @param extraImageMetadataFormatClassNames
-     *            the extra image metadata format class names, returned by
-     *            getImageMetadataFormat.
-     */
-    public ImageWriterSpi(String vendorName, String version, String[] names, String[] suffixes,
-            String[] MIMETypes, String pluginClassName, Class[] outputTypes,
-            String[] readerSpiNames, boolean supportsStandardStreamMetadataFormat,
-            String nativeStreamMetadataFormatName, String nativeStreamMetadataFormatClassName,
-            String[] extraStreamMetadataFormatNames, String[] extraStreamMetadataFormatClassNames,
-            boolean supportsStandardImageMetadataFormat, String nativeImageMetadataFormatName,
-            String nativeImageMetadataFormatClassName, String[] extraImageMetadataFormatNames,
-            String[] extraImageMetadataFormatClassNames) {
-        super(vendorName, version, names, suffixes, MIMETypes, pluginClassName,
-                supportsStandardStreamMetadataFormat, nativeStreamMetadataFormatName,
-                nativeStreamMetadataFormatClassName, extraStreamMetadataFormatNames,
-                extraStreamMetadataFormatClassNames, supportsStandardImageMetadataFormat,
-                nativeImageMetadataFormatName, nativeImageMetadataFormatClassName,
-                extraImageMetadataFormatNames, extraImageMetadataFormatClassNames);
-
-        if (outputTypes == null || outputTypes.length == 0) {
-            throw new NullPointerException("output types array cannot be NULL or empty");
-        }
-
-        this.outputTypes = outputTypes;
-        this.readerSpiNames = readerSpiNames;
-    }
-
-    /**
-     * Returns true if the format of the writer's output is lossless. The
-     * default implementation returns true.
-     * 
-     * @return true, if a format is lossless, false otherwise.
-     */
-    public boolean isFormatLossless() {
-        return true;
-    }
-
-    /**
-     * Gets an array of Class objects whose types can be used as output for this
-     * writer.
-     * 
-     * @return the output types.
-     */
-    public Class[] getOutputTypes() {
-        return outputTypes;
-    }
-
-    /**
-     * Checks whether or not the ImageWriter implementation associated with this
-     * service provider can encode an image with the specified type.
-     * 
-     * @param type
-     *            the ImageTypeSpecifier.
-     * @return true, if an image with the specified type can be encoded, false
-     *         otherwise.
-     */
-    public abstract boolean canEncodeImage(ImageTypeSpecifier type);
-
-    /**
-     * Checks whether or not the ImageWriter implementation associated with this
-     * service provider can encode the specified RenderedImage.
-     * 
-     * @param im
-     *            the RenderedImage.
-     * @return true, if RenderedImage can be encoded, false otherwise.
-     */
-    public boolean canEncodeImage(RenderedImage im) {
-        return canEncodeImage(ImageTypeSpecifier.createFromRenderedImage(im));
-    }
-
-    /**
-     * Returns an instance of the ImageWriter implementation for this service
-     * provider.
-     * 
-     * @return the ImageWriter.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public ImageWriter createWriterInstance() throws IOException {
-        return createWriterInstance(null);
-    }
-
-    /**
-     * Returns an instance of the ImageWriter implementation for this service
-     * provider.
-     * 
-     * @param extension
-     *            the a plug-in specific extension object, or null.
-     * @return the ImageWriter.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public abstract ImageWriter createWriterInstance(Object extension) throws IOException;
-
-    /**
-     * Checks whether or not the specified ImageWriter object is an instance of
-     * the ImageWriter associated with this service provider or not.
-     * 
-     * @param writer
-     *            the ImageWriter.
-     * @return true, if the specified ImageWriter object is an instance of the
-     *         ImageWriter associated with this service provider, false
-     *         otherwise.
-     */
-    public boolean isOwnWriter(ImageWriter writer) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets an array of strings with names of the ImageReaderSpi classes that
-     * support the internal metadata representation used by the ImageWriter of
-     * this service provider, or null if there are no such ImageReaders.
-     * 
-     * @return the array of strings with names of the ImageWriterSpi classes.
-     */
-    public String[] getImageReaderSpiNames() {
-        return readerSpiNames;
-    }
-}
diff --git a/awt/javax/imageio/spi/RegisterableService.java b/awt/javax/imageio/spi/RegisterableService.java
deleted file mode 100644
index ae2f4d3..0000000
--- a/awt/javax/imageio/spi/RegisterableService.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.spi;
-
-/**
- * The RegisterableService interface provides service provider objects that can
- * be registered by a ServiceRegistry, and notifications that registration and
- * deregistration have been performed.
- * 
- * @since Android 1.0
- */
-public interface RegisterableService {
-
-    /**
-     * This method is called when the object which implements this interface is
-     * registered to the specified category of the specified registry.
-     * 
-     * @param registry
-     *            the ServiceRegistry to be registered.
-     * @param category
-     *            the class representing a category.
-     */
-    void onRegistration(ServiceRegistry registry, Class<?> category);
-
-    /**
-     * This method is called when the object which implements this interface is
-     * deregistered to the specified category of the specified registry.
-     * 
-     * @param registry
-     *            the ServiceRegistry to be registered.
-     * @param category
-     *            the class representing a category.
-     */
-    void onDeregistration(ServiceRegistry registry, Class<?> category);
-}
diff --git a/awt/javax/imageio/spi/ServiceRegistry.java b/awt/javax/imageio/spi/ServiceRegistry.java
deleted file mode 100644
index 79b02a3..0000000
--- a/awt/javax/imageio/spi/ServiceRegistry.java
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.spi;
-
-import java.util.*;
-import java.util.Map.Entry;
-
-/**
- * The ServiceRegistry class provides ability to register, deregister, look up
- * and obtain service provider instances (SPIs). A service means a set of
- * interfaces and classes, and a service provider is an implementation of a
- * service. Service providers can be associated with one or more categories.
- * Each category is defined by a class or interface. Only a single instance of a
- * each class is allowed to be registered as a category.
- * 
- * @since Android 1.0
- */
-public class ServiceRegistry {
-
-    /**
-     * The categories.
-     */
-    CategoriesMap categories = new CategoriesMap(this);
-
-    /**
-     * Instantiates a new ServiceRegistry with the specified categories.
-     * 
-     * @param categoriesIterator
-     *            an Iterator of Class objects for defining of categories.
-     */
-    public ServiceRegistry(Iterator<Class<?>> categoriesIterator) {
-        if (null == categoriesIterator) {
-            throw new IllegalArgumentException("categories iterator should not be NULL");
-        }
-        while (categoriesIterator.hasNext()) {
-            Class<?> c = categoriesIterator.next();
-            categories.addCategory(c);
-        }
-    }
-
-    /**
-     * Looks up and instantiates the available providers of this service using
-     * the specified class loader.
-     * 
-     * @param providerClass
-     *            the Class object of the provider to be looked up.
-     * @param loader
-     *            the class loader to be used.
-     * @return the iterator of providers objects for this service.
-     */
-    public static <T> Iterator<T> lookupProviders(Class<T> providerClass, ClassLoader loader) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Looks up and instantiates the available providers of this service using
-     * the context class loader.
-     * 
-     * @param providerClass
-     *            the Class object of the provider to be looked up.
-     * @return the iterator of providers objects for this service.
-     */
-    public static <T> Iterator<T> lookupProviders(Class<T> providerClass) {
-        return lookupProviders(providerClass, Thread.currentThread().getContextClassLoader());
-    }
-
-    /**
-     * Registers the specified service provider object in the specified
-     * categories.
-     * 
-     * @param provider
-     *            the specified provider to be registered.
-     * @param category
-     *            the category.
-     * @return true, if no provider of the same class is registered in this
-     *         category, false otherwise.
-     */
-    public <T> boolean registerServiceProvider(T provider, Class<T> category) {
-        return categories.addProvider(provider, category);
-    }
-
-    /**
-     * Registers a list of service providers.
-     * 
-     * @param providers
-     *            the list of service providers.
-     */
-    public void registerServiceProviders(Iterator<?> providers) {
-        for (Iterator<?> iterator = providers; iterator.hasNext();) {
-            categories.addProvider(iterator.next(), null);
-        }
-    }
-
-    /**
-     * Registers the specified service provider object in all categories.
-     * 
-     * @param provider
-     *            the service provider.
-     */
-    public void registerServiceProvider(Object provider) {
-        categories.addProvider(provider, null);
-    }
-
-    /**
-     * Deregisters the specifies service provider from the specified category.
-     * 
-     * @param provider
-     *            the service provider to be deregistered.
-     * @param category
-     *            the specified category.
-     * @return true, if the provider was already registered in the specified
-     *         category, false otherwise.
-     */
-    public <T> boolean deregisterServiceProvider(T provider, Class<T> category) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Deregisters the specified service provider from all categories.
-     * 
-     * @param provider
-     *            the specified service provider.
-     */
-    public void deregisterServiceProvider(Object provider) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets an Iterator of registered service providers in the specified
-     * category which satisfy the specified Filter. The useOrdering parameter
-     * indicates whether the iterator will return all of the server provider
-     * objects in a set order.
-     * 
-     * @param category
-     *            the specified category.
-     * @param filter
-     *            the specified filter.
-     * @param useOrdering
-     *            the flag indicating that providers are ordered in the returned
-     *            Iterator.
-     * @return the iterator of registered service providers.
-     */
-    @SuppressWarnings("unchecked")
-    public <T> Iterator<T> getServiceProviders(Class<T> category, Filter filter, boolean useOrdering) {
-        return new FilteredIterator<T>(filter, (Iterator<T>)categories.getProviders(category,
-                useOrdering));
-    }
-
-    /**
-     * Gets an Iterator of all registered service providers in the specified
-     * category. The useOrdering parameter indicates whether the iterator will
-     * return all of the server provider objects in a set order.
-     * 
-     * @param category
-     *            the specified category.
-     * @param useOrdering
-     *            the flag indicating that providers are ordered in the returned
-     *            Iterator.
-     * @return the Iterator of service providers.
-     */
-    @SuppressWarnings("unchecked")
-    public <T> Iterator<T> getServiceProviders(Class<T> category, boolean useOrdering) {
-        return (Iterator<T>)categories.getProviders(category, useOrdering);
-    }
-
-    /**
-     * Gets the registered service provider object that has the specified class
-     * type.
-     * 
-     * @param providerClass
-     *            the specified provider class.
-     * @return the service provider object.
-     */
-    public <T> T getServiceProviderByClass(Class<T> providerClass) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Sets an ordering between two service provider objects within the
-     * specified category.
-     * 
-     * @param category
-     *            the specified category.
-     * @param firstProvider
-     *            the first provider.
-     * @param secondProvider
-     *            the second provider.
-     * @return true, if a previously unset order was set.
-     */
-    public <T> boolean setOrdering(Class<T> category, T firstProvider, T secondProvider) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Unsets an ordering between two service provider objects within the
-     * specified category.
-     * 
-     * @param category
-     *            the specified category.
-     * @param firstProvider
-     *            the first provider.
-     * @param secondProvider
-     *            the second provider.
-     * @return true, if a previously unset order was removed.
-     */
-    public <T> boolean unsetOrdering(Class<T> category, T firstProvider, T secondProvider) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Deregisters all providers from the specified category.
-     * 
-     * @param category
-     *            the specified category.
-     */
-    public void deregisterAll(Class<?> category) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Deregister all providers from all categories.
-     */
-    public void deregisterAll() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Finalizes this object.
-     * 
-     * @throws Throwable
-     *             if an error occurs during finalization.
-     */
-    @Override
-    public void finalize() throws Throwable {
-        // TODO uncomment when deregisterAll is implemented
-        // deregisterAll();
-    }
-
-    /**
-     * Checks whether the specified provider has been already registered.
-     * 
-     * @param provider
-     *            the provider to be checked.
-     * @return true, if the specified provider has been already registered,
-     *         false otherwise.
-     */
-    public boolean contains(Object provider) {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
-
-    /**
-     * Gets an iterator of Class objects representing the current categories.
-     * 
-     * @return the Iterator of Class objects.
-     */
-    public Iterator<Class<?>> getCategories() {
-        return categories.list();
-    }
-
-    /**
-     * The ServiceRegistry.Filter interface is used by
-     * ServiceRegistry.getServiceProviders to filter providers according to the
-     * specified criterion.
-     * 
-     * @since Android 1.0
-     */
-    public static interface Filter {
-
-        /**
-         * Returns true if the specified provider satisfies the criterion of
-         * this Filter.
-         * 
-         * @param provider
-         *            the provider.
-         * @return true, if the specified provider satisfies the criterion of
-         *         this Filter, false otherwise.
-         */
-        boolean filter(Object provider);
-    }
-
-    /**
-     * The Class CategoriesMap.
-     */
-    private static class CategoriesMap {
-
-        /**
-         * The categories.
-         */
-        Map<Class<?>, ProvidersMap> categories = new HashMap<Class<?>, ProvidersMap>();
-
-        /**
-         * The registry.
-         */
-        ServiceRegistry registry;
-
-        /**
-         * Instantiates a new categories map.
-         * 
-         * @param registry
-         *            the registry.
-         */
-        public CategoriesMap(ServiceRegistry registry) {
-            this.registry = registry;
-        }
-
-        // -- TODO: useOrdering
-        /**
-         * Gets the providers.
-         * 
-         * @param category
-         *            the category.
-         * @param useOrdering
-         *            the use ordering.
-         * @return the providers.
-         */
-        Iterator<?> getProviders(Class<?> category, boolean useOrdering) {
-            ProvidersMap providers = categories.get(category);
-            if (null == providers) {
-                throw new IllegalArgumentException("Unknown category: " + category);
-            }
-            return providers.getProviders(useOrdering);
-        }
-
-        /**
-         * List.
-         * 
-         * @return the iterator< class<?>>.
-         */
-        Iterator<Class<?>> list() {
-            return categories.keySet().iterator();
-        }
-
-        /**
-         * Adds the category.
-         * 
-         * @param category
-         *            the category.
-         */
-        void addCategory(Class<?> category) {
-            categories.put(category, new ProvidersMap());
-        }
-
-        /**
-         * Adds a provider to the category. If <code>category</code> is
-         * <code>null</code> then the provider will be added to all categories
-         * which the provider is assignable from.
-         * 
-         * @param provider
-         *            provider to add.
-         * @param category
-         *            category to add provider to.
-         * @return true, if there were such provider in some category.
-         */
-        boolean addProvider(Object provider, Class<?> category) {
-            if (provider == null) {
-                throw new IllegalArgumentException("provider should be != NULL");
-            }
-
-            boolean rt;
-            if (category == null) {
-                rt = findAndAdd(provider);
-            } else {
-                rt = addToNamed(provider, category);
-            }
-
-            if (provider instanceof RegisterableService) {
-                ((RegisterableService)provider).onRegistration(registry, category);
-            }
-
-            return rt;
-        }
-
-        /**
-         * Adds the to named.
-         * 
-         * @param provider
-         *            the provider.
-         * @param category
-         *            the category.
-         * @return true, if successful.
-         */
-        private boolean addToNamed(Object provider, Class<?> category) {
-            Object obj = categories.get(category);
-
-            if (null == obj) {
-                throw new IllegalArgumentException("Unknown category: " + category);
-            }
-
-            return ((ProvidersMap)obj).addProvider(provider);
-        }
-
-        /**
-         * Find and add.
-         * 
-         * @param provider
-         *            the provider.
-         * @return true, if successful.
-         */
-        private boolean findAndAdd(Object provider) {
-            boolean rt = false;
-            for (Entry<Class<?>, ProvidersMap> e : categories.entrySet()) {
-                if (e.getKey().isAssignableFrom(provider.getClass())) {
-                    rt |= e.getValue().addProvider(provider);
-                }
-            }
-            return rt;
-        }
-    }
-
-    /**
-     * The Class ProvidersMap.
-     */
-    private static class ProvidersMap {
-        // -- TODO: providers ordering support
-
-        /**
-         * The providers.
-         */
-        Map<Class<?>, Object> providers = new HashMap<Class<?>, Object>();
-
-        /**
-         * Adds the provider.
-         * 
-         * @param provider
-         *            the provider.
-         * @return true, if successful.
-         */
-        boolean addProvider(Object provider) {
-            return providers.put(provider.getClass(), provider) != null;
-        }
-
-        /**
-         * Gets the provider classes.
-         * 
-         * @return the provider classes.
-         */
-        Iterator<Class<?>> getProviderClasses() {
-            return providers.keySet().iterator();
-        }
-
-        // -- TODO ordering
-        /**
-         * Gets the providers.
-         * 
-         * @param userOrdering
-         *            the user ordering.
-         * @return the providers.
-         */
-        Iterator<?> getProviders(boolean userOrdering) {
-            return providers.values().iterator();
-        }
-    }
-
-    /**
-     * The Class FilteredIterator.
-     */
-    private static class FilteredIterator<E> implements Iterator<E> {
-
-        /**
-         * The filter.
-         */
-        private Filter filter;
-
-        /**
-         * The backend.
-         */
-        private Iterator<E> backend;
-
-        /**
-         * The next obj.
-         */
-        private E nextObj;
-
-        /**
-         * Instantiates a new filtered iterator.
-         * 
-         * @param filter
-         *            the filter.
-         * @param backend
-         *            the backend.
-         */
-        public FilteredIterator(Filter filter, Iterator<E> backend) {
-            this.filter = filter;
-            this.backend = backend;
-            findNext();
-        }
-
-        /**
-         * Next.
-         * 
-         * @return the e.
-         */
-        public E next() {
-            if (nextObj == null) {
-                throw new NoSuchElementException();
-            }
-            E tmp = nextObj;
-            findNext();
-            return tmp;
-        }
-
-        /**
-         * Checks for next.
-         * 
-         * @return true, if successful.
-         */
-        public boolean hasNext() {
-            return nextObj != null;
-        }
-
-        /**
-         * Removes the.
-         */
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-
-        /**
-         * Sets nextObj to a next provider matching the criterion given by the
-         * filter.
-         */
-        private void findNext() {
-            nextObj = null;
-            while (backend.hasNext()) {
-                E o = backend.next();
-                if (filter.filter(o)) {
-                    nextObj = o;
-                    return;
-                }
-            }
-        }
-    }
-}
diff --git a/awt/javax/imageio/spi/package.html b/awt/javax/imageio/spi/package.html
deleted file mode 100644
index 18ceff4..0000000
--- a/awt/javax/imageio/spi/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-    This package provides several Service Provider Interface (SPI) classes for readers, writers, transcoders and streams to handle images.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/stream/FileCacheImageInputStream.java b/awt/javax/imageio/stream/FileCacheImageInputStream.java
deleted file mode 100644
index 710ac66..0000000
--- a/awt/javax/imageio/stream/FileCacheImageInputStream.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.stream;
-
-import java.io.*;
-
-/**
- * The FileCacheImageInputStream class is an implementation of ImageInputStream
- * which reads from its InputStream and uses a temporary file as a cache.
- * 
- * @since Android 1.0
- */
-public class FileCacheImageInputStream extends ImageInputStreamImpl {
-
-    /**
-     * The is.
-     */
-    private InputStream is;
-
-    /**
-     * The file.
-     */
-    private File file;
-
-    /**
-     * The raf.
-     */
-    private RandomAccessFile raf;
-
-    /**
-     * Instantiates a new FileCacheImageInputStream from the specified
-     * InputStream and using the specified File as its cache directory.
-     * 
-     * @param stream
-     *            the InputStream for reading.
-     * @param cacheDir
-     *            the cache directory where the cache file will be created.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public FileCacheImageInputStream(InputStream stream, File cacheDir) throws IOException {
-        if (stream == null) {
-            throw new IllegalArgumentException("stream == null!");
-        }
-        is = stream;
-
-        if (cacheDir == null || cacheDir.isDirectory()) {
-            file = File.createTempFile(FileCacheImageOutputStream.IIO_TEMP_FILE_PREFIX, null,
-                    cacheDir);
-            file.deleteOnExit();
-        } else {
-            throw new IllegalArgumentException("Not a directory!");
-        }
-
-        raf = new RandomAccessFile(file, "rw");
-    }
-
-    @Override
-    public int read() throws IOException {
-        bitOffset = 0;
-
-        if (streamPos >= raf.length()) {
-            int b = is.read();
-
-            if (b < 0) {
-                return -1;
-            }
-
-            raf.seek(streamPos++);
-            raf.write(b);
-            return b;
-        }
-
-        raf.seek(streamPos++);
-        return raf.read();
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        bitOffset = 0;
-
-        if (streamPos >= raf.length()) {
-            int nBytes = is.read(b, off, len);
-
-            if (nBytes < 0) {
-                return -1;
-            }
-
-            raf.seek(streamPos);
-            raf.write(b, off, nBytes);
-            streamPos += nBytes;
-            return nBytes;
-        }
-
-        raf.seek(streamPos);
-        int nBytes = raf.read(b, off, len);
-        streamPos += nBytes;
-        return nBytes;
-    }
-
-    @Override
-    public boolean isCached() {
-        return true;
-    }
-
-    @Override
-    public boolean isCachedFile() {
-        return true;
-    }
-
-    @Override
-    public boolean isCachedMemory() {
-        return false;
-    }
-
-    @Override
-    public void close() throws IOException {
-        super.close();
-        raf.close();
-        file.delete();
-    }
-}
diff --git a/awt/javax/imageio/stream/FileCacheImageOutputStream.java b/awt/javax/imageio/stream/FileCacheImageOutputStream.java
deleted file mode 100644
index 135afab..0000000
--- a/awt/javax/imageio/stream/FileCacheImageOutputStream.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.stream;
-
-import java.io.IOException;
-import java.io.File;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-
-/**
- * The FileCacheImageOutputStream class is an implementation of
- * ImageOutputStream that writes to its OutputStream using a temporary file as a
- * cache.
- * 
- * @since Android 1.0
- */
-public class FileCacheImageOutputStream extends ImageOutputStreamImpl {
-
-    /**
-     * The Constant IIO_TEMP_FILE_PREFIX.
-     */
-    static final String IIO_TEMP_FILE_PREFIX = "iioCache";
-
-    /**
-     * The Constant MAX_BUFFER_LEN.
-     */
-    static final int MAX_BUFFER_LEN = 1048575; // 1 MB - is it not too much?
-
-    /**
-     * The os.
-     */
-    private OutputStream os;
-
-    /**
-     * The file.
-     */
-    private File file;
-
-    /**
-     * The raf.
-     */
-    private RandomAccessFile raf;
-
-    /**
-     * Instantiates a FileCacheImageOutputStream.
-     * 
-     * @param stream
-     *            the OutputStream for writing.
-     * @param cacheDir
-     *            the cache directory where the cache file will be created.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public FileCacheImageOutputStream(OutputStream stream, File cacheDir) throws IOException {
-        if (stream == null) {
-            throw new IllegalArgumentException("stream == null!");
-        }
-        os = stream;
-
-        if (cacheDir == null || cacheDir.isDirectory()) {
-            file = File.createTempFile(IIO_TEMP_FILE_PREFIX, null, cacheDir);
-            file.deleteOnExit();
-        } else {
-            throw new IllegalArgumentException("Not a directory!");
-        }
-
-        raf = new RandomAccessFile(file, "rw");
-    }
-
-    @Override
-    public void close() throws IOException {
-        flushBefore(raf.length());
-        super.close();
-        raf.close();
-        file.delete();
-    }
-
-    @Override
-    public boolean isCached() {
-        return true;
-    }
-
-    @Override
-    public boolean isCachedFile() {
-        return true;
-    }
-
-    @Override
-    public boolean isCachedMemory() {
-        return false;
-    }
-
-    @Override
-    public void write(int b) throws IOException {
-        flushBits(); // See the flushBits method description
-
-        raf.write(b);
-        streamPos++;
-    }
-
-    @Override
-    public void write(byte[] b, int off, int len) throws IOException {
-        flushBits(); // See the flushBits method description
-
-        raf.write(b, off, len);
-        streamPos += len;
-    }
-
-    @Override
-    public int read() throws IOException {
-        bitOffset = 0; // Should reset
-
-        int res = raf.read();
-        if (res >= 0) {
-            streamPos++;
-        }
-
-        return res;
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        bitOffset = 0;
-
-        int numRead = raf.read(b, off, len);
-        if (numRead > 0) {
-            streamPos += numRead;
-        }
-
-        return numRead;
-    }
-
-    @Override
-    public void flushBefore(long pos) throws IOException {
-        long readFromPos = flushedPos;
-        super.flushBefore(pos);
-
-        long bytesToRead = pos - readFromPos;
-        raf.seek(readFromPos);
-
-        if (bytesToRead < MAX_BUFFER_LEN) {
-            byte buffer[] = new byte[(int)bytesToRead];
-            raf.readFully(buffer);
-            os.write(buffer);
-        } else {
-            byte buffer[] = new byte[MAX_BUFFER_LEN];
-            while (bytesToRead > 0) {
-                int count = (int)Math.min(MAX_BUFFER_LEN, bytesToRead);
-                raf.readFully(buffer, 0, count);
-                os.write(buffer, 0, count);
-                bytesToRead -= count;
-            }
-        }
-
-        os.flush();
-
-        if (pos != streamPos) {
-            raf.seek(streamPos); // Reset the position
-        }
-    }
-
-    @Override
-    public void seek(long pos) throws IOException {
-        if (pos < flushedPos) {
-            throw new IndexOutOfBoundsException();
-        }
-
-        raf.seek(pos);
-        streamPos = raf.getFilePointer();
-        bitOffset = 0;
-    }
-
-    @Override
-    public long length() {
-        try {
-            return raf.length();
-        } catch (IOException e) {
-            return -1L;
-        }
-    }
-}
diff --git a/awt/javax/imageio/stream/FileImageInputStream.java b/awt/javax/imageio/stream/FileImageInputStream.java
deleted file mode 100644
index b9b6002..0000000
--- a/awt/javax/imageio/stream/FileImageInputStream.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.stream;
-
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.io.File;
-import java.io.FileNotFoundException;
-
-/**
- * The FileImageInputStream class implements ImageInputStream and obtains its
- * input data from a File or RandomAccessFile.
- * 
- * @since Android 1.0
- */
-public class FileImageInputStream extends ImageInputStreamImpl {
-
-    /**
-     * The raf.
-     */
-    RandomAccessFile raf;
-
-    /**
-     * Instantiates a new FileImageInputStream from the specified File.
-     * 
-     * @param f
-     *            the File of input data.
-     * @throws FileNotFoundException
-     *             if the specified file doesn't exist.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    @SuppressWarnings( {
-        "DuplicateThrows"
-    })
-    public FileImageInputStream(File f) throws FileNotFoundException, IOException {
-        if (f == null) {
-            throw new IllegalArgumentException("f == null!");
-        }
-
-        raf = new RandomAccessFile(f, "r");
-    }
-
-    /**
-     * Instantiates a new FileImageInputStream from the specified
-     * RandomAccessFile.
-     * 
-     * @param raf
-     *            the RandomAccessFile of input data.
-     */
-    public FileImageInputStream(RandomAccessFile raf) {
-        if (raf == null) {
-            throw new IllegalArgumentException("raf == null!");
-        }
-
-        this.raf = raf;
-    }
-
-    @Override
-    public int read() throws IOException {
-        bitOffset = 0;
-
-        int res = raf.read();
-        if (res != -1) {
-            streamPos++;
-        }
-        return res;
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        bitOffset = 0;
-
-        int numRead = raf.read(b, off, len);
-        if (numRead >= 0) {
-            streamPos += numRead;
-        }
-
-        return numRead;
-    }
-
-    @Override
-    public long length() {
-        try {
-            return raf.length();
-        } catch (IOException e) {
-            return -1L;
-        }
-    }
-
-    @Override
-    public void seek(long pos) throws IOException {
-        if (pos < getFlushedPosition()) {
-            throw new IndexOutOfBoundsException();
-        }
-
-        raf.seek(pos);
-        streamPos = raf.getFilePointer();
-        bitOffset = 0;
-    }
-
-    @Override
-    public void close() throws IOException {
-        super.close();
-        raf.close();
-    }
-}
diff --git a/awt/javax/imageio/stream/FileImageOutputStream.java b/awt/javax/imageio/stream/FileImageOutputStream.java
deleted file mode 100644
index 2730ba6..0000000
--- a/awt/javax/imageio/stream/FileImageOutputStream.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.stream;
-
-import java.io.*;
-
-/**
- * The FileImageOutputStream class implements ImageOutputStream and writes the
- * output data to a File or RandomAccessFile.
- * 
- * @since Android 1.0
- */
-public class FileImageOutputStream extends ImageOutputStreamImpl {
-
-    /**
-     * The file.
-     */
-    RandomAccessFile file;
-
-    /**
-     * Instantiates a new FileImageOutputStream with the specified File.
-     * 
-     * @param f
-     *            the output File.
-     * @throws FileNotFoundException
-     *             if the file not found.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public FileImageOutputStream(File f) throws FileNotFoundException, IOException {
-        this(f != null ? new RandomAccessFile(f, "rw") : null);
-    }
-
-    /**
-     * Instantiates a new FileImageOutputStream with the specified
-     * RandomAccessFile.
-     * 
-     * @param raf
-     *            the output RandomAccessFile.
-     */
-    public FileImageOutputStream(RandomAccessFile raf) {
-        if (raf == null) {
-            throw new IllegalArgumentException("file should not be NULL");
-        }
-        file = raf;
-    }
-
-    @Override
-    public void write(int b) throws IOException {
-        checkClosed();
-        // according to the spec for ImageOutputStreamImpl#flushBits()
-        flushBits();
-        file.write(b);
-        streamPos++;
-    }
-
-    @Override
-    public void write(byte[] b, int off, int len) throws IOException {
-        checkClosed();
-        // according to the spec for ImageOutputStreamImpl#flushBits()
-        flushBits();
-        file.write(b, off, len);
-        streamPos += len;
-    }
-
-    @Override
-    public int read() throws IOException {
-        checkClosed();
-        int rt = file.read();
-        if (rt != -1) {
-            streamPos++;
-        }
-        return rt;
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        checkClosed();
-        int rt = file.read(b, off, len);
-        if (rt != -1) {
-            streamPos += rt;
-        }
-        return rt;
-    }
-
-    @Override
-    public long length() {
-        try {
-            checkClosed();
-            return file.length();
-        } catch (IOException e) {
-            return super.length(); // -1L
-        }
-    }
-
-    @Override
-    public void seek(long pos) throws IOException {
-        // -- checkClosed() is performed in super.seek()
-        super.seek(pos);
-        file.seek(pos);
-        streamPos = file.getFilePointer();
-    }
-
-    @Override
-    public void close() throws IOException {
-        super.close();
-        file.close();
-    }
-}
diff --git a/awt/javax/imageio/stream/IIOByteBuffer.java b/awt/javax/imageio/stream/IIOByteBuffer.java
deleted file mode 100644
index 867d808..0000000
--- a/awt/javax/imageio/stream/IIOByteBuffer.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Sergey I. Salishev
- * @version $Revision: 1.2 $
- */
-
-package javax.imageio.stream;
-
-// 
-// @author Sergey I. Salishev
-// @version $Revision: 1.2 $
-//
-
-/**
- * The IIOByteBuffer class represents a byte array with offset and length that
- * is used by ImageInputStream for obtaining a sequence of bytes.
- * 
- * @since Android 1.0
- */
-public class IIOByteBuffer {
-
-    /**
-     * The data.
-     */
-    private byte[] data;
-
-    /**
-     * The offset.
-     */
-    private int offset;
-
-    /**
-     * The length.
-     */
-    private int length;
-
-    /**
-     * Instantiates a new IIOByteBuffer.
-     * 
-     * @param data
-     *            the byte array.
-     * @param offset
-     *            the offset in the array.
-     * @param length
-     *            the length of array.
-     */
-    public IIOByteBuffer(byte[] data, int offset, int length) {
-        this.data = data;
-        this.offset = offset;
-        this.length = length;
-    }
-
-    /**
-     * Gets the byte array of this IIOByteBuffer.
-     * 
-     * @return the byte array.
-     */
-    public byte[] getData() {
-        return data;
-    }
-
-    /**
-     * Gets the length in the array which will be used.
-     * 
-     * @return the length of the data.
-     */
-    public int getLength() {
-        return length;
-    }
-
-    /**
-     * Gets the offset of this IIOByteBuffer.
-     * 
-     * @return the offset of this IIOByteBuffer.
-     */
-    public int getOffset() {
-        return offset;
-    }
-
-    /**
-     * Sets the new data array to this IIOByteBuffer object.
-     * 
-     * @param data
-     *            the new data array.
-     */
-    public void setData(byte[] data) {
-        this.data = data;
-    }
-
-    /**
-     * Sets the length of data which will be used.
-     * 
-     * @param length
-     *            the new length.
-     */
-    public void setLength(int length) {
-        this.length = length;
-    }
-
-    /**
-     * Sets the offset in the data array of this IIOByteBuffer.
-     * 
-     * @param offset
-     *            the new offset.
-     */
-    public void setOffset(int offset) {
-        this.offset = offset;
-    }
-}
diff --git a/awt/javax/imageio/stream/ImageInputStream.java b/awt/javax/imageio/stream/ImageInputStream.java
deleted file mode 100644
index 3dec5d2..0000000
--- a/awt/javax/imageio/stream/ImageInputStream.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.2 $
- */
-
-package javax.imageio.stream;
-
-import java.io.DataInput;
-import java.io.IOException;
-import java.nio.ByteOrder;
-
-/**
- * The ImageInputStream represents input stream interface that is used by
- * ImageReaders.
- * 
- * @since Android 1.0
- */
-public interface ImageInputStream extends DataInput {
-
-    /**
-     * Sets the specified byte order for reading of data values from this
-     * stream.
-     * 
-     * @param byteOrder
-     *            the byte order.
-     */
-    void setByteOrder(ByteOrder byteOrder);
-
-    /**
-     * Gets the byte order.
-     * 
-     * @return the byte order.
-     */
-    ByteOrder getByteOrder();
-
-    /**
-     * Reads a byte from the stream.
-     * 
-     * @return the byte of the stream, or -1 for EOF indicating.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int read() throws IOException;
-
-    /**
-     * Reads number of bytes which is equal to the specified array's length and
-     * stores a result to this array.
-     * 
-     * @param b
-     *            the byte array.
-     * @return the number of read bytes, or -1 indicated EOF.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int read(byte[] b) throws IOException;
-
-    /**
-     * Reads the number of bytes specified by len parameter from the stream and
-     * stores a result to the specified array with the specified offset.
-     * 
-     * @param b
-     *            the byte array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of bytes to be read.
-     * @return the number of read bytes, or -1 indicated EOF.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int read(byte[] b, int off, int len) throws IOException;
-
-    /**
-     * Reads the number of bytes specified by len parameter from the stream, and
-     * modifies the specified IIOByteBuffer with the byte array, offset, and
-     * length.
-     * 
-     * @param buf
-     *            the IIOByteBuffer.
-     * @param len
-     *            the number of bytes to be read.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void readBytes(IIOByteBuffer buf, int len) throws IOException;
-
-    /**
-     * Reads a byte from the stream and returns a boolean true value if it is
-     * non zero, false if it is zero.
-     * 
-     * @return the boolean value for read byte.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    boolean readBoolean() throws IOException;
-
-    /**
-     * Reads a byte from the stream and returns its value as signed byte.
-     * 
-     * @return the signed byte value for read byte.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    byte readByte() throws IOException;
-
-    /**
-     * Reads a byte from the stream and returns its value as an integer.
-     * 
-     * @return the unsigned byte value for read byte as an integer.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int readUnsignedByte() throws IOException;
-
-    /**
-     * Reads 2 bytes from the stream, and returns the result as a short.
-     * 
-     * @return the signed short value from the stream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    short readShort() throws IOException;
-
-    /**
-     * Reads 2 bytes from the stream and returns its value as an unsigned short.
-     * 
-     * @return a unsigned short value coded in an integer.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int readUnsignedShort() throws IOException;
-
-    /**
-     * Reads 2 bytes from the stream and returns their unsigned char value.
-     * 
-     * @return the unsigned char value.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    char readChar() throws IOException;
-
-    /**
-     * Reads 4 bytes from the stream, and returns the result as an integer.
-     * 
-     * @return the signed integer value from the stream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int readInt() throws IOException;
-
-    /**
-     * Reads 4 bytes from the stream and returns its value as long.
-     * 
-     * @return the unsigned integer value as long.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    long readUnsignedInt() throws IOException;
-
-    /**
-     * Reads 8 bytes from the stream, and returns the result as a long.
-     * 
-     * @return the long value from the stream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    long readLong() throws IOException;
-
-    /**
-     * Reads 4 bytes from the stream, and returns the result as a float.
-     * 
-     * @return the float value from the stream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    float readFloat() throws IOException;
-
-    /**
-     * Reads 8 bytes from the stream, and returns the result as a double.
-     * 
-     * @return the double value from the stream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    double readDouble() throws IOException;
-
-    /**
-     * Reads a line from the stream.
-     * 
-     * @return the string contained the line from the stream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    String readLine() throws IOException;
-
-    /**
-     * Reads bytes from the stream in a string that has been encoded in a
-     * modified UTF-8 format.
-     * 
-     * @return the string read from stream and modified UTF-8 format.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    String readUTF() throws IOException;
-
-    /**
-     * Reads the specified number of bytes from the stream, and stores the
-     * result into the specified array starting at the specified index offset.
-     * 
-     * @param b
-     *            the byte array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of bytes to be read.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void readFully(byte[] b, int off, int len) throws IOException;
-
-    /**
-     * Reads number of bytes from the stream which is equal to the specified
-     * array's length, and stores them into this array.
-     * 
-     * @param b
-     *            the byte array.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void readFully(byte[] b) throws IOException;
-
-    /**
-     * Reads the specified number of shorts from the stream, and stores the
-     * result into the specified array starting at the specified index offset.
-     * 
-     * @param s
-     *            the short array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of shorts to be read.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void readFully(short[] s, int off, int len) throws IOException;
-
-    /**
-     * Reads the specified number of chars from the stream, and stores the
-     * result into the specified array starting at the specified index offset.
-     * 
-     * @param c
-     *            the char array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of chars to be read.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void readFully(char[] c, int off, int len) throws IOException;
-
-    /**
-     * Reads the specified number of integer from the stream, and stores the
-     * result into the specified array starting at the specified index offset.
-     * 
-     * @param i
-     *            the integer array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of integer to be read.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void readFully(int[] i, int off, int len) throws IOException;
-
-    /**
-     * Reads the specified number of longs from the stream, and stores the
-     * result into the specified array starting at the specified index offset.
-     * 
-     * @param l
-     *            the long array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of longs to be read.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void readFully(long[] l, int off, int len) throws IOException;
-
-    /**
-     * Reads the specified number of floats from the stream, and stores the
-     * result into the specified array starting at the specified index offset.
-     * 
-     * @param f
-     *            the float array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of floats to be read.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void readFully(float[] f, int off, int len) throws IOException;
-
-    /**
-     * Reads the specified number of doubles from the stream, and stores the
-     * result into the specified array starting at the specified index offset.
-     * 
-     * @param d
-     *            the double array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of doubles to be read.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void readFully(double[] d, int off, int len) throws IOException;
-
-    /**
-     * Gets the stream position.
-     * 
-     * @return the stream position.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    long getStreamPosition() throws IOException;
-
-    /**
-     * Gets the bit offset.
-     * 
-     * @return the bit offset.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int getBitOffset() throws IOException;
-
-    /**
-     * Sets the bit offset to an integer between 0 and 7.
-     * 
-     * @param bitOffset
-     *            the bit offset.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void setBitOffset(int bitOffset) throws IOException;
-
-    /**
-     * Reads a bit from the stream and returns the value 0 or 1.
-     * 
-     * @return the value of single bit: 0 or 1.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int readBit() throws IOException;
-
-    /**
-     * Read the specified number of bits and returns their values as long.
-     * 
-     * @param numBits
-     *            the number of bits to be read.
-     * @return the bit string as a long.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    long readBits(int numBits) throws IOException;
-
-    /**
-     * Returns the length of the stream.
-     * 
-     * @return the length of the stream, or -1 if unknown.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    long length() throws IOException;
-
-    /**
-     * Skips the specified number of bytes by moving stream position.
-     * 
-     * @param n
-     *            the number of bytes.
-     * @return the actual skipped number of bytes.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int skipBytes(int n) throws IOException;
-
-    /**
-     * Skips the specified number of bytes by moving stream position.
-     * 
-     * @param n
-     *            the number of bytes.
-     * @return the actual skipped number of bytes.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    long skipBytes(long n) throws IOException;
-
-    /**
-     * Sets the current stream position to the specified location.
-     * 
-     * @param pos
-     *            a file pointer position.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void seek(long pos) throws IOException;
-
-    /**
-     * Marks a position in the stream to be returned to by a subsequent call to
-     * reset.
-     */
-    void mark();
-
-    /**
-     * Returns the file pointer to its previous position.
-     * 
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void reset() throws IOException;
-
-    /**
-     * Flushes the initial position in this stream prior to the specified stream
-     * position.
-     * 
-     * @param pos
-     *            the position.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void flushBefore(long pos) throws IOException;
-
-    /**
-     * Flushes the initial position in this stream prior to the current stream
-     * position.
-     * 
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void flush() throws IOException;
-
-    /**
-     * Gets the flushed position.
-     * 
-     * @return the flushed position.
-     */
-    long getFlushedPosition();
-
-    /**
-     * Returns true if this ImageInputStream caches data in order to allow
-     * seeking backwards.
-     * 
-     * @return true, if this ImageInputStream caches data in order to allow
-     *         seeking backwards, false otherwise.
-     */
-    boolean isCached();
-
-    /**
-     * Returns true if this ImageInputStream caches data in order to allow
-     * seeking backwards, and keeps it in memory.
-     * 
-     * @return true, if this ImageInputStream caches data in order to allow
-     *         seeking backwards, and keeps it in memory.
-     */
-    boolean isCachedMemory();
-
-    /**
-     * Returns true if this ImageInputStream caches data in order to allow
-     * seeking backwards, and keeps it in a temporary file.
-     * 
-     * @return true, if this ImageInputStream caches data in order to allow
-     *         seeking backwards, and keeps it in a temporary file.
-     */
-    boolean isCachedFile();
-
-    /**
-     * Closes this stream.
-     * 
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void close() throws IOException;
-}
diff --git a/awt/javax/imageio/stream/ImageInputStreamImpl.java b/awt/javax/imageio/stream/ImageInputStreamImpl.java
deleted file mode 100644
index d79da41..0000000
--- a/awt/javax/imageio/stream/ImageInputStreamImpl.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.stream;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.nio.ByteOrder;
-
-/**
- * The ImageInputStreamImpl abstract class implements the ImageInputStream
- * interface.
- * 
- * @since Android 1.0
- */
-public abstract class ImageInputStreamImpl implements ImageInputStream {
-
-    /**
-     * The byte order.
-     */
-    protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
-
-    /**
-     * The stream position.
-     */
-    protected long streamPos = 0;
-
-    /**
-     * The flushed position.
-     */
-    protected long flushedPos = 0;
-
-    /**
-     * The bit offset.
-     */
-    protected int bitOffset = 0;
-
-    /**
-     * The closed.
-     */
-    private boolean closed = false;
-
-    /**
-     * The position stack.
-     */
-    private final PositionStack posStack = new PositionStack();
-
-    /**
-     * Instantiates a new ImageInputStreamImpl.
-     */
-    public ImageInputStreamImpl() {
-    }
-
-    /**
-     * Check if the stream is closed and if true, throws an IOException.
-     * 
-     * @throws IOException
-     *             if the stream is closed.
-     */
-    protected final void checkClosed() throws IOException {
-        if (closed) {
-            throw new IOException("stream is closed");
-        }
-    }
-
-    public void setByteOrder(ByteOrder byteOrder) {
-        this.byteOrder = byteOrder;
-    }
-
-    public ByteOrder getByteOrder() {
-        return byteOrder;
-    }
-
-    public abstract int read() throws IOException;
-
-    public int read(byte[] b) throws IOException {
-        return read(b, 0, b.length);
-    }
-
-    public abstract int read(byte[] b, int off, int len) throws IOException;
-
-    public void readBytes(IIOByteBuffer buf, int len) throws IOException {
-        if (buf == null) {
-            throw new NullPointerException("buffer is NULL");
-        }
-
-        byte[] b = new byte[len];
-        len = read(b, 0, b.length);
-
-        buf.setData(b);
-        buf.setOffset(0);
-        buf.setLength(len);
-    }
-
-    public boolean readBoolean() throws IOException {
-        int b = read();
-        if (b < 0) {
-            throw new EOFException("EOF reached");
-        }
-        return b != 0;
-    }
-
-    public byte readByte() throws IOException {
-        int b = read();
-        if (b < 0) {
-            throw new EOFException("EOF reached");
-        }
-        return (byte)b;
-    }
-
-    public int readUnsignedByte() throws IOException {
-        int b = read();
-        if (b < 0) {
-            throw new EOFException("EOF reached");
-        }
-        return b;
-    }
-
-    public short readShort() throws IOException {
-        int b1 = read();
-        int b2 = read();
-
-        if (b1 < 0 || b2 < 0) {
-            throw new EOFException("EOF reached");
-        }
-
-        return byteOrder == ByteOrder.BIG_ENDIAN ? (short)((b1 << 8) | (b2 & 0xff))
-                : (short)((b2 << 8) | (b1 & 0xff));
-    }
-
-    public int readUnsignedShort() throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public char readChar() throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public int readInt() throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public long readUnsignedInt() throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public long readLong() throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public float readFloat() throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public double readDouble() throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public String readLine() throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public String readUTF() throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void readFully(byte[] b, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void readFully(byte[] b) throws IOException {
-        readFully(b, 0, b.length);
-    }
-
-    public void readFully(short[] s, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void readFully(char[] c, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void readFully(int[] i, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void readFully(long[] l, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void readFully(float[] f, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void readFully(double[] d, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public long getStreamPosition() throws IOException {
-        checkClosed();
-        return streamPos;
-    }
-
-    public int getBitOffset() throws IOException {
-        checkClosed();
-        return bitOffset;
-    }
-
-    public void setBitOffset(int bitOffset) throws IOException {
-        checkClosed();
-        this.bitOffset = bitOffset;
-    }
-
-    public int readBit() throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public long readBits(int numBits) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public long length() {
-        return -1L;
-    }
-
-    public int skipBytes(int n) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public long skipBytes(long n) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void seek(long pos) throws IOException {
-        checkClosed();
-        if (pos < getFlushedPosition()) {
-            throw new IllegalArgumentException("trying to seek before flushed pos");
-        }
-        bitOffset = 0;
-        streamPos = pos;
-    }
-
-    public void mark() {
-        try {
-            posStack.push(getStreamPosition());
-        } catch (IOException e) {
-            e.printStackTrace();
-            throw new RuntimeException("Stream marking error");
-        }
-    }
-
-    public void reset() throws IOException {
-        // -- TODO bit pos
-        if (!posStack.isEmpty()) {
-            long p = posStack.pop();
-            if (p < flushedPos) {
-                throw new IOException("marked position lies in the flushed portion of the stream");
-            }
-            seek(p);
-        }
-    }
-
-    public void flushBefore(long pos) throws IOException {
-        if (pos > getStreamPosition()) {
-            throw new IndexOutOfBoundsException("Trying to flush outside of current position");
-        }
-        if (pos < flushedPos) {
-            throw new IndexOutOfBoundsException("Trying to flush within already flushed portion");
-        }
-        flushedPos = pos;
-        // -- TODO implement
-    }
-
-    public void flush() throws IOException {
-        flushBefore(getStreamPosition());
-    }
-
-    public long getFlushedPosition() {
-        return flushedPos;
-    }
-
-    public boolean isCached() {
-        return false; // def
-    }
-
-    public boolean isCachedMemory() {
-        return false; // def
-    }
-
-    public boolean isCachedFile() {
-        return false; // def
-    }
-
-    public void close() throws IOException {
-        checkClosed();
-        closed = true;
-
-    }
-
-    /**
-     * Finalizes this object.
-     * 
-     * @throws Throwable
-     *             if an error occurs.
-     */
-    @Override
-    protected void finalize() throws Throwable {
-        if (!closed) {
-            try {
-                close();
-            } finally {
-                super.finalize();
-            }
-        }
-    }
-
-    /**
-     * The Class PositionStack.
-     */
-    private static class PositionStack {
-
-        /**
-         * The Constant SIZE.
-         */
-        private static final int SIZE = 10;
-
-        /**
-         * The values.
-         */
-        private long[] values = new long[SIZE];
-
-        /**
-         * The pos.
-         */
-        private int pos = 0;
-
-        /**
-         * Push.
-         * 
-         * @param v
-         *            the v.
-         */
-        void push(long v) {
-            if (pos >= values.length) {
-                ensure(pos + 1);
-            }
-            values[pos++] = v;
-        }
-
-        /**
-         * Pop.
-         * 
-         * @return the long.
-         */
-        long pop() {
-            return values[--pos];
-        }
-
-        /**
-         * Checks if is empty.
-         * 
-         * @return true, if is empty.
-         */
-        boolean isEmpty() {
-            return pos == 0;
-        }
-
-        /**
-         * Ensure.
-         * 
-         * @param size
-         *            the size.
-         */
-        private void ensure(int size) {
-            long[] arr = new long[Math.max(2 * values.length, size)];
-            System.arraycopy(values, 0, arr, 0, values.length);
-            values = arr;
-        }
-    }
-}
diff --git a/awt/javax/imageio/stream/ImageOutputStream.java b/awt/javax/imageio/stream/ImageOutputStream.java
deleted file mode 100644
index 28ec932..0000000
--- a/awt/javax/imageio/stream/ImageOutputStream.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.2 $
- */
-
-package javax.imageio.stream;
-
-import java.io.DataOutput;
-import java.io.IOException;
-
-/**
- * The ImageOutputStream represents output stream interface that is used by
- * ImageWriters.
- * 
- * @since Android 1.0
- */
-public interface ImageOutputStream extends DataOutput, ImageInputStream {
-
-    /**
-     * Writes a single byte to the stream at the current position.
-     * 
-     * @param b
-     *            the integer value, of which the 8 lowest bits will be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void write(int b) throws IOException;
-
-    /**
-     * Writes the bytes array to the stream.
-     * 
-     * @param b
-     *            the byte array to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void write(byte[] b) throws IOException;
-
-    /**
-     * Writes a number of bytes from the specified byte array beginning from the
-     * specified offset.
-     * 
-     * @param b
-     *            the byte array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of bytes to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void write(byte[] b, int off, int len) throws IOException;
-
-    /**
-     * Writes the specified boolean value to the stream, 1 if it is true, 0 if
-     * it is false.
-     * 
-     * @param b
-     *            the boolean value to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeBoolean(boolean b) throws IOException;
-
-    /**
-     * Writes the 8 lowest bits of the specified integer value to the stream.
-     * 
-     * @param b
-     *            the specified integer value.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeByte(int b) throws IOException;
-
-    /**
-     * Writes a short value to the output stream.
-     * 
-     * @param v
-     *            the short value to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeShort(int v) throws IOException;
-
-    /**
-     * Writes the 16 lowest bits of the specified integer value to the stream.
-     * 
-     * @param v
-     *            the specified integer value.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeChar(int v) throws IOException;
-
-    /**
-     * Writes an integer value to the output stream.
-     * 
-     * @param v
-     *            the integer value to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeInt(int v) throws IOException;
-
-    /**
-     * Write long.
-     * 
-     * @param v
-     *            the long value.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeLong(long v) throws IOException;
-
-    /**
-     * Writes a float value to the output stream.
-     * 
-     * @param v
-     *            the float which contains value to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeFloat(float v) throws IOException;
-
-    /**
-     * Writes a double value to the output stream.
-     * 
-     * @param v
-     *            the double which contains value to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeDouble(double v) throws IOException;
-
-    /**
-     * Writes the specified string to the stream.
-     * 
-     * @param s
-     *            the string to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeBytes(String s) throws IOException;
-
-    /**
-     * Writes the specified String to the output stream.
-     * 
-     * @param s
-     *            the String to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeChars(String s) throws IOException;
-
-    /**
-     * Writes 2 bytes to the output stream in the modified UTF-8 representation
-     * of every character of the specified string.
-     * 
-     * @param s
-     *            the specified string to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeUTF(String s) throws IOException;
-
-    /**
-     * Flushes the initial position in this stream prior to the specified stream
-     * position.
-     * 
-     * @param pos
-     *            the position.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void flushBefore(long pos) throws IOException;
-
-    /**
-     * Writes a len number of short values from the specified array to the
-     * stream.
-     * 
-     * @param s
-     *            the shorts array to be written.
-     * @param off
-     *            the offset in the char array.
-     * @param len
-     *            the length of chars to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeShorts(short[] s, int off, int len) throws IOException;
-
-    /**
-     * Writes a len number of chars to the stream.
-     * 
-     * @param c
-     *            the char array to be written.
-     * @param off
-     *            the offset in the char array.
-     * @param len
-     *            the length of chars to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeChars(char[] c, int off, int len) throws IOException;
-
-    /**
-     * Writes a len number of integer values from the specified array to the
-     * stream.
-     * 
-     * @param i
-     *            the integer array to be written.
-     * @param off
-     *            the offset in the char array.
-     * @param len
-     *            the length of chars to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeInts(int[] i, int off, int len) throws IOException;
-
-    /**
-     * Writes a len number of long values from the specified array to the
-     * stream.
-     * 
-     * @param l
-     *            the long array to be written.
-     * @param off
-     *            the offset in the char array.
-     * @param len
-     *            the length of chars to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeLongs(long[] l, int off, int len) throws IOException;
-
-    /**
-     * Writes a len number of float values from the specified array to the
-     * stream.
-     * 
-     * @param f
-     *            the float array to be written.
-     * @param off
-     *            the offset in the char array.
-     * @param len
-     *            the length of chars to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeFloats(float[] f, int off, int len) throws IOException;
-
-    /**
-     * Writes a len number of double values from the specified array to the
-     * stream.
-     * 
-     * @param d
-     *            the double array to be written.
-     * @param off
-     *            the offset in the char array.
-     * @param len
-     *            the length of chars to be written.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeDoubles(double[] d, int off, int len) throws IOException;
-
-    /**
-     * Writes a single bit at the current position.
-     * 
-     * @param bit
-     *            the integer whose least significant bit is to be written to
-     *            the stream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeBit(int bit) throws IOException;
-
-    /**
-     * Writes a sequence of bits beginning from the current position.
-     * 
-     * @param bits
-     *            the long value containing the bits to be written, starting
-     *            with the bit in position numBits - 1 down to the least
-     *            significant bit.
-     * @param numBits
-     *            the number of significant bit, it can be between 0 and 64.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeBits(long bits, int numBits) throws IOException;
-
-}
diff --git a/awt/javax/imageio/stream/ImageOutputStreamImpl.java b/awt/javax/imageio/stream/ImageOutputStreamImpl.java
deleted file mode 100644
index 0fef78f..0000000
--- a/awt/javax/imageio/stream/ImageOutputStreamImpl.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-package javax.imageio.stream;
-
-import java.io.IOException;
-import java.nio.ByteOrder;
-
-/* 
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-
-/**
- * The ImageOutputStreamImpl abstract class implements the ImageOutputStream
- * interface.
- * 
- * @since Android 1.0
- */
-public abstract class ImageOutputStreamImpl extends ImageInputStreamImpl implements
-        ImageOutputStream {
-
-    /**
-     * Instantiates a new ImageOutputStreamImpl.
-     */
-    public ImageOutputStreamImpl() {
-    }
-
-    public abstract void write(int b) throws IOException;
-
-    public void write(byte[] b) throws IOException {
-        write(b, 0, b.length);
-    }
-
-    public abstract void write(byte[] b, int off, int len) throws IOException;
-
-    public void writeBoolean(boolean v) throws IOException {
-        write(v ? 1 : 0);
-    }
-
-    public void writeByte(int v) throws IOException {
-        write(v);
-    }
-
-    public void writeShort(int v) throws IOException {
-        if (byteOrder == ByteOrder.BIG_ENDIAN) {
-
-        } else {
-
-        }
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeChar(int v) throws IOException {
-        writeShort(v);
-    }
-
-    public void writeInt(int v) throws IOException {
-        if (byteOrder == ByteOrder.BIG_ENDIAN) {
-
-        } else {
-
-        }
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeLong(long v) throws IOException {
-        if (byteOrder == ByteOrder.BIG_ENDIAN) {
-
-        } else {
-
-        }
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeFloat(float v) throws IOException {
-        writeInt(Float.floatToIntBits(v));
-    }
-
-    public void writeDouble(double v) throws IOException {
-        writeLong(Double.doubleToLongBits(v));
-    }
-
-    public void writeBytes(String s) throws IOException {
-        write(s.getBytes());
-    }
-
-    public void writeChars(String s) throws IOException {
-        char[] chs = s.toCharArray();
-        writeChars(chs, 0, chs.length);
-    }
-
-    public void writeUTF(String s) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeShorts(short[] s, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeChars(char[] c, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeInts(int[] i, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeLongs(long[] l, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeFloats(float[] f, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeDoubles(double[] d, int off, int len) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeBit(int bit) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    public void writeBits(long bits, int numBits) throws IOException {
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-
-    /**
-     * Flushes the bits. This method should be called in the write methods by
-     * subclasses.
-     * 
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    protected final void flushBits() throws IOException {
-        if (bitOffset == 0) {
-            return;
-        }
-
-        // -- TODO implement
-        throw new UnsupportedOperationException("Not implemented yet");
-    }
-}
diff --git a/awt/javax/imageio/stream/MemoryCacheImageInputStream.java b/awt/javax/imageio/stream/MemoryCacheImageInputStream.java
deleted file mode 100644
index d7fc791..0000000
--- a/awt/javax/imageio/stream/MemoryCacheImageInputStream.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.stream;
-
-import org.apache.harmony.x.imageio.stream.RandomAccessMemoryCache;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * The MemoryCacheImageInputStream class implements ImageInputStream using a
- * memory buffer for caching the data.
- * 
- * @since Android 1.0
- */
-public class MemoryCacheImageInputStream extends ImageInputStreamImpl {
-
-    /**
-     * The is.
-     */
-    private InputStream is;
-
-    /**
-     * The ramc.
-     */
-    private RandomAccessMemoryCache ramc = new RandomAccessMemoryCache();
-
-    /**
-     * Instantiates a new MemoryCacheImageInputStream which reads from the
-     * specified InputStream.
-     * 
-     * @param stream
-     *            the InputStream to be read.
-     */
-    public MemoryCacheImageInputStream(InputStream stream) {
-        if (stream == null) {
-            throw new IllegalArgumentException("stream == null!");
-        }
-        is = stream;
-    }
-
-    @Override
-    public int read() throws IOException {
-        bitOffset = 0;
-
-        if (streamPos >= ramc.length()) {
-            int count = (int)(streamPos - ramc.length() + 1);
-            int bytesAppended = ramc.appendData(is, count);
-
-            if (bytesAppended < count) {
-                return -1;
-            }
-        }
-
-        int res = ramc.getData(streamPos);
-        if (res >= 0) {
-            streamPos++;
-        }
-        return res;
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        bitOffset = 0;
-
-        if (streamPos >= ramc.length()) {
-            int count = (int)(streamPos - ramc.length() + len);
-            ramc.appendData(is, count);
-        }
-
-        int res = ramc.getData(b, off, len, streamPos);
-        if (res > 0) {
-            streamPos += res;
-        }
-        return res;
-    }
-
-    @Override
-    public boolean isCached() {
-        return true;
-    }
-
-    @Override
-    public boolean isCachedFile() {
-        return false;
-    }
-
-    @Override
-    public boolean isCachedMemory() {
-        return true;
-    }
-
-    @Override
-    public void close() throws IOException {
-        super.close();
-        ramc.close();
-    }
-
-    @Override
-    public void flushBefore(long pos) throws IOException {
-        super.flushBefore(pos);
-        ramc.freeBefore(getFlushedPosition());
-    }
-}
diff --git a/awt/javax/imageio/stream/MemoryCacheImageOutputStream.java b/awt/javax/imageio/stream/MemoryCacheImageOutputStream.java
deleted file mode 100644
index 1df40a3..0000000
--- a/awt/javax/imageio/stream/MemoryCacheImageOutputStream.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package javax.imageio.stream;
-
-import org.apache.harmony.x.imageio.stream.RandomAccessMemoryCache;
-
-import java.io.OutputStream;
-import java.io.IOException;
-
-/**
- * The MemoryCacheImageOutputStream class implements ImageOutputStream using a
- * memory buffer for caching the data.
- * 
- * @since Android 1.0
- */
-public class MemoryCacheImageOutputStream extends ImageOutputStreamImpl {
-
-    /**
-     * The os.
-     */
-    OutputStream os;
-
-    /**
-     * The ramc.
-     */
-    RandomAccessMemoryCache ramc = new RandomAccessMemoryCache();
-
-    /**
-     * Instantiates a new MemoryCacheImageOutputStream which writes to the
-     * specified OutputStream.
-     * 
-     * @param stream
-     *            the OutputStream.
-     */
-    public MemoryCacheImageOutputStream(OutputStream stream) {
-        if (stream == null) {
-            throw new IllegalArgumentException("stream == null!");
-        }
-        os = stream;
-    }
-
-    @Override
-    public void write(int b) throws IOException {
-        flushBits(); // See the flushBits method description
-
-        ramc.putData(b, streamPos);
-        streamPos++;
-    }
-
-    @Override
-    public void write(byte[] b, int off, int len) throws IOException {
-        flushBits(); // See the flushBits method description
-
-        ramc.putData(b, off, len, streamPos);
-        streamPos += len;
-    }
-
-    @Override
-    public int read() throws IOException {
-        bitOffset = 0;
-
-        int res = ramc.getData(streamPos);
-        if (res >= 0) {
-            streamPos++;
-        }
-        return res;
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        bitOffset = 0;
-
-        int res = ramc.getData(b, off, len, streamPos);
-        if (res > 0) {
-            streamPos += res;
-        }
-        return res;
-    }
-
-    @Override
-    public long length() {
-        return ramc.length();
-    }
-
-    @Override
-    public boolean isCached() {
-        return true;
-    }
-
-    @Override
-    public boolean isCachedMemory() {
-        return true;
-    }
-
-    @Override
-    public boolean isCachedFile() {
-        return false;
-    }
-
-    @Override
-    public void close() throws IOException {
-        flushBefore(length());
-        super.close();
-        ramc.close();
-    }
-
-    @Override
-    public void flushBefore(long pos) throws IOException {
-        long flushedPosition = getFlushedPosition();
-        super.flushBefore(pos);
-
-        long newFlushedPosition = getFlushedPosition();
-        int nBytes = (int)(newFlushedPosition - flushedPosition);
-
-        ramc.getData(os, nBytes, flushedPosition);
-        ramc.freeBefore(newFlushedPosition);
-
-        os.flush();
-    }
-}
diff --git a/awt/javax/imageio/stream/package.html b/awt/javax/imageio/stream/package.html
deleted file mode 100644
index 6cf53c3..0000000
--- a/awt/javax/imageio/stream/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes and interfaces for handling images with low-level I/O operations. 
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/org/apache/harmony/awt/ChoiceStyle.java b/awt/org/apache/harmony/awt/ChoiceStyle.java
deleted file mode 100644
index 93b7aad..0000000
--- a/awt/org/apache/harmony/awt/ChoiceStyle.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package org.apache.harmony.awt;
-
-/**
- * ChoiceStyle.
- * Is used to define custom choice properties:
- * width and x screen coordinate of the list popup window. 
- */
-public interface ChoiceStyle {
-
-    int getPopupX(int x, int width, int choiceWidth, int screenWidth);
-    int getPopupWidth(int choiceWidth);
-
-}
diff --git a/awt/org/apache/harmony/awt/ClipRegion.java b/awt/org/apache/harmony/awt/ClipRegion.java
deleted file mode 100644
index c89a81d..0000000
--- a/awt/org/apache/harmony/awt/ClipRegion.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov, Anton Avtamonov
- * @version $Revision$
- */
-package org.apache.harmony.awt;
-
-import java.awt.Component;
-import java.awt.Rectangle;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-public class ClipRegion extends Rectangle {
-    private final MultiRectArea clip;
-
-    public ClipRegion(final MultiRectArea clip) {
-        this.clip = new MultiRectArea(clip);
-        setBounds(clip.getBounds());
-    }
-
-    public MultiRectArea getClip() {
-        return clip;
-    }
-
-    @Override
-    public String toString() {
-        String str = clip.toString();
-        int i = str.indexOf('[');
-        str = str.substring(i);
-        if (clip.getRectCount() == 1) {
-            str = str.substring(1, str.length() - 1);
-        }
-        return getClass().getName() + str;
-    }
-
-
-    public void convertRegion(final Component child, final Component parent) {
-        convertRegion(child, clip, parent);
-    }
-
-    public void intersect(final Rectangle rect) {
-        clip.intersect(rect);
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return clip.isEmpty();
-    }
-
-    public static void convertRegion(final Component child,
-                                     final MultiRectArea region,
-                                     final Component parent) {
-        int x = 0, y = 0;
-        Component c = child;
-        //???AWT
-        /*
-        for (; c != null && c != parent; c = c.getParent()) {
-            x += c.getX();
-            y += c.getY();
-        }
-        */
-        if (c == null) {
-            // awt.51=Component expected to be a parent
-            throw new IllegalArgumentException(Messages.getString("awt.51")); //$NON-NLS-1$
-        }
-        region.translate(x, y);
-    }
-}
diff --git a/awt/org/apache/harmony/awt/ComponentInternals.java b/awt/org/apache/harmony/awt/ComponentInternals.java
deleted file mode 100644
index c359784..0000000
--- a/awt/org/apache/harmony/awt/ComponentInternals.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt;
-
-//???AWT
-//import java.awt.Component;
-//import java.awt.Container;
-//import java.awt.Dialog;
-import java.awt.Dimension;
-//import java.awt.Image;
-import java.awt.Insets;
-import java.awt.Point;
-import java.awt.Rectangle;
-//import java.awt.Window;
-//import java.awt.Choice;
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-//import org.apache.harmony.awt.text.TextFieldKit;
-//import org.apache.harmony.awt.text.TextKit;
-//import org.apache.harmony.awt.wtk.NativeWindow;
-
-import org.apache.harmony.luni.util.NotImplementedException;
-
-/**
- *  The accessor to AWT private API
- */
-public abstract class ComponentInternals {
-
-    /**
-     * @return the ComponentInternals instance to serve the requests
-     */
-    public static ComponentInternals getComponentInternals() {
-        return ContextStorage.getComponentInternals();
-    }
-
-    /**
-     * This method must be called by AWT to establish the connection
-     * @param internals - implementation of ComponentInternals created by AWT
-     */
-    public static void setComponentInternals(ComponentInternals internals) {
-        ContextStorage.setComponentInternals(internals);
-    }
-
-    /**
-     * The accessor to native resource connected to a component.
-     * It returns non-<code>null</code> value only if component
-     * already has the native resource
-     */
-    //public abstract NativeWindow getNativeWindow(Component component);
-
-    /**
-     * Connect Window object to existing native resource
-     * @param nativeWindowId - id of native window to attach
-     * @return Window object with special behaviour that
-     * restricts manupulation with that window
-     */
-    //public abstract Window attachNativeWindow(long nativeWindowId);
-
-    /**
-     * Start mouse grab in "client" mode.
-     * All mouse events in AWT components will be reported as usual,
-     * mouse events that occured outside of AWT components will be sent to
-     * the window passed as grabWindow parameter. When mouse grab is canceled
-     * (because of click in non-AWT window or by task switching)
-     * the whenCanceled callback is called
-     *
-     * @param grabWindow - window that will own the grab
-     * @param whenCanceled - callback called when grab is canceled by user's action
-     */
-    //public abstract void startMouseGrab(Window grabWindow, Runnable whenCanceled);
-
-    /**
-     * End mouse grab and resume normal processing of mouse events
-     */
-    //public abstract void endMouseGrab();
-
-    /**
-     * Set the <code>popup</code> flag of the window to true.
-     * This window won't be controlled by window manager on Linux.
-     * Call this method before the window is shown first time
-     * @param window - the window that should become popup one
-     */
-    //public abstract void makePopup(Window window);
-
-    /**
-     * This method must be called by Graphics at the beginning of drawImage()
-     * to store image drawing parameters (defined by application developer) in component
-     *
-     * @param comp - component that draws the image
-     * @param image - image to be drawn
-     * @param destLocation - location of the image upon the component's surface. Never null.
-     * @param destSize - size of the component's area to be filled with the image.
-     *                  Equals to null if size parameters omitted in drawImage.
-     * @param source - area of the image to be drawn on the component.
-     *                  Equals to null if src parameters omitted in drawImage.
-     */
-    /*
-    public abstract void onDrawImage(Component comp, Image image, Point destLocation,
-            Dimension destSize, Rectangle source);
-*/
-    /**
-     * Sets system's caret position.
-     * This method should be called by text component to synchronize our caret position
-     * with system's caret position.
-     * @param x
-     * @param y
-     */
-    //public abstract void setCaretPos(Component c, int x, int y);
-
-    /**
-     * NEVER USE IT. FORGET IT. IT DOES NOT EXIST.
-     * See Toolkit.unsafeInvokeAndWait(Runnable).
-     *
-     * Accessor for Toolkit.unsafeInvokeAndWait(Runnable) method.
-     * For use in exceptional cases only.
-     * Read comments for Toolkit.unsafeInvokeAndWait(Runnable) before use.
-     */
-    /*
-    public abstract void unsafeInvokeAndWait(Runnable runnable)
-            throws InterruptedException, InvocationTargetException;
-
-    public abstract TextKit getTextKit(Component comp);
-
-    public abstract void setTextKit(Component comp, TextKit kit);
-
-    public abstract TextFieldKit getTextFieldKit(Component comp);
-
-    public abstract void setTextFieldKit(Component comp, TextFieldKit kit);
-*/
-    /**
-     * Terminate event dispatch thread, completely destroy AWT context.<br>
-     * Intended for multi-context mode, in single-context mode does nothing.
-     *
-     */
-    public abstract void shutdown();
-
-    /**
-     * Sets mouse events preprocessor for event queue
-     */
-    //public abstract void setMouseEventPreprocessor(MouseEventPreprocessor preprocessor);
-
-    /**
-     * Create customized Choice using style
-     */
-    //public abstract Choice createCustomChoice(ChoiceStyle style);
-
-    //public abstract Insets getNativeInsets(Window w);
-
-    /**
-     * Region to be repainted (could be null). Use this in overridden repaint()
-     */
-    //public abstract MultiRectArea getRepaintRegion(Component c);
-
-    //public abstract MultiRectArea subtractPendingRepaintRegion(Component c, MultiRectArea mra);
-
-    /**
-     * Returns true if the window was at least once painted due to native paint events
-     */
-    //public abstract boolean wasPainted(Window w);
-
-    /**
-     * The component's region hidden behind top-level windows
-     * (belonging to both this Java app and all other apps), and behind
-     * heavyweight components overlapping with passed component
-     */
-    //public abstract MultiRectArea getObscuredRegion(Component c);
-    
-    /**
-     * An accessor to Container.addObscuredRegions() method
-     * @see java.awt.Container#addObscuredRegions(MultiRectArea, Component)
-     */
-    //public abstract void addObscuredRegions(MultiRectArea mra, Component c, Container container);
-    
-    /**
-     * Makes it possible to call protected Toolkit.setDesktopProperty()
-     * method from any class outside of java.awt package
-     */
-    public abstract void setDesktopProperty(String name, Object value);
-    
-    /**
-     * Makes it possible to start/stop dialog modal loop
-     * from anywhere outside of java.awt package
-     */
-    //public abstract void runModalLoop(Dialog dlg);
-    //public abstract void endModalLoop(Dialog dlg);
-    
-    /**
-     * Sets component's visible flag only
-     * (the component is not actually shown/hidden)
-     */
-    //public abstract void setVisibleFlag(Component comp, boolean visible);
-    
-}
diff --git a/awt/org/apache/harmony/awt/ContextStorage.java b/awt/org/apache/harmony/awt/ContextStorage.java
deleted file mode 100644
index d44648a..0000000
--- a/awt/org/apache/harmony/awt/ContextStorage.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt;
-
-import java.awt.*;
-
-//???AWT
-//import org.apache.harmony.awt.datatransfer.*;
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.awt.wtk.*;
-
-
-public final class ContextStorage {
-
-    private static volatile boolean multiContextMode = false;
-    private volatile boolean shutdownPending = false;
-
-    private static final ContextStorage globalContext = new ContextStorage();
-
-    private Toolkit toolkit;
-    private ComponentInternals componentInternals;
-    //???AWT: private DTK dtk;
-    private WTK wtk;
-    private GraphicsEnvironment graphicsEnvironment;
-
-    private class ContextLock {}
-    private final Object contextLock = new ContextLock();
-    private final Synchronizer synchronizer = new Synchronizer();
-
-    public static void activateMultiContextMode() {
-        // TODO: checkPermission
-        multiContextMode = true;
-    }
-
-    public static void setDefaultToolkit(Toolkit newToolkit) {
-        // TODO: checkPermission
-        getCurrentContext().toolkit = newToolkit;
-    }
-
-    public static Toolkit getDefaultToolkit() {
-        return getCurrentContext().toolkit;
-    }
-
-    //???AWT
-    /*
-    public static void setDTK(DTK dtk) {
-        // TODO: checkPermission
-        getCurrentContext().dtk = dtk;
-    }
-
-    public static DTK getDTK() {
-        return getCurrentContext().dtk;
-    }
-    */
-
-    public static Synchronizer getSynchronizer() {
-        return getCurrentContext().synchronizer;
-    }
-
-    public static ComponentInternals getComponentInternals() {
-        return getCurrentContext().componentInternals;
-    }
-
-    static void setComponentInternals(ComponentInternals internals) {
-        // TODO: checkPermission
-        getCurrentContext().componentInternals = internals;
-    }
-
-    public static Object getContextLock() {
-        return getCurrentContext().contextLock;
-    }
-
-    public static WindowFactory getWindowFactory() {
-        return getCurrentContext().wtk.getWindowFactory();
-    }
-
-    public static void setWTK(WTK wtk) {
-        getCurrentContext().wtk = wtk;
-    }
-
-    public static NativeIM getNativeIM() {
-        return getCurrentContext().wtk.getNativeIM();
-    }
-
-    public static NativeEventQueue getNativeEventQueue() {
-        return getCurrentContext().wtk.getNativeEventQueue();
-    }
-
-    public static GraphicsEnvironment getGraphicsEnvironment() {
-        return getCurrentContext().graphicsEnvironment;
-    }
-
-    public static void setGraphicsEnvironment(GraphicsEnvironment environment) {
-        getCurrentContext().graphicsEnvironment = environment;
-    }
-
-    private static ContextStorage getCurrentContext() {
-        return multiContextMode ? getContextThreadGroup().context : globalContext;
-    }
-
-    private static ContextThreadGroup getContextThreadGroup() {
-
-        Thread thread = Thread.currentThread();
-        ThreadGroup group = thread.getThreadGroup();
-        while (group != null) {
-            if (group instanceof ContextThreadGroup) {
-                return (ContextThreadGroup)group;
-            }
-            group = group.getParent();
-        }
-        // awt.59=Application has run out of context thread group
-        throw new RuntimeException(Messages.getString("awt.59")); //$NON-NLS-1$
-    }
-    
-    public static boolean shutdownPending() {
-        return getCurrentContext().shutdownPending;
-    }
-
-    void shutdown() {
-        if (!multiContextMode) {
-            return;
-        }
-        shutdownPending = true;
-
-        //???AWT: componentInternals.shutdown();
-
-        synchronized(contextLock) {
-            toolkit = null;
-            componentInternals = null;
-            //???AWT: dtk = null;
-            wtk = null;
-            graphicsEnvironment = null;
-        }
-    }
-    
-}
diff --git a/awt/org/apache/harmony/awt/ContextThreadGroup.java b/awt/org/apache/harmony/awt/ContextThreadGroup.java
deleted file mode 100644
index 4f0af52..0000000
--- a/awt/org/apache/harmony/awt/ContextThreadGroup.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt;
-
-public class ContextThreadGroup extends ThreadGroup {
-
-    final ContextStorage context = new ContextStorage();
-
-    public ContextThreadGroup(String name) {
-        super(name);
-    }
-
-    public void dispose() {
-        context.shutdown();
-    }
-}
diff --git a/awt/org/apache/harmony/awt/ListenerList.java b/awt/org/apache/harmony/awt/ListenerList.java
deleted file mode 100644
index f5c55f1..0000000
--- a/awt/org/apache/harmony/awt/ListenerList.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package org.apache.harmony.awt;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EventListener;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * List of AWT listeners. It is for 3 purposes.
- * 1. To support list modification from listeners
- * 2. To ensure call for all listeners as atomic operation
- * 3. To support system listeners that are needed for built-in AWT components
- */
-public class ListenerList<T extends EventListener> implements Serializable {
-    private static final long serialVersionUID = 9180703263299648154L;
-
-    private transient ArrayList<T> systemList;
-    private transient ArrayList<T> userList;
-    
-    public ListenerList() {
-        super();
-    }
-
-    /**
-     * Adds system listener to this list.
-     *
-     * @param listener - listener to be added.
-     */
-    public void addSystemListener(T listener) {
-        if (systemList == null) {
-            systemList = new ArrayList<T>();
-        }
-        systemList.add(listener);
-    }
-
-    /**
-     * Adds user (public) listener to this list.
-     *
-     * @param listener - listener to be added.
-     */
-    public void addUserListener(T listener) {
-        if (listener == null) {
-            return;
-        }
-        // transactionally replace old list
-        synchronized (this) {
-            if (userList == null) {
-                userList = new ArrayList<T>();
-                userList.add(listener);
-                return;
-            }
-            ArrayList<T> newList = new ArrayList<T>(userList);
-            newList.add(listener);
-            userList = newList;
-        }
-    }
-
-    /**
-     * Removes user (public) listener to this list.
-     *
-     * @param listener - listener to be removed.
-     */
-    public void removeUserListener(Object listener) {
-        if (listener == null) {
-            return;
-        }
-        // transactionally replace old list
-        synchronized (this) {
-            if (userList == null || !userList.contains(listener)) {
-                return;
-            }
-            ArrayList<T> newList = new ArrayList<T>(userList);
-            newList.remove(listener);
-            userList = (newList.size() > 0 ? newList : null);
-        }
-    }
-
-    /**
-     * Gets all user (public) listeners in one array.
-     *
-     * @param emptyArray - empty array, it's for deriving particular listeners class.
-     * @return array of all user listeners.
-     */
-    public <AT> AT[] getUserListeners(AT[] emptyArray){
-        synchronized (this) {
-            return (userList != null ? userList.toArray(emptyArray) : emptyArray);
-
-        }
-    }
-
-    /**
-     * Gets all user (public) listeners in one list.
-     *
-     * @return list of all user listeners.
-     */
-    public List<T> getUserListeners() {
-        synchronized (this) {
-            if (userList == null || userList.isEmpty()) {
-                return Collections.emptyList();
-            }
-            return new ArrayList<T>(userList);
-        }
-    }
-    
-    public List<T> getSystemListeners() {
-        synchronized (this) {
-            if (systemList == null || systemList.isEmpty()) {
-                return Collections.emptyList();
-            }
-            return new ArrayList<T>(systemList);
-        }
-    }
-
-    /**
-     * Gets iterator for user listeners.
-     *
-     * @return iterator for user listeners.
-     */
-    public Iterator<T> getUserIterator() {
-        synchronized (this) {
-            if (userList == null) {
-                List<T> emptyList = Collections.emptyList();
-                return emptyList.iterator();
-            }
-            return new ReadOnlyIterator<T>(userList.iterator());
-        }
-    }
-
-    /**
-     * Gets iterator for system listeners.
-     *
-     * @return iterator for system listeners.
-     */
-    public Iterator<T> getSystemIterator() {
-        return systemList.iterator();
-    }
-
-    private static ArrayList<?> getOnlySerializable(ArrayList<?> list) {
-        if (list == null) {
-            return null;
-        }
-
-        ArrayList<Object> result = new ArrayList<Object>();
-        for (Iterator<?> it = list.iterator(); it.hasNext();) {
-            Object obj = it.next();
-            if (obj instanceof Serializable) {
-                result.add(obj);
-            }
-        }
-
-        return (result.size() != 0) ? result : null;
-    }
-
-    private void writeObject(ObjectOutputStream stream) throws IOException {
-
-        stream.defaultWriteObject();
-
-        stream.writeObject(getOnlySerializable(systemList));
-        stream.writeObject(getOnlySerializable(userList));
-    }
-
-    @SuppressWarnings("unchecked")
-    private void readObject(ObjectInputStream stream)
-            throws IOException, ClassNotFoundException {
-
-        stream.defaultReadObject();
-
-        systemList = (ArrayList<T>)stream.readObject();
-        userList = (ArrayList<T>)stream.readObject();
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/ReadOnlyIterator.java b/awt/org/apache/harmony/awt/ReadOnlyIterator.java
deleted file mode 100644
index 671653f..0000000
--- a/awt/org/apache/harmony/awt/ReadOnlyIterator.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt;
-
-import java.util.Iterator;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * ReadOnlyIterator
- */
-public final class ReadOnlyIterator<E> implements Iterator<E> {
-
-    private final Iterator<E> it;
-
-    public ReadOnlyIterator(Iterator<E> it) {
-        if (it == null) {
-            throw new NullPointerException();
-        }
-        this.it = it;
-    }
-
-    public void remove() {
-        // awt.50=Iterator is read-only
-        throw new UnsupportedOperationException(Messages.getString("awt.50")); //$NON-NLS-1$
-    }
-
-    public boolean hasNext() {
-        return it.hasNext();
-    }
-
-    public E next() {
-        return it.next();
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/AwtImageBackdoorAccessor.java b/awt/org/apache/harmony/awt/gl/AwtImageBackdoorAccessor.java
deleted file mode 100644
index bd5f6c6..0000000
--- a/awt/org/apache/harmony/awt/gl/AwtImageBackdoorAccessor.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- * Created on 23.11.2005
- *
- */
-
-
-package org.apache.harmony.awt.gl;
-
-import java.awt.Image;
-import java.awt.image.DataBuffer;
-import java.awt.image.IndexColorModel;
-import java.awt.image.DataBufferInt;
-
-import org.apache.harmony.awt.gl.image.DataBufferListener;
-
-/**
- * This class give an opportunity to get access to private data of 
- * some java.awt.image classes 
- * Implementation of this class placed in java.awt.image package
- */
-
-public abstract class AwtImageBackdoorAccessor {
-
-    static protected AwtImageBackdoorAccessor inst;
-
-    public static AwtImageBackdoorAccessor getInstance(){
-        // First we need to run the static initializer in the DataBuffer class to resolve inst.
-        new DataBufferInt(0);
-        return inst;
-    }
-
-    public abstract Surface getImageSurface(Image image);
-    public abstract boolean isGrayPallete(IndexColorModel icm);
-
-    public abstract Object getData(DataBuffer db);
-    public abstract int[] getDataInt(DataBuffer db);
-    public abstract byte[] getDataByte(DataBuffer db);
-    public abstract short[] getDataShort(DataBuffer db);
-    public abstract short[] getDataUShort(DataBuffer db);
-    public abstract double[] getDataDouble(DataBuffer db);
-    public abstract float[] getDataFloat(DataBuffer db);
-    public abstract void releaseData(DataBuffer db);
-    
-    public abstract void addDataBufferListener(DataBuffer db, DataBufferListener listener);
-    public abstract void removeDataBufferListener(DataBuffer db);
-    public abstract void validate(DataBuffer db);
-}
diff --git a/awt/org/apache/harmony/awt/gl/CommonGraphics2D.java b/awt/org/apache/harmony/awt/gl/CommonGraphics2D.java
deleted file mode 100644
index a33c38b..0000000
--- a/awt/org/apache/harmony/awt/gl/CommonGraphics2D.java
+++ /dev/null
@@ -1,1132 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl;
-
-
-import java.awt.AlphaComposite;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.Paint;
-import java.awt.PaintContext;
-import java.awt.Point;
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphVector;
-import java.awt.image.AffineTransformOp;
-import java.awt.image.ImageObserver;
-import java.awt.image.BufferedImage;
-import java.awt.image.BufferedImageOp;
-import java.awt.image.Raster;
-import java.awt.image.RenderedImage;
-import java.awt.image.WritableRaster;
-import java.awt.image.renderable.RenderableImage;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.Line2D;
-import java.awt.geom.PathIterator;
-import java.awt.geom.RoundRectangle2D;
-import java.text.AttributedCharacterIterator;
-import java.util.Map;
-
-import org.apache.harmony.awt.gl.Surface;
-import org.apache.harmony.awt.gl.image.OffscreenImage;
-import org.apache.harmony.awt.gl.render.Blitter;
-import org.apache.harmony.awt.gl.render.JavaArcRasterizer;
-import org.apache.harmony.awt.gl.render.JavaLineRasterizer;
-import org.apache.harmony.awt.gl.render.JavaShapeRasterizer;
-import org.apache.harmony.awt.gl.render.JavaTextRenderer;
-import org.apache.harmony.awt.gl.render.NullBlitter;
-
-/*
- * List of abstract methods to implement in subclusses
- * Graphics.copyArea(int x, int y, int width, int height, int dx, int dy)
- * Graphics.create()
- * Graphics2D.getDeviceConfiguration()
- * CommonGraphics2D.fillMultiRectAreaColor(MultiRectArea mra);
- * CommonGraphics2D.fillMultiRectAreaPaint(MultiRectArea mra);
- */
-
-/**
- * CommonGraphics2D class is a super class for all system-dependent
- * implementations. It implements major part of Graphics and Graphics2D
- * abstract methods.
- * <h2>CommonGraphics2D Class Internals</h2>
- * <h3>Line and Shape Rasterizers</h3>
- * <p>
- * The CommonGraphics2D class splits all shapes into a set of rectangles 
- * to unify the drawing process for different operating systems and architectures. 
- * For this purpose Java 2D* uses the JavaShapeRasterizer and the JavaLineRasterizer 
- * classes from the org.apache.harmony.awt.gl.render package. The JavaShapeRasterizer 
- * class splits an object implementing a Shape interface into a set of rectangles and 
- * produces a MultiRectArea object. The JavaLineRasterizer class makes line drawing 
- * more accurate and processes lines with strokes, which are instances of the BasicStroke 
- * class.
- * </p>
- * <p>
- * To port the shape drawing to another platform you just need to override 
- * rectangle-drawing methods. However, if your operating system has functions to draw 
- * particular shapes, you can optimize your subclass of the CommonGraphics2D class by 
- * using this functionality in overridden methods.
- * </p>
-
- * <h3>Blitters</h3>
- * <p>
- * Blitter classes draw images on the display or buffered images. All blitters inherit 
- * the org.apache.harmony.awt.gl.render.Blitter interface.
- * </p>
- * <p>Blitters are divided into:
- * <ul>
- * <li>Native blitters for simple types of images, which the underlying native library 
- * can draw.</li> 
- * <li>Java* blitters for those types of images, which the underlying native library 
- * cannot handle.</li>
- * </ul></p>
- * <p>
- * DRL Java 2D* also uses blitters to fill the shapes and the user-defined subclasses 
- * of the java.awt.Paint class with paints, which the system does not support.
- * </p>
- *
- *<h3>Text Renderers</h3>
- *<p>
- *Text renderers draw strings and glyph vectors. All text renderers are subclasses 
- *of the org.apache.harmony.awt.gl.TextRenderer class.
- *</p>
- *
- */
-public abstract class CommonGraphics2D extends Graphics2D {
-    protected Surface dstSurf = null;
-    protected Blitter blitter = NullBlitter.getInstance();
-    protected RenderingHints hints = new RenderingHints(null);
-
-    // Clipping things
-    protected MultiRectArea clip = null;
-
-    protected Paint paint = Color.WHITE;
-    protected Color fgColor = Color.WHITE;
-    protected Color bgColor = Color.BLACK;
-
-    protected Composite composite = AlphaComposite.SrcOver;
-
-    protected Stroke stroke = new BasicStroke();
-
-    //TODO: Think more about FontRenderContext
-    protected FontRenderContext frc = new FontRenderContext(null, false, false);
-
-    protected JavaShapeRasterizer jsr = new JavaShapeRasterizer();
-
-    protected Font font = new Font("Dialog", Font.PLAIN, 12);; //$NON-NLS-1$
-
-    protected TextRenderer jtr = JavaTextRenderer.inst;
-
-    // Current graphics transform
-    protected AffineTransform transform = new AffineTransform();
-    protected double[] matrix = new double[6];
-
-    // Original user->device translation as transform and point
-    //public AffineTransform origTransform = new AffineTransform();
-    public Point origPoint = new Point(0, 0);
-
-
-    // Print debug output or not
-    protected static final boolean debugOutput = "1".equals(System.getProperty("g2d.debug")); //$NON-NLS-1$ //$NON-NLS-2$
-
-    // Constructors
-    protected CommonGraphics2D() {
-    }
-
-    protected CommonGraphics2D(int tx, int ty) {
-        this(tx, ty, null);
-    }
-
-    protected CommonGraphics2D(int tx, int ty, MultiRectArea clip) {
-        setTransform(AffineTransform.getTranslateInstance(tx, ty));
-        //origTransform = AffineTransform.getTranslateInstance(tx, ty);
-        origPoint = new Point(tx, ty);
-        setClip(clip);
-    }
-
-    // Public methods
-    @Override
-    public void addRenderingHints(Map<?,?> hints) {
-        this.hints.putAll(hints);
-    }
-
-    @Override
-    public void clearRect(int x, int y, int width, int height) {
-        Color c = getColor();
-        Paint p = getPaint();
-        setColor(getBackground());
-        fillRect(x, y, width, height);
-        setColor(c);
-        setPaint(p);
-        if (debugOutput) {
-            System.err.println("CommonGraphics2D.clearRect("+x+", "+y+", "+width+", "+height+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-        }
-    }
-
-    @Override
-    public void clipRect(int x, int y, int width, int height) {
-        clip(new Rectangle(x, y, width, height));
-    }
-
-
-    @Override
-    public void clip(Shape s) {
-        if (s == null) {
-            clip = null;
-            return;
-        }
-
-        MultiRectArea mra = null;
-        if (s instanceof MultiRectArea) {
-            mra = new MultiRectArea((MultiRectArea)s);
-            mra.translate((int)transform.getTranslateX(), (int)transform.getTranslateY());
-        } else {
-            int type = transform.getType();
-            if(s instanceof Rectangle && (type & (AffineTransform.TYPE_IDENTITY |
-                AffineTransform.TYPE_TRANSLATION)) != 0){
-                    mra = new MultiRectArea((Rectangle)s);
-                    if(type == AffineTransform.TYPE_TRANSLATION){
-                        mra.translate((int)transform.getTranslateX(), (int)transform.getTranslateY());
-                    }
-            } else {
-                s = transform.createTransformedShape(s);
-                mra = jsr.rasterize(s, 0.5);
-            }
-        }
-
-        if (clip == null) {
-            setTransformedClip(mra);
-        } else {
-            clip.intersect(mra);
-            setTransformedClip(clip);
-        }
-    }
-
-    @Override
-    public void dispose() {
-        // Do nothing for Java only classes
-    }
-
-
-
-
-    /***************************************************************************
-     *
-     *  Draw methods
-     *
-     ***************************************************************************/
-
-    @Override
-    public void draw(Shape s) {
-        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1) {
-            //TODO: Think about drawing the shape in one fillMultiRectArea call
-            BasicStroke bstroke = (BasicStroke)stroke;
-            JavaLineRasterizer.LineDasher ld = (bstroke.getDashArray() == null)?null:new JavaLineRasterizer.LineDasher(bstroke.getDashArray(), bstroke.getDashPhase());
-            PathIterator pi = s.getPathIterator(transform, 0.5);
-            float []points = new float[6];
-            int x1 = Integer.MIN_VALUE;
-            int y1 = Integer.MIN_VALUE;
-            int cx1 = Integer.MIN_VALUE;
-            int cy1 = Integer.MIN_VALUE;
-            while (!pi.isDone()) {
-                switch (pi.currentSegment(points)) {
-                    case PathIterator.SEG_MOVETO:
-                        x1 = (int)Math.floor(points[0]);
-                        y1 = (int)Math.floor(points[1]);
-                        cx1 = x1;
-                        cy1 = y1;
-                        break;
-                    case PathIterator.SEG_LINETO:
-                        int x2 = (int)Math.floor(points[0]);
-                        int y2 = (int)Math.floor(points[1]);
-                        fillMultiRectArea(JavaLineRasterizer.rasterize(x1, y1, x2, y2, null, ld, false));
-                        x1 = x2;
-                        y1 = y2;
-                        break;
-                    case PathIterator.SEG_CLOSE:
-                        x2 = cx1;
-                        y2 = cy1;
-                        fillMultiRectArea(JavaLineRasterizer.rasterize(x1, y1, x2, y2, null, ld, false));
-                        x1 = x2;
-                        y1 = y2;
-                        break;
-                }
-                pi.next();
-            }
-        } else {
-            s = stroke.createStrokedShape(s);
-            s = transform.createTransformedShape(s);
-            fillMultiRectArea(jsr.rasterize(s, 0.5));
-        }
-    }
-
-    @Override
-    public void drawArc(int x, int y, int width, int height, int sa, int ea) {
-        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1 &&
-                ((BasicStroke)stroke).getDashArray() == null && 
-                (transform.isIdentity() || transform.getType() == AffineTransform.TYPE_TRANSLATION)) {
-            Point p = new Point(x, y);
-            transform.transform(p, p);
-            MultiRectArea mra = JavaArcRasterizer.rasterize(x, y, width, height, sa, ea, clip);
-            fillMultiRectArea(mra);
-            return;
-        }
-        draw(new Arc2D.Float(x, y, width, height, sa, ea, Arc2D.OPEN));
-    }
-
-
-    @Override
-    public boolean drawImage(Image image, int x, int y, Color bgcolor,
-            ImageObserver imageObserver) {
-
-        if(image == null) {
-            return true;
-        }
-
-        boolean done = false;
-        boolean somebits = false;
-        Surface srcSurf = null;
-        if(image instanceof OffscreenImage){
-            OffscreenImage oi = (OffscreenImage) image;
-            if((oi.getState() & ImageObserver.ERROR) != 0) {
-                return false;
-            }
-            done = oi.prepareImage(imageObserver);
-            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
-            srcSurf = oi.getImageSurface();
-        }else{
-            done = true;
-            srcSurf = Surface.getImageSurface(image);
-        }
-
-        if(done || somebits) {
-            int w = srcSurf.getWidth();
-            int h = srcSurf.getHeight();
-            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, (AffineTransform) transform.clone(),
-                    composite, bgcolor, clip);
-        }
-        return done;
-    }
-
-    @Override
-    public boolean drawImage(Image image, int x, int y, ImageObserver imageObserver) {
-        return drawImage(image, x, y, null, imageObserver);
-    }
-
-    @Override
-    public boolean drawImage(Image image, int x, int y, int width, int height,
-            Color bgcolor, ImageObserver imageObserver) {
-
-        if(image == null) {
-            return true;
-        }
-        if(width == 0 || height == 0) {
-            return true;
-        }
-
-        boolean done = false;
-        boolean somebits = false;
-        Surface srcSurf = null;
-
-        if(image instanceof OffscreenImage){
-            OffscreenImage oi = (OffscreenImage) image;
-            if((oi.getState() & ImageObserver.ERROR) != 0) {
-                return false;
-            }
-            done = oi.prepareImage(imageObserver);
-            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
-            srcSurf = oi.getImageSurface();
-        }else{
-            done = true;
-            srcSurf = Surface.getImageSurface(image);
-        }
-
-        if(done || somebits) {
-            int w = srcSurf.getWidth();
-            int h = srcSurf.getHeight();
-            if(w == width && h == height){
-                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
-                        (AffineTransform) transform.clone(),
-                        composite, bgcolor, clip);
-            }else{
-                AffineTransform xform = new AffineTransform();
-                xform.setToScale((float)width / w, (float)height / h);
-                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
-                        (AffineTransform) transform.clone(),
-                        xform, composite, bgcolor, clip);
-            }
-        }
-        return done;
-    }
-
-    @Override
-    public boolean drawImage(Image image, int x, int y, int width, int height,
-            ImageObserver imageObserver) {
-        return drawImage(image, x, y, width, height, null, imageObserver);
-    }
-
-    @Override
-    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
-            int sx1, int sy1, int sx2, int sy2, Color bgcolor,
-            ImageObserver imageObserver) {
-
-        if(image == null) {
-            return true;
-        }
-        if(dx1 == dx2 || dy1 == dy2 || sx1 == sx2 || sy1 == sy2) {
-            return true;
-        }
-
-        boolean done = false;
-        boolean somebits = false;
-        Surface srcSurf = null;
-        if(image instanceof OffscreenImage){
-            OffscreenImage oi = (OffscreenImage) image;
-            if((oi.getState() & ImageObserver.ERROR) != 0) {
-                return false;
-            }
-            done = oi.prepareImage(imageObserver);
-            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
-            srcSurf = oi.getImageSurface();
-        }else{
-            done = true;
-            srcSurf = Surface.getImageSurface(image);
-        }
-
-        if(done || somebits) {
-
-            int dstX = dx1;
-            int dstY = dy1;
-            int srcX = sx1;
-            int srcY = sy1;
-
-            int dstW = dx2 - dx1;
-            int dstH = dy2 - dy1;
-            int srcW = sx2 - sx1;
-            int srcH = sy2 - sy1;
-
-            if(srcW == dstW && srcH == dstH){
-                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
-                        (AffineTransform) transform.clone(),
-                        composite, bgcolor, clip);
-            }else{
-                AffineTransform xform = new AffineTransform();
-                xform.setToScale((float)dstW / srcW, (float)dstH / srcH);
-                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
-                        (AffineTransform) transform.clone(),
-                        xform, composite, bgcolor, clip);
-            }
-        }
-        return done;
-    }
-
-    @Override
-    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
-            int sx1, int sy1, int sx2, int sy2, ImageObserver imageObserver) {
-
-        return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
-                imageObserver);
-     }
-
-    @Override
-    public void drawImage(BufferedImage bufImage, BufferedImageOp op,
-            int x, int y) {
-
-        if(bufImage == null) {
-            return;
-        }
-
-        if(op == null) {
-            drawImage(bufImage, x, y, null);
-        } else if(op instanceof AffineTransformOp){
-            AffineTransformOp atop = (AffineTransformOp) op;
-            AffineTransform xform = atop.getTransform();
-            Surface srcSurf = Surface.getImageSurface(bufImage);
-            int w = srcSurf.getWidth();
-            int h = srcSurf.getHeight();
-            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
-                    (AffineTransform) transform.clone(), xform,
-                    composite, null, clip);
-        } else {
-            bufImage = op.filter(bufImage, null);
-            Surface srcSurf = Surface.getImageSurface(bufImage);
-            int w = srcSurf.getWidth();
-            int h = srcSurf.getHeight();
-            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
-                    (AffineTransform) transform.clone(),
-                    composite, null, clip);
-        }
-    }
-
-    @Override
-    public boolean drawImage(Image image, AffineTransform trans,
-            ImageObserver imageObserver) {
-
-        if(image == null) {
-            return true;
-        }
-        if(trans == null || trans.isIdentity()) {
-            return drawImage(image, 0, 0, imageObserver);
-        }
-
-        boolean done = false;
-        boolean somebits = false;
-        Surface srcSurf = null;
-        if(image instanceof OffscreenImage){
-            OffscreenImage oi = (OffscreenImage) image;
-            if((oi.getState() & ImageObserver.ERROR) != 0) {
-                return false;
-            }
-            done = oi.prepareImage(imageObserver);
-            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
-            srcSurf = oi.getImageSurface();
-        }else{
-            done = true;
-            srcSurf = Surface.getImageSurface(image);
-        }
-
-        if(done || somebits) {
-            int w = srcSurf.getWidth();
-            int h = srcSurf.getHeight();
-            AffineTransform xform = (AffineTransform) transform.clone();
-            xform.concatenate(trans);
-            blitter.blit(0, 0, srcSurf, 0, 0, dstSurf, w, h, xform, composite,
-                    null, clip);
-        }
-        return done;
-    }
-
-    @Override
-    public void drawLine(int x1, int y1, int x2, int y2) {
-        if (debugOutput) {
-            System.err.println("CommonGraphics2D.drawLine("+x1+", "+y1+", "+x2+", "+y2+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-        }
-
-        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1) {
-            BasicStroke bstroke = (BasicStroke)stroke;
-            Point p1 = new Point(x1, y1);
-            Point p2 = new Point(x2, y2);
-            transform.transform(p1, p1);
-            transform.transform(p2, p2);
-            JavaLineRasterizer.LineDasher ld = (bstroke.getDashArray() == null)?null:new JavaLineRasterizer.LineDasher(bstroke.getDashArray(), bstroke.getDashPhase());
-            MultiRectArea mra = JavaLineRasterizer.rasterize(p1.x, p1.y, p2.x, p2.y, null, ld, false);
-            fillMultiRectArea(mra);
-            return;
-        }
-        draw(new Line2D.Float(x1, y1, x2, y2));
-    }
-
-    @Override
-    public void drawOval(int x, int y, int width, int height) {
-        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1 &&
-                ((BasicStroke)stroke).getDashArray() == null && 
-                (transform.isIdentity() || transform.getType() == AffineTransform.TYPE_TRANSLATION)) {
-            Point p = new Point(x, y);
-            transform.transform(p, p);
-            MultiRectArea mra = JavaArcRasterizer.rasterize(x, y, width, height, 0, 360, clip);
-            fillMultiRectArea(mra);
-            return;
-        }
-        draw(new Ellipse2D.Float(x, y, width, height));
-    }
-
-    @Override
-    public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) {
-        draw(new Polygon(xpoints, ypoints, npoints));
-    }
-
-    @Override
-    public void drawPolygon(Polygon polygon) {
-        draw(polygon);
-    }
-
-    @Override
-    public void drawPolyline(int[] xpoints, int[] ypoints, int npoints) {
-        for (int i = 0; i < npoints-1; i++) {
-            drawLine(xpoints[i], ypoints[i], xpoints[i+1], ypoints[i+1]);
-        }
-    }
-
-    @Override
-    public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
-        if (img == null) {
-            return;
-        }
-
-        double scaleX = xform.getScaleX();
-        double scaleY = xform.getScaleY();
-        if (scaleX == 1 && scaleY == 1) {
-            drawRenderedImage(img.createDefaultRendering(), xform);
-        } else {
-            int width = (int)Math.round(img.getWidth()*scaleX);
-            int height = (int)Math.round(img.getHeight()*scaleY);
-            xform = (AffineTransform)xform.clone();
-            xform.scale(1, 1);
-            drawRenderedImage(img.createScaledRendering(width, height, null), xform);
-        }
-    }
-
-    @Override
-    public void drawRenderedImage(RenderedImage rimg, AffineTransform xform) {
-        if (rimg == null) {
-            return;
-        }
-
-        Image img = null;
-
-        if (rimg instanceof Image) {
-            img = (Image)rimg;
-        } else {
-            //TODO: Create new class to provide Image interface for RenderedImage or rewrite this method
-            img = new BufferedImage(rimg.getColorModel(), rimg.copyData(null), false, null);
-        }
-
-        drawImage(img, xform, null);
-    }
-
-    @Override
-    public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
-        if (debugOutput) {
-            System.err.println("CommonGraphics2D.drawRoundRect("+x+", "+y+", "+width+", "+height+","+arcWidth+", "+arcHeight+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
-        }
-
-        draw(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
-    }
-
-
-
-
-
-    /***************************************************************************
-     *
-     *  String methods
-     *
-     ***************************************************************************/
-
-    @Override
-    public void drawString(AttributedCharacterIterator iterator, float x, float y) {
-        GlyphVector gv = font.createGlyphVector(frc, iterator);
-        drawGlyphVector(gv, x, y);
-    }
-
-    @Override
-    public void drawString(AttributedCharacterIterator iterator, int x, int y) {
-        drawString(iterator, (float)x, (float)y);
-    }
-
-    @Override
-    public void drawString(String str, int x, int y) {
-        drawString(str, (float)x, (float)y);
-    }
-
-    @Override
-    public void drawString(String str, float x, float y) {
-        if (debugOutput) {
-            System.err.println("CommonGraphics2D.drawString("+str+", "+x+", "+y+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-        }
-
-        AffineTransform at = (AffineTransform)this.getTransform().clone();
-        AffineTransform fontTransform = font.getTransform();
-        at.concatenate(fontTransform);
-
-        double[] matrix = new double[6];
-        if (!at.isIdentity()){
-
-            int atType = at.getType();
-            at.getMatrix(matrix);
-
-            // TYPE_TRANSLATION
-            if (atType == AffineTransform.TYPE_TRANSLATION){
-                jtr.drawString(this, str,
-                        (float)(x+fontTransform.getTranslateX()),
-                        (float)(y+fontTransform.getTranslateY()));
-                return;
-            }
-            // TODO: we use slow type of drawing strings when Font object
-            // in Graphics has transforms, we just fill outlines. New textrenderer
-            // is to be implemented.
-            Shape sh = font.createGlyphVector(this.getFontRenderContext(), str).getOutline(x, y);
-            this.fill(sh);
-
-        } else {
-            jtr.drawString(this, str, x, y);
-        }
-
-    }
-
-    @Override
-    public void drawGlyphVector(GlyphVector gv, float x, float y) {
-
-        AffineTransform at = gv.getFont().getTransform();
-
-        double[] matrix = new double[6];
-        if ((at != null) && (!at.isIdentity())){
-
-            int atType = at.getType();
-            at.getMatrix(matrix);
-
-            // TYPE_TRANSLATION
-            if ((atType == AffineTransform.TYPE_TRANSLATION) &&
-                ((gv.getLayoutFlags() & GlyphVector.FLAG_HAS_TRANSFORMS) == 0)){
-                jtr.drawGlyphVector(this, gv, (int)(x+matrix[4]), (int)(y+matrix[5]));
-                return;
-            }
-        } else {
-            if (((gv.getLayoutFlags() & GlyphVector.FLAG_HAS_TRANSFORMS) == 0)){
-                jtr.drawGlyphVector(this, gv, x, y);
-                return;
-            }
-        }
-
-        // TODO: we use slow type of drawing strings when Font object
-        // in Graphics has transforms, we just fill outlines. New textrenderer
-        // is to be implemented.
-
-        Shape sh = gv.getOutline(x, y);
-        this.fill(sh);
-
-        }
-
-
-
-
-    /***************************************************************************
-     *
-     *  Fill methods
-     *
-     ***************************************************************************/
-
-    @Override
-    public void fill(Shape s) {
-        s = transform.createTransformedShape(s);
-        MultiRectArea mra = jsr.rasterize(s, 0.5);
-        fillMultiRectArea(mra);
-    }
-
-    @Override
-    public void fillArc(int x, int y, int width, int height, int sa, int ea) {
-        fill(new Arc2D.Float(x, y, width, height, sa, ea, Arc2D.PIE));
-    }
-
-    @Override
-    public void fillOval(int x, int y, int width, int height) {
-        fill(new Ellipse2D.Float(x, y, width, height));
-    }
-
-    @Override
-    public void fillPolygon(int[] xpoints, int[] ypoints, int npoints) {
-        fill(new Polygon(xpoints, ypoints, npoints));
-    }
-
-    @Override
-    public void fillPolygon(Polygon polygon) {
-        fill(polygon);
-    }
-
-    @Override
-    public void fillRect(int x, int y, int width, int height) {
-        if (debugOutput) {
-            System.err.println("CommonGraphics2D.fillRect("+x+", "+y+", "+width+", "+height+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-        }
-
-        fill(new Rectangle(x, y, width, height));
-    }
-
-    @Override
-    public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
-        if (debugOutput) {
-            System.err.println("CommonGraphics2D.fillRoundRect("+x+", "+y+", "+width+", "+height+","+arcWidth+", "+arcHeight+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
-        }
-
-        fill(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
-    }
-
-
-
-
-    /***************************************************************************
-     *
-     *  Get methods
-     *
-     ***************************************************************************/
-
-    @Override
-    public Color getBackground() {
-        return bgColor;
-    }
-
-    @Override
-    public Shape getClip() {
-        if (clip == null) {
-            return null;
-        }
-
-        MultiRectArea res = new MultiRectArea(clip);
-        res.translate(-Math.round((float)transform.getTranslateX()), -Math.round((float)transform.getTranslateY()));
-        return res;
-    }
-
-    @Override
-    public Rectangle getClipBounds() {
-        if (clip == null) {
-            return null;
-        }
-
-        Rectangle res = (Rectangle) clip.getBounds().clone();
-        res.translate(-Math.round((float)transform.getTranslateX()), -Math.round((float)transform.getTranslateY()));
-        return res;
-    }
-
-    @Override
-    public Color getColor() {
-        return fgColor;
-    }
-
-    @Override
-    public Composite getComposite() {
-        return composite;
-    }
-
-    @Override
-    public Font getFont() {
-        return font;
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    public FontMetrics getFontMetrics(Font font) {
-        return Toolkit.getDefaultToolkit().getFontMetrics(font);
-    }
-
-    @Override
-    public FontRenderContext getFontRenderContext() {
-        return frc;
-    }
-
-    @Override
-    public Paint getPaint() {
-        return paint;
-    }
-
-    @Override
-    public Object getRenderingHint(RenderingHints.Key key) {
-        return hints.get(key);
-    }
-
-    @Override
-    public RenderingHints getRenderingHints() {
-        return hints;
-    }
-
-    @Override
-    public Stroke getStroke() {
-        return stroke;
-    }
-
-    @Override
-    public AffineTransform getTransform() {
-        return (AffineTransform)transform.clone();
-    }
-
-    @Override
-    public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
-        //TODO: Implement method....
-        return false;
-    }
-
-
-
-
-    /***************************************************************************
-     *
-     *  Transformation methods
-     *
-     ***************************************************************************/
-
-    @Override
-    public void rotate(double theta) {
-        transform.rotate(theta);
-        transform.getMatrix(matrix);
-    }
-
-    @Override
-    public void rotate(double theta, double x, double y) {
-        transform.rotate(theta, x, y);
-        transform.getMatrix(matrix);
-    }
-
-    @Override
-    public void scale(double sx, double sy) {
-        transform.scale(sx, sy);
-        transform.getMatrix(matrix);
-    }
-
-    @Override
-    public void shear(double shx, double shy) {
-        transform.shear(shx, shy);
-        transform.getMatrix(matrix);
-    }
-
-    @Override
-    public void transform(AffineTransform at) {
-        transform.concatenate(at);
-        transform.getMatrix(matrix);
-    }
-
-    @Override
-    public void translate(double tx, double ty) {
-        if (debugOutput) {
-            System.err.println("CommonGraphics2D.translate("+tx+", "+ty+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-
-        transform.translate(tx, ty);
-        transform.getMatrix(matrix);
-    }
-
-    @Override
-    public void translate(int tx, int ty) {
-        if (debugOutput) {
-            System.err.println("CommonGraphics2D.translate("+tx+", "+ty+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        }
-
-        transform.translate(tx, ty);
-        transform.getMatrix(matrix);
-    }
-
-
-
-
-    /***************************************************************************
-     *
-     *  Set methods
-     *
-     ***************************************************************************/
-
-    @Override
-    public void setBackground(Color color) {
-        bgColor = color;
-    }
-
-    @Override
-    public void setClip(int x, int y, int width, int height) {
-        setClip(new Rectangle(x, y, width, height));
-    }
-
-    @Override
-    public void setClip(Shape s) {
-        if (s == null) {
-            setTransformedClip(null);
-            if (debugOutput) {
-                System.err.println("CommonGraphics2D.setClip(null)"); //$NON-NLS-1$
-            }
-            return;
-        }
-
-        if (debugOutput) {
-            System.err.println("CommonGraphics2D.setClip("+s.getBounds()+")"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        if (s instanceof MultiRectArea) {
-            MultiRectArea nclip = new MultiRectArea((MultiRectArea)s);
-            nclip.translate(Math.round((float)transform.getTranslateX()), Math.round((float)transform.getTranslateY()));
-            setTransformedClip(nclip);
-        } else {
-            int type = transform.getType();
-            if(s instanceof Rectangle && (type & (AffineTransform.TYPE_IDENTITY |
-                AffineTransform.TYPE_TRANSLATION)) != 0){
-                    MultiRectArea nclip = new MultiRectArea((Rectangle)s);
-                    if(type == AffineTransform.TYPE_TRANSLATION){
-                        nclip.translate((int)transform.getTranslateX(), (int)transform.getTranslateY());
-                    }
-                    setTransformedClip(nclip);
-            } else {
-                s = transform.createTransformedShape(s);
-                setTransformedClip(jsr.rasterize(s, 0.5));
-            }
-        }
-    }
-
-    @Override
-    public void setColor(Color color) {
-        if (color != null) {
-            fgColor = color;
-            paint = color;
-        }
-    }
-
-    @Override
-    public void setComposite(Composite composite) {
-        this.composite = composite;
-    }
-
-    @Override
-    public void setFont(Font font) {
-        this.font = font;
-    }
-
-    @Override
-    public void setPaint(Paint paint) {
-        if (paint == null)
-            return;
-            
-        this.paint = paint;
-        if (paint instanceof Color) {
-            fgColor = (Color)paint;
-        }
-    }
-
-    @Override
-    public void setPaintMode() {
-        composite = AlphaComposite.SrcOver;
-    }
-
-    @Override
-    public void setRenderingHint(RenderingHints.Key key, Object value) {
-        hints.put(key, value);
-    }
-
-    @Override
-    public void setRenderingHints(Map<?,?> hints) {
-        this.hints.clear();
-        this.hints.putAll(hints);
-    }
-
-    @Override
-    public void setStroke(Stroke stroke) {
-        this.stroke = stroke;
-    }
-
-    @Override
-    public void setTransform(AffineTransform transform) {
-        this.transform = transform;
-
-        transform.getMatrix(matrix);
-    }
-
-    @Override
-    public void setXORMode(Color color) {
-        composite = new XORComposite(color);
-    }
-
-
-    // Protected methods
-    protected void setTransformedClip(MultiRectArea clip) {
-        this.clip = clip;
-    }
-
-    /**
-     * This method fills the given MultiRectArea with current paint.
-     * It calls fillMultiRectAreaColor and fillMultiRectAreaPaint 
-     * methods depending on the type of current paint.
-     * @param mra MultiRectArea to fill
-     */
-    protected void fillMultiRectArea(MultiRectArea mra) {
-        if (clip != null) {
-            mra.intersect(clip);
-        }
-
-        // Return if all stuff is clipped
-        if (mra.rect[0] < 5) {
-            return;
-        }
-
-        if (debugOutput) {
-            System.err.println("CommonGraphics2D.fillMultiRectArea("+mra+")"); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        if (paint instanceof Color){
-            fillMultiRectAreaColor(mra);
-        }else{
-            fillMultiRectAreaPaint(mra);
-        }
-    }
-
-    /**
-     * This method fills the given MultiRectArea with solid color.
-     * @param mra MultiRectArea to fill
-     */
-    protected void fillMultiRectAreaColor(MultiRectArea mra) {
-        fillMultiRectAreaPaint(mra);
-    }
-
-    /**
-     * This method fills the given MultiRectArea with any paint.
-     * @param mra MultiRectArea to fill
-     */
-    protected void fillMultiRectAreaPaint(MultiRectArea mra) {
-        Rectangle rec = mra.getBounds();
-        int x = rec.x;
-        int y = rec.y;
-        int w = rec.width;
-        int h = rec.height;
-        if(w <= 0 || h <= 0) {
-            return;
-        }
-        PaintContext pc = paint.createContext(null, rec, rec, transform, hints);
-        Raster r = pc.getRaster(x, y, w, h);
-        WritableRaster wr;
-        if(r instanceof WritableRaster){
-            wr = (WritableRaster) r;
-        }else{
-            wr = r.createCompatibleWritableRaster();
-            wr.setRect(r);
-        }
-        Surface srcSurf = new ImageSurface(pc.getColorModel(), wr);
-        blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
-                composite, null, mra);
-        srcSurf.dispose();
-    }
-
-    /**
-     * Copies graphics class fields. 
-     * Used in create method
-     * 
-     * @param copy Graphics class to copy
-     */
-    protected void copyInternalFields(CommonGraphics2D copy) {
-        if (clip == null) {
-            copy.setTransformedClip(null);
-        } else {
-            copy.setTransformedClip(new MultiRectArea(clip));
-        }
-        copy.setBackground(bgColor);
-        copy.setColor(fgColor);
-        copy.setPaint(paint);
-        copy.setComposite(composite);
-        copy.setStroke(stroke);
-        copy.setFont(font);
-        copy.setTransform(new AffineTransform(transform));
-        //copy.origTransform = new AffineTransform(origTransform);
-        copy.origPoint = new Point(origPoint);
-    }
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/CommonGraphics2DFactory.java b/awt/org/apache/harmony/awt/gl/CommonGraphics2DFactory.java
deleted file mode 100644
index 27e3ef0..0000000
--- a/awt/org/apache/harmony/awt/gl/CommonGraphics2DFactory.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko, Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.peer.FontPeer;
-
-import org.apache.harmony.awt.gl.font.FontMetricsImpl;
-import org.apache.harmony.awt.wtk.GraphicsFactory;
-
-/**
- * Common GraphicsFactory implementation
- *
- */
-public abstract class CommonGraphics2DFactory implements GraphicsFactory {
-    
-    // static instance of CommonGraphics2DFactory
-    public static CommonGraphics2DFactory inst;
-
-    /**
-     * Returns FontMetrics object that keeps metrics of the specified font.
-     * 
-     * @param font specified Font
-     * @return FontMetrics object corresponding to the specified Font object
-     */
-    public FontMetrics getFontMetrics(Font font) {
-        FontMetrics fm;
-        for (FontMetrics element : cacheFM) {
-            fm = element;
-            if (fm == null){
-                break;
-            }
-
-            if (fm.getFont().equals(font)){
-                return fm;
-            }
-        }
-        fm = new FontMetricsImpl(font);
-
-        System.arraycopy(cacheFM, 0, cacheFM, 1, cacheFM.length -1);
-        cacheFM[0] = fm;
-
-        return fm;
-    }
-    // Font methods
-
-    public FontPeer getFontPeer(Font font) {
-        return getFontManager().getFontPeer(font.getName(), font.getStyle(), font.getSize());
-    }
-    
-    /**
-     * Embeds font from gile with specified path into the system. 
-     * 
-     * @param fontFilePath path to the font file 
-     * @return Font object that was created from the file.
-     */
-    public abstract Font embedFont(String fontFilePath);
-
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/CommonGraphicsEnvironment.java b/awt/org/apache/harmony/awt/gl/CommonGraphicsEnvironment.java
deleted file mode 100644
index 5c78e50..0000000
--- a/awt/org/apache/harmony/awt/gl/CommonGraphicsEnvironment.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko, Oleg V. Khaschansky
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.GraphicsEnvironment;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Locale;
-
-import org.apache.harmony.awt.gl.image.BufferedImageGraphics2D;
-
-/**
- * Common GraphicsEnvironment implementation
- *
- */
-public abstract class CommonGraphicsEnvironment extends GraphicsEnvironment {
-
-    @Override
-    public Graphics2D createGraphics(BufferedImage bufferedImage) {
-        return new BufferedImageGraphics2D(bufferedImage);
-    }
-
-    @Override
-    public String[] getAvailableFontFamilyNames(Locale locale) {
-        Font[] fonts = getAllFonts();
-        ArrayList<String> familyNames = new ArrayList<String>();
-
-        for (Font element : fonts) {
-            String name = element.getFamily(locale);
-            if (!familyNames.contains(name)) {
-                familyNames.add(name);
-            }
-        }
-
-        return familyNames.toArray(new String[familyNames.size()]);
-    }
-
-    @Override
-    public Font[] getAllFonts() {
-        return CommonGraphics2DFactory.inst.getFontManager().getAllFonts();
-    }
-
-    @Override
-    public String[] getAvailableFontFamilyNames() {
-        return CommonGraphics2DFactory.inst.getFontManager().getAllFamilies();
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/Crossing.java b/awt/org/apache/harmony/awt/gl/Crossing.java
deleted file mode 100644
index ae7fb0e..0000000
--- a/awt/org/apache/harmony/awt/gl/Crossing.java
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.Shape;
-import java.awt.geom.PathIterator;
-
-public class Crossing {
-
-    /**
-     * Allowable tolerance for bounds comparison
-     */
-    static final double DELTA = 1E-5;
-    
-    /**
-     * If roots have distance less then <code>ROOT_DELTA</code> they are double
-     */
-    static final double ROOT_DELTA = 1E-10;
-    
-    /**
-     * Rectangle cross segment
-     */
-    public static final int CROSSING = 255;
-    
-    /**
-     * Unknown crossing result
-     */
-    static final int UNKNOWN = 254;
-
-    /**
-     * Solves quadratic equation
-     * @param eqn - the coefficients of the equation
-     * @param res - the roots of the equation
-     * @return a number of roots
-     */
-    public static int solveQuad(double eqn[], double res[]) {
-        double a = eqn[2];
-        double b = eqn[1];
-        double c = eqn[0];
-        int rc = 0;
-        if (a == 0.0) {
-            if (b == 0.0) {
-                return -1;
-            }
-            res[rc++] = -c / b;
-        } else {
-            double d = b * b - 4.0 * a * c;
-            // d < 0.0
-            if (d < 0.0) {
-                return 0;
-            }
-            d = Math.sqrt(d);
-            res[rc++] = (- b + d) / (a * 2.0);
-            // d != 0.0
-            if (d != 0.0) {
-                res[rc++] = (- b - d) / (a * 2.0);
-            }
-        }
-        return fixRoots(res, rc);
-    }
-
-    /**
-     * Solves cubic equation
-     * @param eqn - the coefficients of the equation
-     * @param res - the roots of the equation
-     * @return a number of roots
-     */
-    public static int solveCubic(double eqn[], double res[]) {
-        double d = eqn[3];
-        if (d == 0) {
-            return solveQuad(eqn, res);
-        }
-        double a = eqn[2] / d;
-        double b = eqn[1] / d;
-        double c = eqn[0] / d;
-        int rc = 0;
-
-        double Q = (a * a - 3.0 * b) / 9.0;
-        double R = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;
-        double Q3 = Q * Q * Q;
-        double R2 = R * R;
-        double n = - a / 3.0;
-
-        if (R2 < Q3) {
-            double t = Math.acos(R / Math.sqrt(Q3)) / 3.0;
-            double p = 2.0 * Math.PI / 3.0;
-            double m = -2.0 * Math.sqrt(Q);
-            res[rc++] = m * Math.cos(t) + n;
-            res[rc++] = m * Math.cos(t + p) + n;
-            res[rc++] = m * Math.cos(t - p) + n;
-        } else {
-//          Debug.println("R2 >= Q3 (" + R2 + "/" + Q3 + ")");
-            double A = Math.pow(Math.abs(R) + Math.sqrt(R2 - Q3), 1.0 / 3.0);
-            if (R > 0.0) {
-                A = -A;
-            }
-//          if (A == 0.0) {
-            if (-ROOT_DELTA < A && A < ROOT_DELTA) {
-                res[rc++] = n;
-            } else {
-                double B = Q / A;
-                res[rc++] = A + B + n;
-//              if (R2 == Q3) {
-                double delta = R2 - Q3;
-                if (-ROOT_DELTA < delta && delta < ROOT_DELTA) {
-                    res[rc++] = - (A + B) / 2.0 + n;
-                }
-            }
-
-        }
-        return fixRoots(res, rc);
-    }
-
-    /**
-     * Excludes double roots. Roots are double if they lies enough close with each other. 
-     * @param res - the roots 
-     * @param rc - the roots count
-     * @return new roots count
-     */
-    static int fixRoots(double res[], int rc) {
-        int tc = 0;
-        for(int i = 0; i < rc; i++) {
-            out: {
-                for(int j = i + 1; j < rc; j++) {
-                    if (isZero(res[i] - res[j])) {
-                        break out;
-                    }
-                }
-                res[tc++] = res[i];
-            }
-        }
-        return tc;
-    }
-
-    /**
-     * QuadCurve class provides basic functionality to find curve crossing and calculating bounds
-     */
-    public static class QuadCurve {
-
-        double ax, ay, bx, by;
-        double Ax, Ay, Bx, By;
-
-        public QuadCurve(double x1, double y1, double cx, double cy, double x2, double y2) {
-            ax = x2 - x1;
-            ay = y2 - y1;
-            bx = cx - x1;
-            by = cy - y1;
-
-            Bx = bx + bx;   // Bx = 2.0 * bx
-            Ax = ax - Bx;   // Ax = ax - 2.0 * bx
-
-            By = by + by;   // By = 2.0 * by
-            Ay = ay - By;   // Ay = ay - 2.0 * by
-        }
-
-        int cross(double res[], int rc, double py1, double py2) {
-            int cross = 0;
-
-            for (int i = 0; i < rc; i++) {
-                double t = res[i];
-
-                // CURVE-OUTSIDE
-                if (t < -DELTA || t > 1 + DELTA) {
-                    continue;
-                }
-                // CURVE-START
-                if (t < DELTA) {
-                    if (py1 < 0.0 && (bx != 0.0 ? bx : ax - bx) < 0.0) {
-                        cross--;
-                    }
-                    continue;
-                }
-                // CURVE-END
-                if (t > 1 - DELTA) {
-                    if (py1 < ay && (ax != bx ? ax - bx : bx) > 0.0) {
-                        cross++;
-                    }
-                    continue;
-                }
-                // CURVE-INSIDE
-                double ry = t * (t * Ay + By);
-                // ry = t * t * Ay + t * By
-                if (ry > py2) {
-                    double rxt = t * Ax + bx;
-                    // rxt = 2.0 * t * Ax + Bx = 2.0 * t * Ax + 2.0 * bx
-                    if (rxt > -DELTA && rxt < DELTA) {
-                        continue;
-                    }
-                    cross += rxt > 0.0 ? 1 : -1;
-                }
-            } // for
-
-            return cross;
-        }
-
-        int solvePoint(double res[], double px) {
-            double eqn[] = {-px, Bx, Ax};
-            return solveQuad(eqn, res);
-        }
-
-        int solveExtrem(double res[]) {
-            int rc = 0;
-            if (Ax != 0.0) {
-                res[rc++] = - Bx / (Ax + Ax);
-            }
-            if (Ay != 0.0) {
-                res[rc++] = - By / (Ay + Ay);
-            }
-            return rc;
-        }
-
-        int addBound(double bound[], int bc, double res[], int rc, double minX, double maxX, boolean changeId, int id) {
-            for(int i = 0; i < rc; i++) {
-                double t = res[i];
-                if (t > -DELTA && t < 1 + DELTA) {
-                    double rx = t * (t * Ax + Bx);
-                    if (minX <= rx && rx <= maxX) {
-                        bound[bc++] = t;
-                        bound[bc++] = rx;
-                        bound[bc++] = t * (t * Ay + By);
-                        bound[bc++] = id;
-                        if (changeId) {
-                            id++;
-                        }
-                    }
-                }
-            }
-            return bc;
-        }
-
-    }
-
-    /**
-     * CubicCurve class provides basic functionality to find curve crossing and calculating bounds
-     */
-    public static class CubicCurve {
-
-        double ax, ay, bx, by, cx, cy;
-        double Ax, Ay, Bx, By, Cx, Cy;
-        double Ax3, Bx2;
-
-        public CubicCurve(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2) {
-            ax = x2 - x1;
-            ay = y2 - y1;
-            bx = cx1 - x1;
-            by = cy1 - y1;
-            cx = cx2 - x1;
-            cy = cy2 - y1;
-
-            Cx = bx + bx + bx;           // Cx = 3.0 * bx
-            Bx = cx + cx + cx - Cx - Cx; // Bx = 3.0 * cx - 6.0 * bx
-            Ax = ax - Bx - Cx;           // Ax = ax - 3.0 * cx + 3.0 * bx
-
-            Cy = by + by + by;           // Cy = 3.0 * by
-            By = cy + cy + cy - Cy - Cy; // By = 3.0 * cy - 6.0 * by
-            Ay = ay - By - Cy;           // Ay = ay - 3.0 * cy + 3.0 * by
-
-            Ax3 = Ax + Ax + Ax;
-            Bx2 = Bx + Bx;
-        }
-
-        int cross(double res[], int rc, double py1, double py2) {
-            int cross = 0;
-            for (int i = 0; i < rc; i++) {
-                double t = res[i];
-
-                // CURVE-OUTSIDE
-                if (t < -DELTA || t > 1 + DELTA) {
-                    continue;
-                }
-                // CURVE-START
-                if (t < DELTA) {
-                    if (py1 < 0.0 && (bx != 0.0 ? bx : (cx != bx ? cx - bx : ax - cx)) < 0.0) {
-                        cross--;
-                    }
-                    continue;
-                }
-                // CURVE-END
-                if (t > 1 - DELTA) {
-                    if (py1 < ay && (ax != cx ? ax - cx : (cx != bx ? cx - bx : bx)) > 0.0) {
-                        cross++;
-                    }
-                    continue;
-                }
-                // CURVE-INSIDE
-                double ry = t * (t * (t * Ay + By) + Cy);
-                // ry = t * t * t * Ay + t * t * By + t * Cy
-                if (ry > py2) {
-                    double rxt = t * (t * Ax3 + Bx2) + Cx;
-                    // rxt = 3.0 * t * t * Ax + 2.0 * t * Bx + Cx
-                    if (rxt > -DELTA && rxt < DELTA) {
-                        rxt = t * (Ax3 + Ax3) + Bx2;
-                        // rxt = 6.0 * t * Ax + 2.0 * Bx
-                        if (rxt < -DELTA || rxt > DELTA) {
-                            // Inflection point
-                            continue;
-                        }
-                        rxt = ax;
-                    }
-                    cross += rxt > 0.0 ? 1 : -1;
-                }
-            } //for
-
-            return cross;
-        }
-
-        int solvePoint(double res[], double px) {
-            double eqn[] = {-px, Cx, Bx, Ax};
-            return solveCubic(eqn, res);
-        }
-
-        int solveExtremX(double res[]) {
-            double eqn[] = {Cx, Bx2, Ax3};
-            return solveQuad(eqn, res);
-        }
-
-        int solveExtremY(double res[]) {
-            double eqn[] = {Cy, By + By, Ay + Ay + Ay};
-            return solveQuad(eqn, res);
-        }
-
-        int addBound(double bound[], int bc, double res[], int rc, double minX, double maxX, boolean changeId, int id) {
-            for(int i = 0; i < rc; i++) {
-                double t = res[i];
-                if (t > -DELTA && t < 1 + DELTA) {
-                    double rx = t * (t * (t * Ax + Bx) + Cx);
-                    if (minX <= rx && rx <= maxX) {
-                        bound[bc++] = t;
-                        bound[bc++] = rx;
-                        bound[bc++] = t * (t * (t * Ay + By) + Cy);
-                        bound[bc++] = id;
-                        if (changeId) {
-                            id++;
-                        }
-                    }
-                }
-            }
-            return bc;
-        }
-
-    }
-
-    /**
-     * Returns how many times ray from point (x,y) cross line.
-     */
-    public static int crossLine(double x1, double y1, double x2, double y2, double x, double y) {
-
-        // LEFT/RIGHT/UP/EMPTY
-        if ((x < x1 && x < x2) ||
-            (x > x1 && x > x2) ||
-            (y > y1 && y > y2) ||
-            (x1 == x2))
-        {
-            return 0;
-        }
-
-        // DOWN
-        if (y < y1 && y < y2) {
-        } else {
-            // INSIDE
-            if ((y2 - y1) * (x - x1) / (x2 - x1) <= y - y1) {
-                // INSIDE-UP
-                return 0;
-            }
-        }
-
-        // START
-        if (x == x1) {
-            return x1 < x2 ? 0 : -1;
-        }
-
-        // END
-        if (x == x2) {
-            return x1 < x2 ? 1 : 0;
-        }
-
-        // INSIDE-DOWN
-        return x1 < x2 ? 1 : -1;
-    }
-
-    /**
-     * Returns how many times ray from point (x,y) cross quard curve
-     */
-    public static int crossQuad(double x1, double y1, double cx, double cy, double x2, double y2, double x, double y) {
-
-        // LEFT/RIGHT/UP/EMPTY
-        if ((x < x1 && x < cx && x < x2) ||
-            (x > x1 && x > cx && x > x2) ||
-            (y > y1 && y > cy && y > y2) ||
-            (x1 == cx && cx == x2))
-        {
-            return 0;
-        }
-
-        // DOWN
-        if (y < y1 && y < cy && y < y2 && x != x1 && x != x2) {
-            if (x1 < x2) {
-                return x1 < x && x < x2 ? 1 : 0;
-            }
-            return x2 < x && x < x1 ? -1 : 0;
-        }
-
-        // INSIDE
-        QuadCurve c = new QuadCurve(x1, y1, cx, cy, x2, y2);
-        double px = x - x1;
-        double py = y - y1;
-        double res[] = new double[3];
-        int rc = c.solvePoint(res, px);
-
-        return c.cross(res, rc, py, py);
-    }
-
-    /**
-     * Returns how many times ray from point (x,y) cross cubic curve
-     */
-    public static int crossCubic(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2, double x, double y) {
-
-        // LEFT/RIGHT/UP/EMPTY
-        if ((x < x1 && x < cx1 && x < cx2 && x < x2) ||
-            (x > x1 && x > cx1 && x > cx2 && x > x2) ||
-            (y > y1 && y > cy1 && y > cy2 && y > y2) ||
-            (x1 == cx1 && cx1 == cx2 && cx2 == x2))
-        {
-            return 0;
-        }
-
-        // DOWN
-        if (y < y1 && y < cy1 && y < cy2 && y < y2 && x != x1 && x != x2) {
-            if (x1 < x2) {
-                return x1 < x && x < x2 ? 1 : 0;
-            }
-            return x2 < x && x < x1 ? -1 : 0;
-        }
-
-        // INSIDE
-        CubicCurve c = new CubicCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
-        double px = x - x1;
-        double py = y - y1;
-        double res[] = new double[3];
-        int rc = c.solvePoint(res, px);
-        return c.cross(res, rc, py, py);
-    }
-
-    /**
-     * Returns how many times ray from point (x,y) cross path
-     */
-    public static int crossPath(PathIterator p, double x, double y) {
-        int cross = 0;
-        double mx, my, cx, cy;
-        mx = my = cx = cy = 0.0;
-        double coords[] = new double[6];
-
-        while (!p.isDone()) {
-            switch (p.currentSegment(coords)) {
-            case PathIterator.SEG_MOVETO:
-                if (cx != mx || cy != my) {
-                    cross += crossLine(cx, cy, mx, my, x, y);
-                }
-                mx = cx = coords[0];
-                my = cy = coords[1];
-                break;
-            case PathIterator.SEG_LINETO:
-                cross += crossLine(cx, cy, cx = coords[0], cy = coords[1], x, y);
-                break;
-            case PathIterator.SEG_QUADTO:
-                cross += crossQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], x, y);
-                break;
-            case PathIterator.SEG_CUBICTO:
-                cross += crossCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], x, y);
-                break;
-            case PathIterator.SEG_CLOSE:
-                if (cy != my || cx != mx) {
-                    cross += crossLine(cx, cy, cx = mx, cy = my, x, y);
-                }
-                break;
-            }
-            p.next();
-        }
-        if (cy != my) {
-            cross += crossLine(cx, cy, mx, my, x, y);
-        }
-        return cross;
-    }
-
-    /**
-     * Returns how many times ray from point (x,y) cross shape
-     */
-    public static int crossShape(Shape s, double x, double y) {
-        if (!s.getBounds2D().contains(x, y)) {
-            return 0;
-        }
-        return crossPath(s.getPathIterator(null), x, y);
-    }
-
-    /**
-     * Returns true if value enough small
-     */
-    public static boolean isZero(double val) {
-        return -DELTA < val && val < DELTA;
-    }
-
-    /**
-     * Sort bound array
-     */
-    static void sortBound(double bound[], int bc) {
-        for(int i = 0; i < bc - 4; i += 4) {
-            int k = i;
-            for(int j = i + 4; j < bc; j += 4) {
-                if (bound[k] > bound[j]) {
-                    k = j;
-                }
-            }
-            if (k != i) {
-                double tmp = bound[i];
-                bound[i] = bound[k];
-                bound[k] = tmp;
-                tmp = bound[i + 1];
-                bound[i + 1] = bound[k + 1];
-                bound[k + 1] = tmp;
-                tmp = bound[i + 2];
-                bound[i + 2] = bound[k + 2];
-                bound[k + 2] = tmp;
-                tmp = bound[i + 3];
-                bound[i + 3] = bound[k + 3];
-                bound[k + 3] = tmp;
-            }
-        }
-    }
-    
-    /**
-     * Returns are bounds intersect or not intersect rectangle 
-     */
-    static int crossBound(double bound[], int bc, double py1, double py2) {
-
-        // LEFT/RIGHT
-        if (bc == 0) {
-            return 0;
-        }
-
-        // Check Y coordinate
-        int up = 0;
-        int down = 0;
-        for(int i = 2; i < bc; i += 4) {
-            if (bound[i] < py1) {
-                up++;
-                continue;
-            }
-            if (bound[i] > py2) {
-                down++;
-                continue;
-            }
-            return CROSSING;
-        }
-
-        // UP
-        if (down == 0) {
-            return 0;
-        }
-
-        if (up != 0) {
-            // bc >= 2
-            sortBound(bound, bc);
-            boolean sign = bound[2] > py2;
-            for(int i = 6; i < bc; i += 4) {
-                boolean sign2 = bound[i] > py2;
-                if (sign != sign2 && bound[i + 1] != bound[i - 3]) {
-                    return CROSSING;
-                }
-                sign = sign2;
-            }
-        }
-        return UNKNOWN;
-    }
-
-    /**
-     * Returns how many times rectangle stripe cross line or the are intersect
-     */
-    public static int intersectLine(double x1, double y1, double x2, double y2, double rx1, double ry1, double rx2, double ry2) {
-
-        // LEFT/RIGHT/UP
-        if ((rx2 < x1 && rx2 < x2) ||
-            (rx1 > x1 && rx1 > x2) ||
-            (ry1 > y1 && ry1 > y2))
-        {
-            return 0;
-        }
-
-        // DOWN
-        if (ry2 < y1 && ry2 < y2) {
-        } else {
-
-            // INSIDE
-            if (x1 == x2) {
-                return CROSSING;
-            }
-
-            // Build bound
-            double bx1, bx2;
-            if (x1 < x2) {
-                bx1 = x1 < rx1 ? rx1 : x1;
-                bx2 = x2 < rx2 ? x2 : rx2;
-            } else {
-                bx1 = x2 < rx1 ? rx1 : x2;
-                bx2 = x1 < rx2 ? x1 : rx2;
-            }
-            double k = (y2 - y1) / (x2 - x1);
-            double by1 = k * (bx1 - x1) + y1;
-            double by2 = k * (bx2 - x1) + y1;
-
-            // BOUND-UP
-            if (by1 < ry1 && by2 < ry1) {
-                return 0;
-            }
-
-            // BOUND-DOWN
-            if (by1 > ry2 && by2 > ry2) {
-            } else {
-                return CROSSING;
-            }
-        }
-
-        // EMPTY
-        if (x1 == x2) {
-            return 0;
-        }
-
-        // CURVE-START
-        if (rx1 == x1) {
-            return x1 < x2 ? 0 : -1;
-        }
-
-        // CURVE-END
-        if (rx1 == x2) {
-            return x1 < x2 ? 1 : 0;
-        }
-
-        if (x1 < x2) {
-            return x1 < rx1 && rx1 < x2 ? 1 : 0;
-        }
-        return x2 < rx1 && rx1 < x1 ? -1 : 0;
-
-    }
-
-    /**
-     * Returns how many times rectangle stripe cross quad curve or the are intersect
-     */
-    public static int intersectQuad(double x1, double y1, double cx, double cy, double x2, double y2, double rx1, double ry1, double rx2, double ry2) {
-
-        // LEFT/RIGHT/UP ------------------------------------------------------
-        if ((rx2 < x1 && rx2 < cx && rx2 < x2) ||
-            (rx1 > x1 && rx1 > cx && rx1 > x2) ||
-            (ry1 > y1 && ry1 > cy && ry1 > y2))
-        {
-            return 0;
-        }
-
-        // DOWN ---------------------------------------------------------------
-        if (ry2 < y1 && ry2 < cy && ry2 < y2 && rx1 != x1 && rx1 != x2) {
-            if (x1 < x2) {
-                return x1 < rx1 && rx1 < x2 ? 1 : 0;
-            }
-            return x2 < rx1 && rx1 < x1 ? -1 : 0;
-        }
-
-        // INSIDE -------------------------------------------------------------
-        QuadCurve c = new QuadCurve(x1, y1, cx, cy, x2, y2);
-        double px1 = rx1 - x1;
-        double py1 = ry1 - y1;
-        double px2 = rx2 - x1;
-        double py2 = ry2 - y1;
-
-        double res1[] = new double[3];
-        double res2[] = new double[3];
-        int rc1 = c.solvePoint(res1, px1);
-        int rc2 = c.solvePoint(res2, px2);
-
-        // INSIDE-LEFT/RIGHT
-        if (rc1 == 0 && rc2 == 0) {
-            return 0;
-        }
-
-        // Build bound --------------------------------------------------------
-        double minX = px1 - DELTA;
-        double maxX = px2 + DELTA;
-        double bound[] = new double[28];
-        int bc = 0;
-        // Add roots
-        bc = c.addBound(bound, bc, res1, rc1, minX, maxX, false, 0);
-        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, false, 1);
-        // Add extremal points`
-        rc2 = c.solveExtrem(res2);
-        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 2);
-        // Add start and end
-        if (rx1 < x1 && x1 < rx2) {
-            bound[bc++] = 0.0;
-            bound[bc++] = 0.0;
-            bound[bc++] = 0.0;
-            bound[bc++] = 4;
-        }
-        if (rx1 < x2 && x2 < rx2) {
-            bound[bc++] = 1.0;
-            bound[bc++] = c.ax;
-            bound[bc++] = c.ay;
-            bound[bc++] = 5;
-        }
-        // End build bound ----------------------------------------------------
-
-        int cross = crossBound(bound, bc, py1, py2);
-        if (cross != UNKNOWN) {
-            return cross;
-        }
-        return c.cross(res1, rc1, py1, py2);
-    }
-
-    /**
-     * Returns how many times rectangle stripe cross cubic curve or the are intersect
-     */
-    public static int intersectCubic(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2, double rx1, double ry1, double rx2, double ry2) {
-
-        // LEFT/RIGHT/UP
-        if ((rx2 < x1 && rx2 < cx1 && rx2 < cx2 && rx2 < x2) ||
-            (rx1 > x1 && rx1 > cx1 && rx1 > cx2 && rx1 > x2) ||
-            (ry1 > y1 && ry1 > cy1 && ry1 > cy2 && ry1 > y2))
-        {
-            return 0;
-        }
-
-        // DOWN
-        if (ry2 < y1 && ry2 < cy1 && ry2 < cy2 && ry2 < y2 && rx1 != x1 && rx1 != x2) {
-            if (x1 < x2) {
-                return x1 < rx1 && rx1 < x2 ? 1 : 0;
-            }
-            return x2 < rx1 && rx1 < x1 ? -1 : 0;
-        }
-
-        // INSIDE
-        CubicCurve c = new CubicCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
-        double px1 = rx1 - x1;
-        double py1 = ry1 - y1;
-        double px2 = rx2 - x1;
-        double py2 = ry2 - y1;
-
-        double res1[] = new double[3];
-        double res2[] = new double[3];
-        int rc1 = c.solvePoint(res1, px1);
-        int rc2 = c.solvePoint(res2, px2);
-
-        // LEFT/RIGHT
-        if (rc1 == 0 && rc2 == 0) {
-            return 0;
-        }
-
-        double minX = px1 - DELTA;
-        double maxX = px2 + DELTA;
-
-        // Build bound --------------------------------------------------------
-        double bound[] = new double[40];
-        int bc = 0;
-        // Add roots
-        bc = c.addBound(bound, bc, res1, rc1, minX, maxX, false, 0);
-        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, false, 1);
-        // Add extrimal points
-        rc2 = c.solveExtremX(res2);
-        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 2);
-        rc2 = c.solveExtremY(res2);
-        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 4);
-        // Add start and end
-        if (rx1 < x1 && x1 < rx2) {
-            bound[bc++] = 0.0;
-            bound[bc++] = 0.0;
-            bound[bc++] = 0.0;
-            bound[bc++] = 6;
-        }
-        if (rx1 < x2 && x2 < rx2) {
-            bound[bc++] = 1.0;
-            bound[bc++] = c.ax;
-            bound[bc++] = c.ay;
-            bound[bc++] = 7;
-        }
-        // End build bound ----------------------------------------------------
-
-        int cross = crossBound(bound, bc, py1, py2);
-        if (cross != UNKNOWN) {
-            return cross;
-        }
-        return c.cross(res1, rc1, py1, py2);
-    }
-
-    /**
-     * Returns how many times rectangle stripe cross path or the are intersect
-     */
-    public static int intersectPath(PathIterator p, double x, double y, double w, double h) {
-
-        int cross = 0;
-        int count;
-        double mx, my, cx, cy;
-        mx = my = cx = cy = 0.0;
-        double coords[] = new double[6];
-
-        double rx1 = x;
-        double ry1 = y;
-        double rx2 = x + w;
-        double ry2 = y + h;
-
-        while (!p.isDone()) {
-            count = 0;
-            switch (p.currentSegment(coords)) {
-            case PathIterator.SEG_MOVETO:
-                if (cx != mx || cy != my) {
-                    count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
-                }
-                mx = cx = coords[0];
-                my = cy = coords[1];
-                break;
-            case PathIterator.SEG_LINETO:
-                count = intersectLine(cx, cy, cx = coords[0], cy = coords[1], rx1, ry1, rx2, ry2);
-                break;
-            case PathIterator.SEG_QUADTO:
-                count = intersectQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], rx1, ry1, rx2, ry2);
-                break;
-            case PathIterator.SEG_CUBICTO:
-                count = intersectCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], rx1, ry1, rx2, ry2);
-                break;
-            case PathIterator.SEG_CLOSE:
-                if (cy != my || cx != mx) {
-                    count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
-                }
-                cx = mx;
-                cy = my;
-                break;
-            }
-            if (count == CROSSING) {
-                return CROSSING;
-            }
-            cross += count;
-            p.next();
-        }
-        if (cy != my) {
-            count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
-            if (count == CROSSING) {
-                return CROSSING;
-            }
-            cross += count;
-        }
-        return cross;
-    }
-
-    /**
-     * Returns how many times rectangle stripe cross shape or the are intersect
-     */
-    public static int intersectShape(Shape s, double x, double y, double w, double h) {
-        if (!s.getBounds2D().intersects(x, y, w, h)) {
-            return 0;
-        }
-        return intersectPath(s.getPathIterator(null), x, y, w, h);
-    }
-
-    /**
-     * Returns true if cross count correspond inside location for non zero path rule
-     */
-    public static boolean isInsideNonZero(int cross) {
-        return cross != 0;
-    }
-
-    /**
-     * Returns true if cross count correspond inside location for even-odd path rule
-     */
-    public static boolean isInsideEvenOdd(int cross) {
-        return (cross & 1) != 0;
-    }
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/GLVolatileImage.java b/awt/org/apache/harmony/awt/gl/GLVolatileImage.java
deleted file mode 100644
index 177be23..0000000
--- a/awt/org/apache/harmony/awt/gl/GLVolatileImage.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.image.*;
-
-import org.apache.harmony.awt.gl.Surface;
-
-public abstract class GLVolatileImage extends VolatileImage {
-
-    public abstract Surface getImageSurface();
-}
diff --git a/awt/org/apache/harmony/awt/gl/ICompositeContext.java b/awt/org/apache/harmony/awt/gl/ICompositeContext.java
deleted file mode 100644
index fc5631f..0000000
--- a/awt/org/apache/harmony/awt/gl/ICompositeContext.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.Composite;
-import java.awt.CompositeContext;
-import java.awt.image.ColorModel;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-
-import org.apache.harmony.awt.gl.ImageSurface;
-import org.apache.harmony.awt.gl.render.NativeImageBlitter;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-
-/**
- * This class represent implementation of the CompositeContext interface
- */
-public class ICompositeContext implements CompositeContext {
-    Composite composite;
-    ColorModel srcCM, dstCM;
-    ImageSurface srcSurf, dstSurf;
-
-    public ICompositeContext(Composite comp, ColorModel src, ColorModel dst){
-        composite = comp;
-        srcCM = src;
-        dstCM = dst;
-    }
-
-    public void dispose() {
-        srcSurf.dispose();
-        dstSurf.dispose();
-    }
-
-    public void compose(Raster srcIn, Raster dstIn, WritableRaster dstOut) {
-
-        if(!srcCM.isCompatibleRaster(srcIn)) {
-            // awt.48=The srcIn raster is incompatible with src ColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.48")); //$NON-NLS-1$
-        }
-
-        if(!dstCM.isCompatibleRaster(dstIn)) {
-            // awt.49=The dstIn raster is incompatible with dst ColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.49")); //$NON-NLS-1$
-        }
-
-        if(dstIn != dstOut){
-            if(!dstCM.isCompatibleRaster(dstOut)) {
-                // awt.4A=The dstOut raster is incompatible with dst ColorModel
-                throw new IllegalArgumentException(Messages.getString("awt.4A")); //$NON-NLS-1$
-            }
-            dstOut.setDataElements(0, 0, dstIn);
-        }
-        WritableRaster src;
-        if(srcIn instanceof WritableRaster){
-            src = (WritableRaster) srcIn;
-        }else{
-            src = srcIn.createCompatibleWritableRaster();
-            src.setDataElements(0, 0, srcIn);
-        }
-        srcSurf = new ImageSurface(srcCM, src);
-        dstSurf = new ImageSurface(dstCM, dstOut);
-
-        int w = Math.min(srcIn.getWidth(), dstOut.getWidth());
-        int h = Math.min(srcIn.getHeight(), dstOut.getHeight());
-
-        NativeImageBlitter.getInstance().blit(0, 0, srcSurf, 0, 0, dstSurf,
-                w, h, composite, null, null);
-
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/ImageSurface.java b/awt/org/apache/harmony/awt/gl/ImageSurface.java
deleted file mode 100644
index 6368dd8..0000000
--- a/awt/org/apache/harmony/awt/gl/ImageSurface.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- * Created on 10.11.2005
- *
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.color.ColorSpace;
-import java.awt.image.BandedSampleModel;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.ComponentSampleModel;
-import java.awt.image.DirectColorModel;
-import java.awt.image.IndexColorModel;
-import java.awt.image.MultiPixelPackedSampleModel;
-import java.awt.image.PixelInterleavedSampleModel;
-import java.awt.image.SampleModel;
-import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.WritableRaster;
-
-import org.apache.harmony.awt.gl.color.LUTColorConverter;
-import org.apache.harmony.awt.gl.image.DataBufferListener;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-
-/**
- * This class represent Surface for different types of Images (BufferedImage, 
- * OffscreenImage and so on) 
- */
-public class ImageSurface extends Surface implements DataBufferListener {
-
-    boolean nativeDrawable = true;
-    int surfaceType;
-    int csType;
-    ColorModel cm;
-    WritableRaster raster;
-    Object data;
-    
-    boolean needToRefresh = true;
-    boolean dataTaken = false;
-    
-    private long cachedDataPtr;       // Pointer for cached Image Data
-    private boolean alphaPre;         // Cached Image Data alpha premultiplied 
-
-    public ImageSurface(ColorModel cm, WritableRaster raster){
-        this(cm, raster, Surface.getType(cm, raster));
-    }
-
-    public ImageSurface(ColorModel cm, WritableRaster raster, int type){
-        if (!cm.isCompatibleRaster(raster)) {
-            // awt.4D=The raster is incompatible with this ColorModel
-            throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
-        }
-        this.cm = cm;
-        this.raster = raster;
-        surfaceType = type;
-
-        data = AwtImageBackdoorAccessor.getInstance().
-        getData(raster.getDataBuffer());
-        ColorSpace cs = cm.getColorSpace();
-        transparency = cm.getTransparency();
-        width = raster.getWidth();
-        height = raster.getHeight();
-
-        // For the moment we can build natively only images which have 
-        // sRGB, Linear_RGB, Linear_Gray Color Space and type different
-        // from BufferedImage.TYPE_CUSTOM
-        if(cs == LUTColorConverter.sRGB_CS){
-            csType = sRGB_CS;
-        }else if(cs == LUTColorConverter.LINEAR_RGB_CS){
-            csType = Linear_RGB_CS;
-        }else if(cs == LUTColorConverter.LINEAR_GRAY_CS){
-            csType = Linear_Gray_CS;
-        }else{
-            csType = Custom_CS;
-            nativeDrawable = false;
-        }
-
-        if(type == BufferedImage.TYPE_CUSTOM){
-            nativeDrawable = false;
-        }
-    }
-
-    @Override
-    public ColorModel getColorModel() {
-        return cm;
-    }
-
-    @Override
-    public WritableRaster getRaster() {
-        return raster;
-    }
-
-    @Override
-    public long getSurfaceDataPtr() {
-        if(surfaceDataPtr == 0L && nativeDrawable){
-            createSufaceStructure();
-        }
-        return surfaceDataPtr;
-    }
-
-    @Override
-    public Object getData(){
-        return data;
-    }
-
-    @Override
-    public boolean isNativeDrawable(){
-        return nativeDrawable;
-    }
-
-    @Override
-    public int getSurfaceType() {
-        return surfaceType;
-    }
-
-    /**
-     * Creates native Surface structure which used for native blitting
-     */
-    private void createSufaceStructure(){
-        int cmType = 0;
-        int numComponents = cm.getNumComponents();
-        boolean hasAlpha = cm.hasAlpha();
-        boolean isAlphaPre = cm.isAlphaPremultiplied();
-        int transparency = cm.getTransparency();
-        int bits[] = cm.getComponentSize();
-        int pixelStride = cm.getPixelSize();
-        int masks[] = null;
-        int colorMap[] = null;
-        int colorMapSize = 0;
-        int transpPixel = -1;
-        boolean isGrayPallete = false;
-        SampleModel sm = raster.getSampleModel();
-        int smType = 0;
-        int dataType = sm.getDataType();
-        int scanlineStride = 0;
-        int bankIndeces[] = null;
-        int bandOffsets[] = null;
-        int offset = raster.getDataBuffer().getOffset();
-
-        if(cm instanceof DirectColorModel){
-            cmType = DCM;
-            DirectColorModel dcm = (DirectColorModel) cm;
-            masks = dcm.getMasks();
-            smType = SPPSM;
-            SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
-            scanlineStride = sppsm.getScanlineStride();
-
-        }else if(cm instanceof IndexColorModel){
-            cmType = ICM;
-            IndexColorModel icm = (IndexColorModel) cm;
-            colorMapSize = icm.getMapSize();
-            colorMap = new int[colorMapSize];
-            icm.getRGBs(colorMap);
-            transpPixel = icm.getTransparentPixel();
-            isGrayPallete = Surface.isGrayPallete(icm);
-
-            if(sm instanceof MultiPixelPackedSampleModel){
-                smType = MPPSM;
-                MultiPixelPackedSampleModel mppsm =
-                    (MultiPixelPackedSampleModel) sm;
-                scanlineStride = mppsm.getScanlineStride();
-            }else if(sm instanceof ComponentSampleModel){
-                smType = CSM;
-                ComponentSampleModel csm =
-                    (ComponentSampleModel) sm;
-                scanlineStride = csm.getScanlineStride();
-            }else{
-                // awt.4D=The raster is incompatible with this ColorModel
-                throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
-            }
-
-        }else if(cm instanceof ComponentColorModel){
-            cmType = CCM;
-            if(sm instanceof ComponentSampleModel){
-                ComponentSampleModel csm = (ComponentSampleModel) sm;
-                scanlineStride = csm.getScanlineStride();
-                bankIndeces = csm.getBankIndices();
-                bandOffsets = csm.getBandOffsets();
-                if(sm instanceof PixelInterleavedSampleModel){
-                    smType = PISM;
-                }else if(sm instanceof BandedSampleModel){
-                    smType = BSM;
-                }else{
-                    smType = CSM;
-                }
-            }else{
-                // awt.4D=The raster is incompatible with this ColorModel
-                throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
-            }
-
-        }else{
-            surfaceDataPtr = 0L;
-            return;
-        }
-        surfaceDataPtr = createSurfStruct(surfaceType, width, height, cmType, csType, smType, dataType,
-                numComponents, pixelStride, scanlineStride, bits, masks, colorMapSize,
-                colorMap, transpPixel, isGrayPallete, bankIndeces, bandOffsets,
-                offset, hasAlpha, isAlphaPre, transparency);
-    }
-
-    @Override
-    public void dispose() {
-        if(surfaceDataPtr != 0L){
-            dispose(surfaceDataPtr);
-            surfaceDataPtr = 0L;
-        }
-    }
-    
-    public long getCachedData(boolean alphaPre){
-        if(nativeDrawable){
-            if(cachedDataPtr == 0L || needToRefresh || this.alphaPre != alphaPre){
-                cachedDataPtr = updateCache(getSurfaceDataPtr(), data, alphaPre);
-                this.alphaPre = alphaPre;
-                validate(); 
-            }
-        }
-        return cachedDataPtr;
-    }
-
-    private native long createSurfStruct(int surfaceType, int width, int height, 
-            int cmType, int csType, int smType, int dataType,
-            int numComponents, int pixelStride, int scanlineStride,
-            int bits[], int masks[], int colorMapSize, int colorMap[],
-            int transpPixel, boolean isGrayPalette, int bankIndeces[], 
-            int bandOffsets[], int offset, boolean hasAlpha, boolean isAlphaPre,
-            int transparency);
-
-    private native void dispose(long structPtr);
-
-    private native void setImageSize(long structPtr, int width, int height);
-
-    private native long updateCache(long structPtr, Object data, boolean alphaPre);
-    
-    /**
-     * Supposes that new raster is compatible with an old one
-     * @param r
-     */
-    public void setRaster(WritableRaster r) {
-        raster = r;
-        data = AwtImageBackdoorAccessor.getInstance().getData(r.getDataBuffer());
-        if (surfaceDataPtr != 0) {
-            setImageSize(surfaceDataPtr, r.getWidth(), r.getHeight());
-        }
-        this.width = r.getWidth();
-        this.height = r.getHeight();
-    }
-
-    @Override
-    public long lock() {
-        // TODO
-        return 0;
-    }
-
-    @Override
-    public void unlock() {
-        //TODO
-    }
-
-    @Override
-    public Surface getImageSurface() {
-        return this;
-    }
-
-    public void dataChanged() {
-        needToRefresh = true;
-        clearValidCaches();
-    }
-
-    public void dataTaken() {
-        dataTaken = true;
-        needToRefresh = true;
-        clearValidCaches();
-    }
-    
-    public void dataReleased(){
-        dataTaken = false;
-        needToRefresh = true;
-        clearValidCaches();
-    }
-    
-    @Override
-    public void invalidate(){
-        needToRefresh = true;
-        clearValidCaches();
-    }
-    
-    @Override
-    public void validate(){
-        if(!needToRefresh) {
-            return;
-        }
-        if(!dataTaken){
-            needToRefresh = false;
-            AwtImageBackdoorAccessor ba = AwtImageBackdoorAccessor.getInstance();
-            ba.validate(raster.getDataBuffer());
-        }
-        
-    }
-    
-    @Override
-    public boolean invalidated(){
-        return needToRefresh;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/MultiRectArea.java b/awt/org/apache/harmony/awt/gl/MultiRectArea.java
deleted file mode 100644
index c4267f3..0000000
--- a/awt/org/apache/harmony/awt/gl/MultiRectArea.java
+++ /dev/null
@@ -1,836 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-public class MultiRectArea implements Shape {
-
-    /**
-     * If CHECK is true validation check active
-     */
-    private static final boolean CHECK = false;
-
-    boolean sorted = true;
-    
-    /**
-     * Rectangle buffer
-     */
-    public int[] rect;
-    
-    /**
-     * Bounding box
-     */
-    Rectangle bounds;
-    
-    /**
-     * Result rectangle array
-     */
-    Rectangle[] rectangles;
-
-    /**
-     * LineCash provides creating MultiRectArea line by line. Used in JavaShapeRasterizer.
-     */
-    public static class LineCash extends MultiRectArea {
-
-        int lineY;
-        int bottomCount;
-        int[] bottom;
-
-        public LineCash(int size) {
-            super();
-            bottom = new int[size];
-            bottomCount = 0;
-        }
-
-        public void setLine(int y) {
-            lineY = y;
-        }
-
-        public void skipLine() {
-            lineY++;
-            bottomCount = 0;
-        }
-
-        public void addLine(int[] points, int pointCount) {
-            int bottomIndex = 0;
-            int pointIndex = 0;
-            int rectIndex = 0;
-            int pointX1 = 0;
-            int pointX2 = 0;
-            int bottomX1 = 0;
-            int bottomX2 = 0;
-            boolean appendRect = false;
-            boolean deleteRect = false;
-            int lastCount = bottomCount;
-
-            while (bottomIndex < lastCount || pointIndex < pointCount) {
-
-                appendRect = false;
-                deleteRect = false;
-
-                if (bottomIndex < lastCount) {
-                    rectIndex = bottom[bottomIndex];
-                    bottomX1 = rect[rectIndex];
-                    bottomX2 = rect[rectIndex + 2];
-                } else {
-                    appendRect = true;
-                }
-
-                if (pointIndex < pointCount) {
-                    pointX1 = points[pointIndex];
-                    pointX2 = points[pointIndex + 1];
-                } else {
-                    deleteRect = true;
-                }
-
-                if (!deleteRect && !appendRect) {
-                    if (pointX1 == bottomX1 && pointX2 == bottomX2) {
-                        rect[rectIndex + 3] = rect[rectIndex + 3] + 1;
-                        pointIndex += 2;
-                        bottomIndex++;
-                        continue;
-                    }
-                    deleteRect = pointX2 >= bottomX1;
-                    appendRect = pointX1 <= bottomX2;
-                }
-
-                if (deleteRect) {
-                    if (bottomIndex < bottomCount - 1) {
-                        System.arraycopy(bottom, bottomIndex + 1, bottom, bottomIndex, bottomCount - bottomIndex - 1);
-                        rectIndex -= 4;
-                    }
-                    bottomCount--;
-                    lastCount--;
-                }
-
-                if (appendRect) {
-                    int i = rect[0];
-                    bottom[bottomCount++] = i;
-                    rect = MultiRectAreaOp.checkBufSize(rect, 4);
-                    rect[i++] = pointX1;
-                    rect[i++] = lineY;
-                    rect[i++] = pointX2;
-                    rect[i++] = lineY;
-                    pointIndex += 2;
-                }
-            }
-            lineY++;
-
-            invalidate();
-        }
-
-    }
-
-    /**
-     * RectCash provides simple creating MultiRectArea
-     */
-    public static class RectCash extends MultiRectArea {
-
-        int[] cash;
-
-        public RectCash() {
-            super();
-            cash = new int[MultiRectAreaOp.RECT_CAPACITY];
-            cash[0] = 1;
-        }
-
-        public void addRectCashed(int x1, int y1, int x2, int y2) {
-            addRect(x1, y1, x2, y2);
-            invalidate();
-/*
-            // Exclude from cash unnecessary rectangles
-            int i = 1;
-            while(i < cash[0]) {
-                if (rect[cash[i] + 3] >= y1 - 1) {
-                    if (i > 1) {
-                        System.arraycopy(cash, i, cash, 1, cash[0] - i);
-                    }
-                    break;
-                }
-                i++;
-            }
-            cash[0] -= i - 1;
-
-            // Find in cash rectangle to concatinate
-            i = 1;
-            while(i < cash[0]) {
-                int index = cash[i];
-                if (rect[index + 3] != y1 - 1) {
-                    break;
-                }
-                if (rect[index] == x1 && rect[index + 2] == x2) {
-                    rect[index + 3] += y2 - y1 + 1;
-
-                    int pos = i + 1;
-                    while(pos < cash[0]) {
-                        if (rect[index + 3] <= rect[cash[i] + 3]) {
-                            System.arraycopy(cash, i + 1, cash, i, pos - i);
-                            break;
-                        }
-                        i++;
-                    }
-                    cash[pos - 1] = index;
-
-                    invalidate();
-                    return;
-                }
-                i++;
-            }
-
-            // Add rectangle to buffer
-            int index = rect[0];
-            rect = MultiRectAreaOp.checkBufSize(rect, 4);
-            rect[index + 0] = x1;
-            rect[index + 1] = y1;
-            rect[index + 2] = x2;
-            rect[index + 3] = y2;
-
-            // Add rectangle to cash
-            int length = cash[0];
-            cash = MultiRectAreaOp.checkBufSize(cash, 1);
-            while(i < length) {
-                if (y2 <= rect[cash[i] + 3]) {
-                    System.arraycopy(cash, i, cash, i + 1, length - i);
-                    break;
-                }
-                i++;
-            }
-            cash[i] = index;
-            invalidate();
-*/
-        }
-
-        public void addRectCashed(int[] rect, int rectOff, int rectLength) {
-            for(int i = rectOff; i < rectOff + rectLength;) {
-                addRect(rect[i++], rect[i++], rect[i++], rect[i++]);
-//              addRectCashed(rect[i++], rect[i++], rect[i++], rect[i++]);
-            }
-        }
-
-    }
-
-    /**
-     * MultiRectArea path iterator
-     */
-    class Iterator implements PathIterator {
-
-        int type;
-        int index;
-        int pos;
-
-        int[] rect;
-        AffineTransform t;
-
-        Iterator(MultiRectArea mra, AffineTransform t) {
-            rect = new int[mra.rect[0] - 1];
-            System.arraycopy(mra.rect, 1, rect, 0, rect.length);
-            this.t = t;
-        }
-
-        public int getWindingRule() {
-            return WIND_NON_ZERO;
-        }
-
-        public boolean isDone() {
-            return pos >= rect.length;
-        }
-
-        public void next() {
-            if (index == 4) {
-                pos += 4;
-            }
-            index = (index + 1) % 5;
-        }
-
-        public int currentSegment(double[] coords) {
-            if (isDone()) {
-                // awt.4B=Iiterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type = 0;
-
-            switch(index) {
-            case 0 :
-                type = SEG_MOVETO;
-                coords[0] = rect[pos + 0];
-                coords[1] = rect[pos + 1];
-                break;
-            case 1:
-                type = SEG_LINETO;
-                coords[0] = rect[pos + 2];
-                coords[1] = rect[pos + 1];
-                break;
-            case 2:
-                type = SEG_LINETO;
-                coords[0] = rect[pos + 2];
-                coords[1] = rect[pos + 3];
-                break;
-            case 3:
-                type = SEG_LINETO;
-                coords[0] = rect[pos + 0];
-                coords[1] = rect[pos + 3];
-                break;
-            case 4:
-                type = SEG_CLOSE;
-                break;
-            }
-
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, 1);
-            }
-            return type;
-        }
-
-        public int currentSegment(float[] coords) {
-            if (isDone()) {
-                // awt.4B=Iiterator out of bounds
-                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
-            }
-            int type = 0;
-
-            switch(index) {
-            case 0 :
-                type = SEG_MOVETO;
-                coords[0] = rect[pos + 0];
-                coords[1] = rect[pos + 1];
-                break;
-            case 1:
-                type = SEG_LINETO;
-                coords[0] = rect[pos + 2];
-                coords[1] = rect[pos + 1];
-                break;
-            case 2:
-                type = SEG_LINETO;
-                coords[0] = rect[pos + 2];
-                coords[1] = rect[pos + 3];
-                break;
-            case 3:
-                type = SEG_LINETO;
-                coords[0] = rect[pos + 0];
-                coords[1] = rect[pos + 3];
-                break;
-            case 4:
-                type = SEG_CLOSE;
-                break;
-            }
-
-            if (t != null) {
-                t.transform(coords, 0, coords, 0, 1);
-            }
-            return type;
-        }
-
-    }
-
-    /**
-     * Constructs a new empty MultiRectArea 
-     */
-    public MultiRectArea() {
-        rect = MultiRectAreaOp.createBuf(0);
-    }
-
-    public MultiRectArea(boolean sorted) {
-       this();
-       this.sorted = sorted;
-    }
-    
-    /**
-     * Constructs a new MultiRectArea as a copy of another one 
-     */
-    public MultiRectArea(MultiRectArea mra) {
-        if (mra == null) {
-            rect = MultiRectAreaOp.createBuf(0);
-        } else {
-            rect = new int[mra.rect.length];
-            System.arraycopy(mra.rect, 0, rect, 0, mra.rect.length);
-            check(this, "MultiRectArea(MRA)"); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Constructs a new MultiRectArea consists of single rectangle 
-     */
-    public MultiRectArea(Rectangle r) {
-        rect = MultiRectAreaOp.createBuf(0);
-        if (r != null && !r.isEmpty()) {
-            rect[0] = 5;
-            rect[1] = r.x;
-            rect[2] = r.y;
-            rect[3] = r.x + r.width - 1;
-            rect[4] = r.y + r.height - 1;
-        }
-        check(this, "MultiRectArea(Rectangle)"); //$NON-NLS-1$
-    }
-
-    /**
-     * Constructs a new MultiRectArea consists of single rectangle
-     */
-    public MultiRectArea(int x0, int y0, int x1, int y1) {
-        rect = MultiRectAreaOp.createBuf(0);
-        if (x1 >= x0 && y1 >= y0) {
-            rect[0] = 5;
-            rect[1] = x0;
-            rect[2] = y0;
-            rect[3] = x1;
-            rect[4] = y1;
-        }
-        check(this, "MultiRectArea(Rectangle)"); //$NON-NLS-1$
-    }
-
-    /**
-     * Constructs a new MultiRectArea and append rectangle from buffer
-     */
-    public MultiRectArea(Rectangle[] buf) {
-        this();
-        for (Rectangle element : buf) {
-            add(element);
-        }
-    }
-
-    /**
-     * Constructs a new MultiRectArea and append rectangle from array
-     */
-    public MultiRectArea(ArrayList<Rectangle> buf) {
-        this();
-        for(int i = 0; i < buf.size(); i++) {
-            add(buf.get(i));
-        }
-    }
-
-    /**
-     * Sort rectangle buffer
-     */
-    void resort() {
-        int[] buf = new int[4];
-        for(int i = 1; i < rect[0]; i += 4) {
-            int k = i;
-            int x1 = rect[k];
-            int y1 = rect[k + 1];
-            for(int j = i + 4; j < rect[0]; j += 4) {
-                int x2 = rect[j];
-                int y2 = rect[j + 1];
-                if (y1 > y2 || (y1 == y2 && x1 > x2)) {
-                    x1 = x2;
-                    y1 = y2;
-                    k = j;
-                }
-            }
-            if (k != i) {
-                System.arraycopy(rect, i, buf, 0, 4);
-                System.arraycopy(rect, k, rect, i, 4);
-                System.arraycopy(buf, 0, rect, k, 4);
-            }
-        }
-        invalidate();
-    }
-
-    /**
-     * Tests equals with another object
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (obj instanceof MultiRectArea) {
-            MultiRectArea mra = (MultiRectArea) obj;
-            for(int i = 0; i < rect[0]; i++) {
-                if (rect[i] != mra.rect[i]) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Checks validation of MultiRectArea object
-     */
-    static MultiRectArea check(MultiRectArea mra, String msg) {
-        if (CHECK && mra != null) {
-            if (MultiRectArea.checkValidation(mra.getRectangles(), mra.sorted) != -1) {
-                // awt.4C=Invalid MultiRectArea in method {0}
-                new RuntimeException(Messages.getString("awt.4C", msg)); //$NON-NLS-1$
-            }
-        }
-        return mra;
-    }
-
-    /**
-     * Checks validation of MultiRectArea object
-     */
-    public static int checkValidation(Rectangle[] r, boolean sorted) {
-
-        // Check width and height
-        for(int i = 0; i < r.length; i++) {
-            if (r[i].width <= 0 || r[i].height <= 0) {
-                return i;
-            }
-        }
-
-        // Check order
-        if (sorted) {
-            for(int i = 1; i < r.length; i++) {
-                if (r[i - 1].y > r[i].y) {
-                    return i;
-                }
-                if (r[i - 1].y == r[i].y) {
-                    if (r[i - 1].x > r[i].x) {
-                        return i;
-                    }
-                }
-            }
-        }
-
-        // Check override
-        for(int i = 0; i < r.length; i++) {
-            for(int j = i + 1; j < r.length; j++) {
-                if (r[i].intersects(r[j])) {
-                    return i;
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Assigns rectangle from another buffer
-     */
-    protected void setRect(int[] buf, boolean copy) {
-        if (copy) {
-            rect = new int[buf.length];
-            System.arraycopy(buf, 0, rect, 0, buf.length);
-        } else {
-            rect = buf;
-        }
-        invalidate();
-    }
-
-    /**
-     * Union with another MultiRectArea object
-     */
-    public void add(MultiRectArea mra) {
-        setRect(union(this, mra).rect, false);
-        invalidate();
-    }
-
-    /**
-     * Intersect with another MultiRectArea object
-     */
-    public void intersect(MultiRectArea mra) {
-        setRect(intersect(this, mra).rect, false);
-        invalidate();
-    }
-
-    /**
-     * Subtract another MultiRectArea object
-     */
-    public void substract(MultiRectArea mra) {
-        setRect(subtract(this, mra).rect, false);
-        invalidate();
-    }
-
-    /**
-     * Union with Rectangle object
-     */
-    public void add(Rectangle rect) {
-        setRect(union(this, new MultiRectArea(rect)).rect, false);
-        invalidate();
-    }
-
-    /**
-     * Intersect with Rectangle object
-     */
-    public void intersect(Rectangle rect) {
-        setRect(intersect(this, new MultiRectArea(rect)).rect, false);
-        invalidate();
-    }
-
-    /**
-     * Subtract rectangle object
-     */
-    public void substract(Rectangle rect) {
-        setRect(subtract(this, new MultiRectArea(rect)).rect, false);
-    }
-
-    /**
-     * Union two MutliRectareArea objects
-     */
-    public static MultiRectArea intersect(MultiRectArea src1, MultiRectArea src2) {
-        MultiRectArea res = check(MultiRectAreaOp.Intersection.getResult(src1, src2), "intersect(MRA,MRA)"); //$NON-NLS-1$
-        return res;
-    }
-
-    /**
-     * Intersect two MultiRectArea objects
-     */
-    public static MultiRectArea union(MultiRectArea src1, MultiRectArea src2) {
-        MultiRectArea res = check(new MultiRectAreaOp.Union().getResult(src1, src2), "union(MRA,MRA)"); //$NON-NLS-1$
-        return res;
-    }
-
-    /**
-     * Subtract two MultiRectArea objects
-     */
-    public static MultiRectArea subtract(MultiRectArea src1, MultiRectArea src2) {
-        MultiRectArea res = check(MultiRectAreaOp.Subtraction.getResult(src1, src2), "subtract(MRA,MRA)"); //$NON-NLS-1$
-        return res;
-    }
-
-    /**
-     * Print MultiRectArea object to output stream
-     */
-    public static void print(MultiRectArea mra, String msg) {
-        if (mra == null) {
-            System.out.println(msg + "=null"); //$NON-NLS-1$
-        } else {
-            Rectangle[] rects = mra.getRectangles();
-            System.out.println(msg + "(" + rects.length + ")"); //$NON-NLS-1$ //$NON-NLS-2$
-            for (Rectangle element : rects) {
-                System.out.println(
-                        element.x + "," + //$NON-NLS-1$
-                        element.y + "," + //$NON-NLS-1$
-                        (element.x + element.width - 1) + "," + //$NON-NLS-1$
-                        (element.y + element.height - 1));
-            }
-        }
-    }
-
-    /**
-     * Translate MultiRectArea object by (x, y)
-     */
-    public void translate(int x, int y) {
-        for(int i = 1; i < rect[0];) {
-            rect[i++] += x;
-            rect[i++] += y;
-            rect[i++] += x;
-            rect[i++] += y;
-        }
-
-        if (bounds != null && !bounds.isEmpty()) {
-            bounds.translate(x, y);
-        }
-
-        if (rectangles != null) {
-            for (Rectangle element : rectangles) {
-                element.translate(x, y);
-            }
-        }
-    }
-
-    /**
-     * Add rectangle to the buffer without any checking
-     */
-    public void addRect(int x1, int y1, int x2, int y2) {
-        int i = rect[0];
-        rect = MultiRectAreaOp.checkBufSize(rect, 4);
-        rect[i++] = x1;
-        rect[i++] = y1;
-        rect[i++] = x2;
-        rect[i++] = y2;
-    }
-
-    /**
-     * Tests is MultiRectArea empty 
-     */
-    public boolean isEmpty() {
-        return rect[0] == 1;
-    }
-
-    void invalidate() {
-        bounds = null;
-        rectangles = null;
-    }
-
-    /**
-     * Returns bounds of MultiRectArea object
-     */
-    public Rectangle getBounds() {
-        if (bounds != null) {
-            return bounds;
-        }
-
-        if (isEmpty()) {
-            return bounds = new Rectangle();
-        }
-
-        int x1 = rect[1];
-        int y1 = rect[2];
-        int x2 = rect[3];
-        int y2 = rect[4];
-        
-        for(int i = 5; i < rect[0]; i += 4) {
-            int rx1 = rect[i + 0];
-            int ry1 = rect[i + 1];
-            int rx2 = rect[i + 2];
-            int ry2 = rect[i + 3];
-            if (rx1 < x1) {
-                x1 = rx1;
-            }
-            if (rx2 > x2) {
-                x2 = rx2;
-            }
-            if (ry1 < y1) {
-                y1 = ry1;
-            }
-            if (ry2 > y2) {
-                y2 = ry2;
-            }
-        }
-        
-        return bounds = new Rectangle(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
-    }
-
-    /**
-     * Recturn rectangle count in the buffer
-     */
-    public int getRectCount() {
-        return (rect[0] - 1) / 4;
-    }
-
-    /**
-     * Returns Rectangle array 
-     */
-    public Rectangle[] getRectangles() {
-        if (rectangles != null) {
-            return rectangles;
-        }
-
-        rectangles = new Rectangle[(rect[0] - 1) / 4];
-        int j = 0;
-        for(int i = 1; i < rect[0]; i += 4) {
-            rectangles[j++] = new Rectangle(
-                    rect[i],
-                    rect[i + 1],
-                    rect[i + 2] - rect[i] + 1,
-                    rect[i + 3] - rect[i + 1] + 1);
-        }
-        return rectangles;
-    }
-
-    /**
-     * Returns Bounds2D
-     */
-    public Rectangle2D getBounds2D() {
-        return getBounds();
-    }
-
-    /**
-     * Tests does point lie inside MultiRectArea object
-     */
-    public boolean contains(double x, double y) {
-        for(int i = 1; i < rect[0]; i+= 4) {
-            if (rect[i] <= x && x <= rect[i + 2] && rect[i + 1] <= y && y <= rect[i + 3]) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Tests does Point2D lie inside MultiRectArea object
-     */
-    public boolean contains(Point2D p) {
-        return contains(p.getX(), p.getY());
-    }
-
-    /**
-     * Tests does rectangle lie inside MultiRectArea object
-     */
-    public boolean contains(double x, double y, double w, double h) {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    /**
-     * Tests does Rectangle2D lie inside MultiRectArea object
-     */
-    public boolean contains(Rectangle2D r) {
-        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
-    }
-
-    /**
-     * Tests does rectangle intersect MultiRectArea object
-     */
-    public boolean intersects(double x, double y, double w, double h) {
-        Rectangle r = new Rectangle();
-        r.setRect(x, y, w, h);
-        return intersects(r);
-    }
-
-    /**
-     * Tests does Rectangle2D intersect MultiRectArea object
-     */
-    public boolean intersects(Rectangle2D r) {
-        if (r == null || r.isEmpty()) {
-            return false;
-        }
-        for(int i = 1; i < rect[0]; i+= 4) {
-            if (r.intersects(rect[i], rect[i+1], rect[i + 2]-rect[i]+1, rect[i + 3]-rect[i + 1]+1)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns path iterator
-     */
-    public PathIterator getPathIterator(AffineTransform t, double flatness) {
-        return new Iterator(this, t);
-    }
-
-    /**
-     * Returns path iterator
-     */
-    public PathIterator getPathIterator(AffineTransform t) {
-        return new Iterator(this, t);
-    }
-
-    /**
-     * Returns MultiRectArea object converted to string 
-     */
-    @Override
-    public String toString() {
-        int cnt = getRectCount();
-        StringBuffer sb = new StringBuffer((cnt << 5) + 128);
-        sb.append(getClass().getName()).append(" ["); //$NON-NLS-1$
-        for(int i = 1; i < rect[0]; i += 4) {
-            sb.append(i > 1 ? ", [" : "[").append(rect[i]).append(", ").append(rect[i + 1]). //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-            append(", ").append(rect[i + 2] - rect[i] + 1).append(", "). //$NON-NLS-1$ //$NON-NLS-2$
-            append(rect[i + 3] - rect[i + 1] + 1).append("]"); //$NON-NLS-1$
-        }
-        return sb.append("]").toString(); //$NON-NLS-1$
-    }
-
-}
-
diff --git a/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java b/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java
deleted file mode 100644
index c75e203..0000000
--- a/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.Rectangle;
-
-public class MultiRectAreaOp {
-
-    /**
-     * Rectangle buffer capacity
-     */
-    public static final int RECT_CAPACITY = 16;
-    
-    /**
-     * If number of rectangle in MultiRectArea object less than MAX_SIMPLE simple algorithm applies 
-     */
-    private static final int MAX_SIMPLE = 8;
-
-    /**
-     * Create buffer
-     */
-    public static int[] createBuf(int capacity) {
-        if (capacity == 0) {
-            capacity = RECT_CAPACITY;
-        }
-        int[] buf = new int[capacity];
-        buf[0] = 1;
-        return buf;
-    }
-
-    /**
-     * Checks buffer size and reallocate if necessary  
-     */
-    public static int[] checkBufSize(int[] buf, int capacity) {
-        if (buf[0] + capacity >= buf.length) {
-            int length = buf[0] + (capacity > RECT_CAPACITY ? capacity : RECT_CAPACITY);
-            int[] tmp = new int[length];
-            System.arraycopy(buf, 0, tmp, 0, buf[0]);
-            buf = tmp;
-        }
-        buf[0] += capacity;
-        return buf;
-    }
-
-    /**
-     * Region class provides basic functionlity for MultiRectArea objects to make logical operations 
-     */
-    static class Region {
-
-        int[] region;
-        int[] active;
-        int[] bottom;
-        int index;
-
-        public Region(int[] region) {
-            this.region = region;
-            active = new int[RECT_CAPACITY];
-            bottom = new int[RECT_CAPACITY];
-            active[0] = 1;
-            bottom[0] = 1;
-            index = 1;
-        }
-
-        void addActive(int index) {
-            int length = active[0];
-            active = checkBufSize(active, 4);
-            int i = 1;
-
-            while(i < length) {
-                if (region[index] < active[i]) {
-                    // Insert
-                    System.arraycopy(active, i, active, i + 4, length - i);
-                    length = i;
-                    break;
-                }
-                i += 4;
-            }
-            System.arraycopy(region, index, active, length, 4);
-
-        }
-
-        void findActive(int top, int bottom) {
-            while(index < region[0]) {
-                if (region[index + 1] > bottom) { // y1 > bottom
-                    return;
-                }
-                if (region[index + 3] >= top) { // y2 >= top
-                    addActive(index);
-                }
-                index += 4;
-            }
-        }
-
-        void deleteActive(int bottom) {
-            int length = active[0];
-            for(int i = 1; i < length;) {
-                if (active[i + 3] == bottom) {
-                    length -= 4;
-                    if (i < length) {
-                        System.arraycopy(active, i + 4, active, i, length - i);
-                    }
-                } else {
-                     i += 4;
-                }
-            }
-            active[0] = length;
-        }
-
-        void deleteActive() {
-            int length = active[0];
-            for(int i = length - 4; i > 0; i -= 4) {
-                if (active[i + 1] > active[i + 3]) {
-                    length -= 4;
-                    if (i < length) {
-                        System.arraycopy(active, i + 4, active, i, length - i);
-                    }
-                }
-            }
-            active[0] = length;
-        }
-
-        void createLevel(int[] level) {
-            int levelCount = 1;
-            int topIndex = 1;
-            int i = 1;
-            while(i < region[0]) {
-
-                int top = region[i + 1];
-                int bottom = region[i + 3] + 1;
-                int j = topIndex;
-
-                addTop: {
-                    while(j < levelCount) {
-                        if (level[j] == top) {
-                            break addTop;
-                        }
-                        if (level[j] > top) {
-                            System.arraycopy(level, j, level, j + 1, levelCount - j);
-                            break;
-                        }
-                        j++;
-                    }
-
-                    level[j] = top;
-                    levelCount++;
-                    topIndex = j;
-                }
-
-                addBottom: {
-                    while(j < levelCount) {
-                        if (level[j] == bottom) {
-                            break addBottom;
-                        }
-                        if (level[j] > bottom) {
-                            System.arraycopy(level, j, level, j + 1, levelCount - j);
-                            break;
-                        }
-                        j++;
-                    };
-
-                    level[j] = bottom;
-                    levelCount++;
-                }
-
-                i += 4;
-            }
-            level[0] = levelCount;
-        }
-
-        static void sortOrdered(int[] src1, int[] src2, int[] dst) {
-            int length1 = src1[0];
-            int length2 = src2[0];
-            int count = 1;
-            int i1 = 1;
-            int i2 = 1;
-            int v1 = src1[1];
-            int v2 = src2[1];
-            while(true) {
-
-                LEFT: {
-                    while(i1 < length1) {
-                        v1 = src1[i1];
-                        if (v1 >= v2) {
-                            break LEFT;
-                        }
-                        dst[count++] = v1;
-                        i1++;
-                    }
-                    while(i2 < length2) {
-                        dst[count++] = src2[i2++];
-                    }
-                    dst[0] = count;
-                    return;
-                }
-
-                RIGHT: {
-                    while(i2 < length2) {
-                        v2 = src2[i2];
-                        if (v2 >= v1) {
-                            break RIGHT;
-                        }
-                        dst[count++] = v2;
-                        i2++;
-                    }
-                    while(i1 < length1) {
-                        dst[count++] = src1[i1++];
-                    }
-                    dst[0] = count;
-                    return;
-                }
-
-                if (v1 == v2) {
-                    dst[count++] = v1;
-                    i1++;
-                    i2++;
-                    if (i1 < length1) {
-                        v1 = src1[i1];
-                    }
-                    if (i2 < length2 - 1) {
-                        v2 = src2[i2];
-                    }
-                }
-            }
-            // UNREACHABLE
-        }
-
-    }
-
-    /**
-     * Intersection class provides intersection of two MultiRectAre aobjects
-     */
-    static class Intersection {
-
-        static void intersectRegions(int[] reg1, int[] reg2, MultiRectArea.RectCash dst, int height1, int height2) {
-
-            Region d1 = new Region(reg1);
-            Region d2 = new Region(reg2);
-
-            int[] level = new int[height1 + height2];
-            int[] level1 = new int[height1];
-            int[] level2 = new int[height2];
-            d1.createLevel(level1);
-            d2.createLevel(level2);
-            Region.sortOrdered(level1, level2, level);
-
-            int top;
-            int bottom = level[1] - 1;
-            for(int i = 2; i < level[0]; i++) {
-
-                top = bottom + 1;
-                bottom = level[i] - 1;
-
-                d1.findActive(top, bottom);
-                d2.findActive(top, bottom);
-
-                int i1 = 1;
-                int i2 = 1;
-
-                while(i1 < d1.active[0] && i2 < d2.active[0]) {
-
-                    int x11 = d1.active[i1];
-                    int x12 = d1.active[i1 + 2];
-                    int x21 = d2.active[i2];
-                    int x22 = d2.active[i2 + 2];
-
-                    if (x11 <= x21) {
-                        if (x12 >= x21) {
-                            if (x12 <= x22) {
-                                dst.addRectCashed(x21, top, x12, bottom);
-                                i1 += 4;
-                            } else {
-                                dst.addRectCashed(x21, top, x22, bottom);
-                                i2 += 4;
-                            }
-                        } else {
-                            i1 += 4;
-                        }
-                    } else {
-                        if (x22 >= x11) {
-                            if (x22 <= x12) {
-                                dst.addRectCashed(x11, top, x22, bottom);
-                                i2 += 4;
-                            } else {
-                                dst.addRectCashed(x11, top, x12, bottom);
-                                i1 += 4;
-                            }
-                        } else {
-                            i2 += 4;
-                        }
-                    }
-                }
-
-                d1.deleteActive(bottom);
-                d2.deleteActive(bottom);
-            }
-        }
-
-        static int[] simpleIntersect(MultiRectArea src1, MultiRectArea src2) {
-            int[] rect1 = src1.rect;
-            int[] rect2 = src2.rect;
-            int[] rect = createBuf(0);
-
-            int k = 1;
-            for(int i = 1; i < rect1[0];) {
-
-                int x11 = rect1[i++];
-                int y11 = rect1[i++];
-                int x12 = rect1[i++];
-                int y12 = rect1[i++];
-
-                for(int j = 1; j < rect2[0];) {
-
-                    int x21 = rect2[j++];
-                    int y21 = rect2[j++];
-                    int x22 = rect2[j++];
-                    int y22 = rect2[j++];
-
-                    if (x11 <= x22 && x12 >= x21 &&
-                        y11 <= y22 && y12 >= y21)
-                    {
-                        rect = checkBufSize(rect, 4);
-                        rect[k++] = x11 > x21 ? x11 : x21;
-                        rect[k++] = y11 > y21 ? y11 : y21;
-                        rect[k++] = x12 > x22 ? x22 : x12;
-                        rect[k++] = y12 > y22 ? y22 : y12;
-                    }
-                }
-            }
-
-            rect[0] = k;
-            return rect;
-        }
-
-        public static MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) {
-
-            if (src1 == null || src2 == null || src1.isEmpty() || src2.isEmpty()) {
-                return new MultiRectArea();
-            }
-
-            MultiRectArea.RectCash dst = new MultiRectArea.RectCash();
-
-            if (!src1.sorted || !src2.sorted || 
-               src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 
-            {
-                dst.setRect(simpleIntersect(src1, src2), false);
-            } else {
-                Rectangle bounds1 = src1.getBounds();
-                Rectangle bounds2 = src2.getBounds();
-                Rectangle bounds3 = bounds1.intersection(bounds2);
-                if (bounds3.width > 0 && bounds3.height > 0) {
-                    intersectRegions(src1.rect, src2.rect, dst, bounds1.height + 2, bounds2.height + 2);
-                }
-            }
-
-            return dst;
-        }
-
-    }
-
-    /**
-     * Union class provides union of two MultiRectAre aobjects
-     */
-    static class Union {
-
-        int rx1, rx2;
-        int top, bottom;
-        MultiRectArea.RectCash dst;
-
-        boolean next(Region d, int index) {
-            int x1 = d.active[index];
-            int x2 = d.active[index + 2];
-            boolean res = false;
-
-            if (x2 < rx1 - 1) {
-                res = true;
-                dst.addRectCashed(x1, top, x2, bottom);
-            } else
-                if (x1 > rx2 + 1) {
-                    res = false;
-                    dst.addRectCashed(rx1, top, rx2, bottom);
-                    rx1 = x1;
-                    rx2 = x2;
-                } else {
-                    res = x2 <= rx2;
-                    rx1 = Math.min(x1, rx1);
-                    rx2 = Math.max(x2, rx2);
-                }
-
-            // Top
-            if (d.active[index + 1] < top) {
-                dst.addRectCashed(x1, d.active[index + 1], x2, top - 1);
-            }
-            // Bottom
-            if (d.active[index + 3] > bottom) {
-                d.active[index + 1] = bottom + 1;
-            }
-            return res;
-        }
-
-        void check(Region d, int index, boolean t) {
-            int x1 = d.active[index];
-            int x2 = d.active[index + 2];
-            // Top
-            if (d.active[index + 1] < top) {
-                dst.addRectCashed(x1, d.active[index + 1], x2, top - 1);
-            }
-            if (t) {
-                dst.addRectCashed(x1, top, x2, bottom);
-            }
-            // Bottom
-            if (d.active[index + 3] > bottom) {
-                d.active[index + 1] = bottom + 1;
-            }
-        }
-
-        void unionRegions(int[] reg1, int[] reg2, int height1, int height2) {
-            Region d1 = new Region(reg1);
-            Region d2 = new Region(reg2);
-
-            int[] level = new int[height1 + height2];
-            int[] level1 = new int[height1];
-            int[] level2 = new int[height2];
-            d1.createLevel(level1);
-            d2.createLevel(level2);
-            Region.sortOrdered(level1, level2, level);
-
-            bottom = level[1] - 1;
-            for(int i = 2; i < level[0]; i++) {
-
-                top = bottom + 1;
-                bottom = level[i] - 1;
-
-                d1.findActive(top, bottom);
-                d2.findActive(top, bottom);
-
-                int i1 = 1;
-                int i2 = 1;
-                boolean res1, res2;
-
-                if (d1.active[0] > 1) {
-                    check(d1, 1, false);
-                    rx1 = d1.active[1];
-                    rx2 = d1.active[3];
-                    i1 += 4;
-                    res1 = false;
-                    res2 = true;
-                } else
-                    if (d2.active[0] > 1) {
-                        check(d2, 1, false);
-                        rx1 = d2.active[1];
-                        rx2 = d2.active[3];
-                        i2 += 4;
-                        res1 = true;
-                        res2 = false;
-                    } else {
-                        continue;
-                    }
-
-            outer:
-                while(true) {
-
-                    while (res1) {
-                        if (i1 >= d1.active[0]) {
-                            dst.addRectCashed(rx1, top, rx2, bottom);
-                            while(i2 < d2.active[0]) {
-                                check(d2, i2, true);
-                                i2 += 4;
-                            }
-                            break outer;
-                        }
-                        res1 = next(d1, i1);
-                        i1 += 4;
-                    }
-
-                    while (res2) {
-                        if (i2 >= d2.active[0]) {
-                            dst.addRectCashed(rx1, top, rx2, bottom);
-                            while(i1 < d1.active[0]) {
-                                check(d1, i1, true);
-                                i1 += 4;
-                            }
-                            break outer;
-                        }
-                        res2 = next(d2, i2);
-                        i2 += 4;
-                    }
-
-                    res1 = true;
-                    res2 = true;
-                } // while
-
-                d1.deleteActive(bottom);
-                d2.deleteActive(bottom);
-
-            }
-        }
-
-        static void simpleUnion(MultiRectArea src1, MultiRectArea src2, MultiRectArea dst) {
-            if (src1.getRectCount() < src2.getRectCount()) {
-                simpleUnion(src2, src1, dst);
-            } else {
-                Subtraction.simpleSubtract(src1, src2, dst);
-                int pos = dst.rect[0];
-                int size = src2.rect[0] - 1;
-                dst.rect = checkBufSize(dst.rect, size);
-                System.arraycopy(src2.rect,1, dst.rect, pos, size);
-                dst.resort();
-            }
-        }
-
-        MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) {
-
-            if (src1 == null || src1.isEmpty()) {
-                return new MultiRectArea(src2);
-            }
-
-            if (src2 == null || src2.isEmpty()) {
-                return new MultiRectArea(src1);
-            }
-
-            dst = new MultiRectArea.RectCash();
-
-            if (!src1.sorted || !src2.sorted ||
-               src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 
-            {
-                simpleUnion(src1, src2, dst);
-            } else {
-                Rectangle bounds1 = src1.getBounds();
-                Rectangle bounds2 = src2.getBounds();
-                Rectangle bounds3 = bounds1.intersection(bounds2);
-
-                if (bounds3.width < 0 || bounds3.height < 0) {
-                    if (bounds1.y + bounds1.height < bounds2.y) {
-                        dst.setRect(addVerRegion(src1.rect, src2.rect), false);
-                    } else
-                        if (bounds2.y + bounds2.height < bounds1.y) {
-                            dst.setRect(addVerRegion(src2.rect, src1.rect), false);
-                        } else
-                            if (bounds1.x < bounds2.x) {
-                                dst.setRect(addHorRegion(src1.rect, src2.rect), false);
-                            } else {
-                                dst.setRect(addHorRegion(src2.rect, src1.rect), false);
-                            }
-                } else {
-                    unionRegions(src1.rect, src2.rect, bounds1.height + 2, bounds2.height + 2);
-                }
-            }
-
-            return dst;
-        }
-
-        int[] addVerRegion(int[] top, int[] bottom) {
-            int length = top[0] + bottom[0] - 1;
-            int[] dst = new int[length];
-            dst[0] = length;
-            System.arraycopy(top, 1, dst, 1, top[0] - 1);
-            System.arraycopy(bottom, 1, dst, top[0], bottom[0] - 1);
-            return dst;
-        }
-
-        int[] addHorRegion(int[] left, int[] right) {
-            int count1 = left[0];
-            int count2 = right[0];
-            int[] dst = new int[count1 + count2 + 1];
-            int count = 1;
-            int index1 = 1;
-            int index2 = 1;
-
-            int top1 = left[2];
-            int top2 = right[2];
-            int pos1, pos2;
-
-            while(true) {
-
-                if (index1 >= count1) {
-                    System.arraycopy(right, index2, dst, count, count2 - index2);
-                    count += count2 - index2;
-                    break;
-                }
-                if (index2 >= count2) {
-                    System.arraycopy(left, index1, dst, count, count1 - index1);
-                    count += count1 - index1;
-                    break;
-                }
-
-                if (top1 < top2) {
-                    pos1 = index1;
-                    do {
-                        index1 += 4;
-                    } while (index1 < count1 && (top1 = left[index1 + 1]) < top2);
-                    System.arraycopy(left, pos1, dst, count, index1 - pos1);
-                    count += index1 - pos1;
-                    continue;
-                }
-
-                if (top1 > top2) {
-                    pos2 = index2;
-                    do {
-                        index2 += 4;
-                    } while (index2 < count2 && (top2 = right[index2 + 1]) < top1);
-                    System.arraycopy(right, pos2, dst, count, index2 - pos2);
-                    count += index2 - pos2;
-                    continue;
-                }
-
-                int top = top1;
-                pos1 = index1;
-                pos2 = index2;
-                do  {
-                    index1 += 4;
-                } while(index1 < count1 && (top1 = left[index1 + 1]) == top);
-                do {
-                    index2 += 4;
-                } while(index2 < count2 && (top2 = right[index2 + 1]) == top);
-
-                System.arraycopy(left, pos1, dst, count, index1 - pos1);
-                count += index1 - pos1;
-                System.arraycopy(right, pos2, dst, count, index2 - pos2);
-                count += index2 - pos2;
-            }
-
-            dst[0] = count;
-            return dst;
-        }
-
-    }
-
-    /**
-     * Subtraction class provides subtraction of two MultiRectAre aobjects
-     */
-    static class Subtraction {
-
-        static void subtractRegions(int[] reg1, int[] reg2, MultiRectArea.RectCash dst, int height1, int height2) {
-            Region d1 = new Region(reg1);
-            Region d2 = new Region(reg2);
-
-            int[] level = new int[height1 + height2];
-            int[] level1 = new int[height1];
-            int[] level2 = new int[height2];
-            d1.createLevel(level1);
-            d2.createLevel(level2);
-            Region.sortOrdered(level1, level2, level);
-
-            int top;
-            int bottom = level[1] - 1;
-            for(int i = 2; i < level[0]; i++) {
-
-                top = bottom + 1;
-                bottom = level[i] - 1;
-
-                d1.findActive(top, bottom);
-                if (d1.active[0] == 1) {
-                    d2.deleteActive(bottom);
-                    continue;
-                }
-
-                d2.findActive(top, bottom);
-
-                int i1 = 1;
-                int i2 = 1;
-
-                int rx1 = 0;
-                int rx2 = 0;
-
-                boolean next = true;
-
-                while(true) {
-
-                    if (next) {
-                        next = false;
-                        if (i1 >= d1.active[0]) {
-                            break;
-                        }
-                        // Bottom
-                        d1.active[i1 + 1] = bottom + 1;
-                        rx1 = d1.active[i1];
-                        rx2 = d1.active[i1 + 2];
-                        i1 += 4;
-                    }
-
-                    if (i2 >= d2.active[0]) {
-                        dst.addRectCashed(rx1, top, rx2, bottom);
-                        for(int j = i1; j < d1.active[0]; j += 4) {
-                            dst.addRectCashed(d1.active[j], top, d1.active[j + 2], bottom);
-                            d1.active[j + 1] = bottom + 1;
-                        }
-                        break;
-                    }
-
-                    int x1 = d2.active[i2];
-                    int x2 = d2.active[i2 + 2];
-
-                    if (rx1 < x1) {
-                        if (rx2 >= x1) {
-                            if (rx2 <= x2) {
-                                //  [-----------]
-                                //       [-------------]
-                                dst.addRectCashed(rx1, top, x1 - 1, bottom);
-                                next = true;
-                            } else {
-                                // [-----------------]
-                                //      [------]
-                                dst.addRectCashed(rx1, top, x1 - 1, bottom);
-                                rx1 = x2 + 1;
-                                i2 += 4;
-                            }
-                        } else {
-                            // [-----]
-                            //         [----]
-                            dst.addRectCashed(rx1, top, rx2, bottom);
-                            next = true;
-                        }
-                    } else {
-                        if (rx1 <= x2) {
-                            if (rx2 <= x2) {
-                                //    [------]
-                                //  [-----------]
-                                next = true;
-                            } else {
-                                //     [------------]
-                                // [---------]
-                                rx1 = x2 + 1;
-                                i2 += 4;
-                            }
-                        } else {
-                            //         [----]
-                            // [-----]
-                            i2 += 4;
-                        }
-                    }
-
-                }
-                d1.deleteActive();
-                d2.deleteActive(bottom);
-            }
-        }
-
-        static void subtractRect(int x11, int y11, int x12, int y12, int[] rect, int index, MultiRectArea dst) {
-
-            for(int i = index; i < rect[0]; i += 4) {
-                int x21 = rect[i + 0];
-                int y21 = rect[i + 1];
-                int x22 = rect[i + 2];
-                int y22 = rect[i + 3];
-
-                if (x11 <= x22 && x12 >= x21 && y11 <= y22 && y12 >= y21) {
-                    int top, bottom;
-                    if (y11 < y21) {
-                        subtractRect(x11, y11, x12, y21 - 1, rect, i + 4, dst);
-                        top = y21;
-                    } else {
-                        top = y11;
-                    }
-                    if (y12 > y22) {
-                        subtractRect(x11, y22 + 1, x12, y12, rect, i + 4, dst);
-                        bottom = y22;
-                    } else {
-                        bottom = y12;
-                    }
-                    if (x11 < x21) {
-                        subtractRect(x11, top, x21 - 1, bottom, rect, i + 4, dst);
-                    }
-                    if (x12 > x22) {
-                        subtractRect(x22 + 1, top, x12, bottom, rect, i + 4, dst);
-                    }
-                    return;
-                }
-            }
-            dst.addRect(x11, y11, x12, y12);
-        }
-
-        static void simpleSubtract(MultiRectArea src1, MultiRectArea src2, MultiRectArea dst) {
-            for(int i = 1; i < src1.rect[0]; i += 4) {
-                subtractRect(
-                        src1.rect[i + 0],
-                        src1.rect[i + 1],
-                        src1.rect[i + 2],
-                        src1.rect[i + 3],
-                        src2.rect,
-                        1,
-                        dst);
-            }
-            dst.resort();
-        }
-
-        public static MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) {
-
-            if (src1 == null || src1.isEmpty()) {
-                return new MultiRectArea();
-            }
-
-            if (src2 == null || src2.isEmpty()) {
-                return new MultiRectArea(src1);
-            }
-
-            MultiRectArea.RectCash dst = new MultiRectArea.RectCash();
-
-            if (!src1.sorted || !src2.sorted ||
-               src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 
-            {
-                simpleSubtract(src1, src2, dst);
-            } else {
-                Rectangle bounds1 = src1.getBounds();
-                Rectangle bounds2 = src2.getBounds();
-                Rectangle bounds3 = bounds1.intersection(bounds2);
-
-                if (bounds3.width > 0 && bounds3.height > 0) {
-                    subtractRegions(src1.rect, src2.rect, dst, bounds1.height + 2, bounds2.height + 2);
-                } else {
-                    dst.setRect(src1.rect, true);
-                }
-            }
-
-            return dst;
-        }
-
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/Surface.java b/awt/org/apache/harmony/awt/gl/Surface.java
deleted file mode 100644
index 8b0ae38..0000000
--- a/awt/org/apache/harmony/awt/gl/Surface.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- * Created on 10.11.2005
- *
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.Image;
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.ComponentSampleModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DirectColorModel;
-import java.awt.image.IndexColorModel;
-import java.awt.image.MultiPixelPackedSampleModel;
-import java.awt.image.SampleModel;
-import java.awt.image.WritableRaster;
-import java.util.ArrayList;
-
-import org.apache.harmony.awt.gl.color.LUTColorConverter;
-
-
-/**
- * This class is super class for others types of Surfaces. 
- * Surface is storing data and data format description, that are using
- * in blitting operations    
- */
-public abstract class Surface implements Transparency{
-
-    // Color Space Types
-    public static final int sRGB_CS = 1;
-    public static final int Linear_RGB_CS = 2;
-    public static final int Linear_Gray_CS = 3;
-    public static final int Custom_CS = 0;
-    
-    // Color Model Types
-    public static final int DCM = 1;  // Direct Color Model
-    public static final int ICM = 2;  // Index Color Model
-    public static final int CCM = 3;  // Component Color Model
-
-    // Sample Model Types
-    public static final int SPPSM = 1;  // Single Pixel Packed Sample Model
-    public static final int MPPSM = 2;  // Multi Pixel Packed Sample Model
-    public static final int CSM   = 3;  // Component Sample Model
-    public static final int PISM  = 4;  // Pixel Interleaved Sample Model
-    public static final int BSM   = 5;  // Banded Sample Model
-
-    // Surface Types
-    private static final int ALPHA_MASK = 0xff000000;
-    private static final int RED_MASK = 0x00ff0000;
-    private static final int GREEN_MASK = 0x0000ff00;
-    private static final int BLUE_MASK = 0x000000ff;
-    private static final int RED_BGR_MASK = 0x000000ff;
-    private static final int GREEN_BGR_MASK = 0x0000ff00;
-    private static final int BLUE_BGR_MASK = 0x00ff0000;
-    private static final int RED_565_MASK = 0xf800;
-    private static final int GREEN_565_MASK = 0x07e0;
-    private static final int BLUE_565_MASK = 0x001f;
-    private static final int RED_555_MASK = 0x7c00;
-    private static final int GREEN_555_MASK = 0x03e0;
-    private static final int BLUE_555_MASK = 0x001f;
-
-    static{
-        //???AWT
-        /*
-        System.loadLibrary("gl"); //$NON-NLS-1$
-        initIDs();
-        */
-    }
-
-
-    protected long surfaceDataPtr;        // Pointer for Native Surface data
-    protected int transparency = OPAQUE;
-    protected int width;
-    protected int height;
-
-    /**
-     * This list contains caches with the data of this surface that are valid at the moment.
-     * Surface should clear this list when its data is updated.
-     * Caches may check if they are still valid using isCacheValid method.
-     * When cache gets data from the surface, it should call addValidCache method of the surface.
-     */
-    private final ArrayList<Object> validCaches = new ArrayList<Object>();
-
-    public abstract ColorModel getColorModel();
-    public abstract WritableRaster getRaster();
-    public abstract int getSurfaceType(); // Syrface type. It is equal 
-                                          // BufferedImge type
-    /**
-     * Lock Native Surface data
-     */
-    public abstract long lock();     
-    
-    /**
-     * Unlock Native Surface data 
-     */
-    public abstract void unlock();
-    
-    /**
-     * Dispose Native Surface data
-     */
-    public abstract void dispose();
-    public abstract Surface getImageSurface();
-
-    public long getSurfaceDataPtr(){
-        return surfaceDataPtr;
-    }
-
-    public final boolean isCaheValid(Object cache) {
-        return validCaches.contains(cache);
-    }
-
-    public final void addValidCache(Object cache) {
-        validCaches.add(cache);
-    }
-
-    protected final void clearValidCaches() {
-        validCaches.clear();
-    }
-
-    /**
-     * Returns could or coldn't the Surface be blit by Native blitter 
-     * @return - true if the Surface could be blit by Native blitter, 
-     *           false in other case
-     */
-    public boolean isNativeDrawable(){
-        return true;
-    }
-
-    public int getTransparency() {
-        return transparency;
-    }
-
-    public int getWidth(){
-        return width;
-    }
-
-    public int getHeight(){
-        return height;
-    }
-    
-    /**
-     * If Surface has Raster, this method returns data array of Raster's DataBuffer
-     * @return - data array
-     */
-    public Object getData(){
-        return null;
-    }
-    
-    public boolean invalidated(){
-        return true;
-    }
-    
-    public void validate(){}
-    
-    public void invalidate(){}
-
-    /**
-     * Computation type of BufferedImage or Surface
-     * @param cm - ColorModel
-     * @param raster - WritableRaste
-     * @return - type of BufferedImage
-     */
-    public static int getType(ColorModel cm, WritableRaster raster){
-        int transferType = cm.getTransferType();
-        boolean hasAlpha = cm.hasAlpha();
-        ColorSpace cs = cm.getColorSpace();
-        int csType = cs.getType();
-        SampleModel sm = raster.getSampleModel();
-
-        if(csType == ColorSpace.TYPE_RGB){
-            if(cm instanceof DirectColorModel){
-                DirectColorModel dcm = (DirectColorModel) cm;
-                switch (transferType) {
-                case DataBuffer.TYPE_INT:
-                    if (dcm.getRedMask() == RED_MASK &&
-                            dcm.getGreenMask() == GREEN_MASK &&
-                            dcm.getBlueMask() == BLUE_MASK) {
-                        if (!hasAlpha) {
-                            return BufferedImage.TYPE_INT_RGB;
-                        }
-                        if (dcm.getAlphaMask() == ALPHA_MASK) {
-                            if (dcm.isAlphaPremultiplied()) {
-                                return BufferedImage.TYPE_INT_ARGB_PRE;
-                            }
-                            return BufferedImage.TYPE_INT_ARGB;
-                        }
-                        return BufferedImage.TYPE_CUSTOM;
-                    } else if (dcm.getRedMask() == RED_BGR_MASK &&
-                            dcm.getGreenMask() == GREEN_BGR_MASK &&
-                            dcm.getBlueMask() == BLUE_BGR_MASK) {
-                        if (!hasAlpha) {
-                            return BufferedImage.TYPE_INT_BGR;
-                        }
-                    } else {
-                        return BufferedImage.TYPE_CUSTOM;
-                    }
-                case DataBuffer.TYPE_USHORT:
-                    if (dcm.getRedMask() == RED_555_MASK &&
-                            dcm.getGreenMask() == GREEN_555_MASK &&
-                            dcm.getBlueMask() == BLUE_555_MASK && !hasAlpha) {
-                        return BufferedImage.TYPE_USHORT_555_RGB;
-                    } else if (dcm.getRedMask() == RED_565_MASK &&
-                            dcm.getGreenMask() == GREEN_565_MASK &&
-                            dcm.getBlueMask() == BLUE_565_MASK) {
-                        return BufferedImage.TYPE_USHORT_565_RGB;
-                    }
-                default:
-                    return BufferedImage.TYPE_CUSTOM;
-                }
-            }else if(cm instanceof IndexColorModel){
-                IndexColorModel icm = (IndexColorModel) cm;
-                int pixelBits = icm.getPixelSize();
-                if(transferType == DataBuffer.TYPE_BYTE){
-                    if(sm instanceof MultiPixelPackedSampleModel && !hasAlpha &&
-                        pixelBits < 5){
-                            return BufferedImage.TYPE_BYTE_BINARY;
-                    }else if(pixelBits == 8){
-                        return BufferedImage.TYPE_BYTE_INDEXED;
-                    }
-                }
-                return BufferedImage.TYPE_CUSTOM;
-            }else if(cm instanceof ComponentColorModel){
-                ComponentColorModel ccm = (ComponentColorModel) cm;
-                if(transferType == DataBuffer.TYPE_BYTE &&
-                        sm instanceof ComponentSampleModel){
-                    ComponentSampleModel csm =
-                        (ComponentSampleModel) sm;
-                    int[] offsets = csm.getBandOffsets();
-                    int[] bits = ccm.getComponentSize();
-                    boolean isCustom = false;
-                    for (int i = 0; i < bits.length; i++) {
-                        if (bits[i] != 8 ||
-                               offsets[i] != offsets.length - 1 - i) {
-                            isCustom = true;
-                            break;
-                        }
-                    }
-                    if (!isCustom) {
-                        if (!ccm.hasAlpha()) {
-                            return BufferedImage.TYPE_3BYTE_BGR;
-                        } else if (ccm.isAlphaPremultiplied()) {
-                            return BufferedImage.TYPE_4BYTE_ABGR_PRE;
-                        } else {
-                            return BufferedImage.TYPE_4BYTE_ABGR;
-                        }
-                    }
-                }
-                return BufferedImage.TYPE_CUSTOM;
-            }
-            return BufferedImage.TYPE_CUSTOM;
-        }else if(cs == LUTColorConverter.LINEAR_GRAY_CS){
-            if(cm instanceof ComponentColorModel &&
-                    cm.getNumComponents() == 1){
-                int bits[] = cm.getComponentSize();
-                if(transferType == DataBuffer.TYPE_BYTE &&
-                        bits[0] == 8){
-                    return BufferedImage.TYPE_BYTE_GRAY;
-                }else if(transferType == DataBuffer.TYPE_USHORT &&
-                        bits[0] == 16){
-                    return BufferedImage.TYPE_USHORT_GRAY;
-                }else{
-                    return BufferedImage.TYPE_CUSTOM;
-                }
-            }
-            return BufferedImage.TYPE_CUSTOM;
-        }
-        return BufferedImage.TYPE_CUSTOM;
-    }
-
-    public static Surface getImageSurface(Image image){
-        return AwtImageBackdoorAccessor.getInstance().getImageSurface(image);
-    }
-
-    @Override
-    protected void finalize() throws Throwable{
-        dispose();
-    }
-
-    public static boolean isGrayPallete(IndexColorModel icm){
-        return AwtImageBackdoorAccessor.getInstance().isGrayPallete(icm);
-    }
-
-    /**
-     * Initialization of Native data
-     * 
-     */
-    //???AWT: private static native void initIDs();
-}
diff --git a/awt/org/apache/harmony/awt/gl/TextRenderer.java b/awt/org/apache/harmony/awt/gl/TextRenderer.java
deleted file mode 100644
index f57952d..0000000
--- a/awt/org/apache/harmony/awt/gl/TextRenderer.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.Graphics2D;
-import java.awt.font.GlyphVector;
-
-public abstract class TextRenderer {
-    
-    /**
-     * Draws string on specified Graphics at desired position.
-     * 
-     * @param g specified Graphics2D object
-     * @param str String object to draw
-     * @param x start X position to draw
-     * @param y start Y position to draw
-     */
-    public abstract void drawString(Graphics2D g, String str, float x, float y);
-
-    /**
-     * Draws string on specified Graphics at desired position.
-     * 
-     * @param g specified Graphics2D object
-     * @param str String object to draw
-     * @param x start X position to draw
-     * @param y start Y position to draw
-     */    
-    public void drawString(Graphics2D g, String str, int x, int y){
-        drawString(g, str, (float)x, (float)y);
-    }
-
-    /**
-     * Draws GlyphVector on specified Graphics at desired position.
-     * 
-     * @param g specified Graphics2D object
-     * @param glyphVector GlyphVector object to draw
-     * @param x start X position to draw
-     * @param y start Y position to draw
-     */
-    public abstract void drawGlyphVector(Graphics2D g, GlyphVector glyphVector, float x, float y);
-}
diff --git a/awt/org/apache/harmony/awt/gl/XORComposite.java b/awt/org/apache/harmony/awt/gl/XORComposite.java
deleted file mode 100644
index e27e1d3..0000000
--- a/awt/org/apache/harmony/awt/gl/XORComposite.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- * Created on 21.11.2005
- *
- */
-package org.apache.harmony.awt.gl;
-
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.CompositeContext;
-import java.awt.RenderingHints;
-import java.awt.image.ColorModel;
-
-public class XORComposite implements Composite {
-
-    Color xorcolor;
-
-    public XORComposite(Color xorcolor){
-        this.xorcolor = xorcolor;
-    }
-
-    public CompositeContext createContext(ColorModel srcCM, ColorModel dstCM,
-            RenderingHints hints) {
-
-        return new ICompositeContext(this, srcCM, dstCM);
-    }
-
-    public Color getXORColor(){
-        return xorcolor;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/color/ColorConverter.java b/awt/org/apache/harmony/awt/gl/color/ColorConverter.java
deleted file mode 100644
index c98e114..0000000
--- a/awt/org/apache/harmony/awt/gl/color/ColorConverter.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.color;
-
-import java.awt.color.ColorSpace;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-
-/**
- * This class combines ColorScaler, ICC_Transform and NativeImageFormat functionality
- * in the workflows for different types of input/output pixel data.
- */
-public class ColorConverter {
-    private ColorScaler scaler = new ColorScaler();
-
-    public void loadScalingData(ColorSpace cs) {
-        scaler.loadScalingData(cs);
-    }
-
-    /**
-     * Translates pixels, stored in source buffered image and writes the data
-     * to the destination image.
-     * @param t - ICC transform
-     * @param src - source image
-     * @param dst - destination image
-     */
-    public void translateColor(ICC_Transform t,
-            BufferedImage src, BufferedImage dst) {
-      NativeImageFormat srcIF = NativeImageFormat.createNativeImageFormat(src);
-      NativeImageFormat dstIF = NativeImageFormat.createNativeImageFormat(dst);
-
-      if (srcIF != null && dstIF != null) {
-          t.translateColors(srcIF, dstIF);
-          return;
-      }
-
-        srcIF = createImageFormat(src);
-        dstIF = createImageFormat(dst);
-
-        short srcChanData[] = (short[]) srcIF.getChannelData();
-        short dstChanData[] = (short[]) dstIF.getChannelData();
-
-        ColorModel srcCM = src.getColorModel();
-        int nColorChannels = srcCM.getNumColorComponents();
-        scaler.loadScalingData(srcCM.getColorSpace()); // input scaling data
-        ColorModel dstCM = dst.getColorModel();
-
-        // Prepare array for alpha channel
-        float alpha[] = null;
-        boolean saveAlpha = srcCM.hasAlpha() && dstCM.hasAlpha();
-        if (saveAlpha) {
-            alpha = new float[src.getWidth()*src.getHeight()];
-        }
-
-        WritableRaster wr = src.getRaster();
-        int srcDataPos = 0, alphaPos = 0;
-        float normalizedVal[];
-        for (int row=0, nRows = srcIF.getNumRows(); row<nRows; row++) {
-            for (int col=0, nCols = srcIF.getNumCols(); col<nCols; col++) {
-                normalizedVal = srcCM.getNormalizedComponents(
-                    wr.getDataElements(col, row, null),
-                    null, 0);
-                // Save alpha channel
-                if (saveAlpha) {
-                    // We need nColorChannels'th element cause it's nChannels - 1
-                    alpha[alphaPos++] = normalizedVal[nColorChannels];
-                }
-                scaler.scale(normalizedVal, srcChanData, srcDataPos);
-                srcDataPos += nColorChannels;
-            }
-        }
-
-        t.translateColors(srcIF, dstIF);
-
-        nColorChannels = dstCM.getNumColorComponents();
-        boolean fillAlpha = dstCM.hasAlpha();
-        scaler.loadScalingData(dstCM.getColorSpace()); // output scaling data
-        float dstPixel[] = new float[dstCM.getNumComponents()];
-        int dstDataPos = 0;
-        alphaPos = 0;
-        wr = dst.getRaster();
-
-        for (int row=0, nRows = dstIF.getNumRows(); row<nRows; row++) {
-            for (int col=0, nCols = dstIF.getNumCols(); col<nCols; col++) {
-                scaler.unscale(dstPixel, dstChanData, dstDataPos);
-                dstDataPos += nColorChannels;
-                if (fillAlpha) {
-                    if (saveAlpha) {
-                        dstPixel[nColorChannels] = alpha[alphaPos++];
-                    } else {
-                        dstPixel[nColorChannels] = 1f;
-                    }
-                }
-                wr.setDataElements(col, row,
-                        dstCM.getDataElements(dstPixel, 0 , null));
-            }
-        }
-    }
-
-    /**
-     * Translates pixels, stored in the float data buffer.
-     * Each pixel occupies separate array. Input pixels passed in the buffer
-     * are replaced by output pixels and then the buffer is returned
-     * @param t - ICC transform
-     * @param buffer - data buffer
-     * @param srcCS - source color space
-     * @param dstCS - destination color space
-     * @param nPixels - number of pixels
-     * @return translated pixels
-     */
-    public float[][] translateColor(ICC_Transform t,
-            float buffer[][],
-            ColorSpace srcCS,
-            ColorSpace dstCS,
-            int nPixels) {
-        // Scale source data
-        if (srcCS != null) { // if it is null use old scaling data
-            scaler.loadScalingData(srcCS);
-        }
-        int nSrcChannels = t.getNumInputChannels();
-        short srcShortData[] = new short[nPixels*nSrcChannels];
-        for (int i=0, srcDataPos = 0; i<nPixels; i++) {
-            scaler.scale(buffer[i], srcShortData, srcDataPos);
-            srcDataPos += nSrcChannels;
-        }
-
-        // Apply transform
-        short dstShortData[] = this.translateColor(t, srcShortData, null);
-
-        int nDstChannels = t.getNumOutputChannels();
-        int bufferSize = buffer[0].length;
-        if (bufferSize < nDstChannels + 1) { // Re-allocate buffer if needed
-            for (int i=0; i<nPixels; i++) {
-                // One extra element reserved for alpha
-                buffer[i] = new float[nDstChannels + 1];
-            }
-        }
-
-        // Unscale destination data
-        if (dstCS != null) { // if it is null use old scaling data
-            scaler.loadScalingData(dstCS);
-        }
-        for (int i=0, dstDataPos = 0; i<nPixels; i++) {
-            scaler.unscale(buffer[i], dstShortData, dstDataPos);
-            dstDataPos += nDstChannels;
-        }
-
-        return buffer;
-    }
-
-    /**
-     * Translates pixels stored in a raster.
-     * All data types are supported
-     * @param t - ICC transform
-     * @param src - source pixels
-     * @param dst - destination pixels
-     */
-   public void translateColor(ICC_Transform t, Raster src, WritableRaster dst) {
-        try{
-            NativeImageFormat srcFmt = NativeImageFormat.createNativeImageFormat(src);
-            NativeImageFormat dstFmt = NativeImageFormat.createNativeImageFormat(dst);
-
-          if (srcFmt != null && dstFmt != null) {
-              t.translateColors(srcFmt, dstFmt);
-              return;
-          }
-        } catch (IllegalArgumentException e) {
-      }
-
-        // Go ahead and rescale the source image
-        scaler.loadScalingData(src, t.getSrc());
-        short srcData[] = scaler.scale(src);
-
-        short dstData[] = translateColor(t, srcData, null);
-
-        scaler.loadScalingData(dst, t.getDst());
-        scaler.unscale(dstData, dst);
-   }
-
-    /**
-     * Translates pixels stored in an array of shorts.
-     * Samples are stored one-by-one, i.e. array structure is like following: RGBRGBRGB...
-     * The number of pixels is (size of the array) / (number of components).
-     * @param t - ICC transform
-     * @param src - source pixels
-     * @param dst - destination pixels
-     * @return destination pixels, stored in the array, passed in dst
-     */
-    public short[] translateColor(ICC_Transform t, short src[], short dst[]) {
-        NativeImageFormat srcFmt = createImageFormat(t, src, 0, true);
-        NativeImageFormat dstFmt = createImageFormat(t, dst, srcFmt.getNumCols(), false);
-
-        t.translateColors(srcFmt, dstFmt);
-
-        return (short[]) dstFmt.getChannelData();
-    }
-
-
-    /**
-     * Creates NativeImageFormat from buffered image.
-     * @param bi - buffered image
-     * @return created NativeImageFormat
-     */
-    private NativeImageFormat createImageFormat(BufferedImage bi) {
-        int nRows = bi.getHeight();
-        int nCols = bi.getWidth();
-        int nComps = bi.getColorModel().getNumColorComponents();
-        short imgData[] = new short[nRows*nCols*nComps];
-        return new NativeImageFormat(
-                imgData, nComps, nRows, nCols);
-    }
-
-    /**
-     * Creates one-row NativeImageFormat, using either nCols if it is positive,
-     * or arr.length to determine the number of pixels
-     *
-     * @param t - transform
-     * @param arr - short array or null if nCols is positive
-     * @param nCols - number of pixels in the array or 0 if array is not null
-     * @param in - is it an input or output array
-     * @return one-row NativeImageFormat
-     */
-    private NativeImageFormat createImageFormat(
-            ICC_Transform t, short arr[], int nCols, boolean in
-    ) {
-        int nComponents = in ? t.getNumInputChannels() : t.getNumOutputChannels();
-
-        if (arr == null || arr.length < nCols*nComponents) {
-            arr = new short[nCols*nComponents];
-        }
-
-        if (nCols == 0)
-            nCols = arr.length / nComponents;
-
-        return new NativeImageFormat(arr, nComponents, 1, nCols);
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/color/ColorScaler.java b/awt/org/apache/harmony/awt/gl/color/ColorScaler.java
deleted file mode 100644
index a1cc169..0000000
--- a/awt/org/apache/harmony/awt/gl/color/ColorScaler.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.color;
-
-import java.awt.color.ColorSpace;
-import java.awt.color.ICC_Profile;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-import java.awt.image.SampleModel;
-import java.awt.image.WritableRaster;
-
-/**
- * This class provides functionality for scaling color data when
- * ranges of the source and destination color values differs. 
- */
-public class ColorScaler {
-    private static final float MAX_SHORT = 0xFFFF;
-    private static final float MAX_SIGNED_SHORT = 0x7FFF;
-
-    private static final float MAX_XYZ = 1f + (32767f/32768f);
-
-    // Cached values for scaling color data
-    private float[] channelMinValues = null;
-    private float[] channelMulipliers = null; // for scale
-    private float[] invChannelMulipliers = null; // for unscale
-
-    int nColorChannels = 0;
-
-    // For scaling rasters, false if transfer type is double or float
-    boolean isTTypeIntegral = false;
-
-    /**
-     * Loads scaling data for raster. Note, if profile pf is null,
-     * for non-integral data types multipliers are not initialized.
-     * @param r - raster
-     * @param pf - profile which helps to determine the ranges of the color data
-     */
-    public void loadScalingData(Raster r, ICC_Profile pf) {
-        boolean isSrcTTypeIntegral =
-            r.getTransferType() != DataBuffer.TYPE_FLOAT &&
-            r.getTransferType() != DataBuffer.TYPE_DOUBLE;
-        if (isSrcTTypeIntegral)
-            loadScalingData(r.getSampleModel());
-        else if (pf != null)
-            loadScalingData(pf);
-    }
-
-    /**
-     * Use this method only for integral transfer types.
-     * Extracts min/max values from the sample model
-     * @param sm - sample model
-     */
-    public void loadScalingData(SampleModel sm) {
-        // Supposing integral transfer type
-        isTTypeIntegral = true;
-
-        nColorChannels = sm.getNumBands();
-
-        channelMinValues = new float[nColorChannels];
-        channelMulipliers = new float[nColorChannels];
-        invChannelMulipliers = new float[nColorChannels];
-
-        boolean isSignedShort =
-            (sm.getTransferType() == DataBuffer.TYPE_SHORT);
-
-        float maxVal;
-        for (int i=0; i<nColorChannels; i++) {
-            channelMinValues[i] = 0;
-            if (isSignedShort) {
-                channelMulipliers[i] = MAX_SHORT / MAX_SIGNED_SHORT;
-                invChannelMulipliers[i] = MAX_SIGNED_SHORT / MAX_SHORT;
-            } else {
-                maxVal = ((1 << sm.getSampleSize(i)) - 1);
-                channelMulipliers[i] = MAX_SHORT / maxVal;
-                invChannelMulipliers[i] = maxVal / MAX_SHORT;
-            }
-        }
-    }
-
-    /**
-     * Use this method only for double of float transfer types.
-     * Extracts scaling data from the color space signature
-     * and other tags, stored in the profile
-     * @param pf - ICC profile
-     */
-    public void loadScalingData(ICC_Profile pf) {
-        // Supposing double or float transfer type
-        isTTypeIntegral = false;
-
-        nColorChannels = pf.getNumComponents();
-
-        // Get min/max values directly from the profile
-        // Very much like fillMinMaxValues in ICC_ColorSpace
-        float maxValues[] = new float[nColorChannels];
-        float minValues[] = new float[nColorChannels];
-
-        switch (pf.getColorSpaceType()) {
-            case ColorSpace.TYPE_XYZ:
-                minValues[0] = 0;
-                minValues[1] = 0;
-                minValues[2] = 0;
-                maxValues[0] = MAX_XYZ;
-                maxValues[1] = MAX_XYZ;
-                maxValues[2] = MAX_XYZ;
-                break;
-            case ColorSpace.TYPE_Lab:
-                minValues[0] = 0;
-                minValues[1] = -128;
-                minValues[2] = -128;
-                maxValues[0] = 100;
-                maxValues[1] = 127;
-                maxValues[2] = 127;
-                break;
-            default:
-                for (int i=0; i<nColorChannels; i++) {
-                    minValues[i] = 0;
-                    maxValues[i] = 1;
-                }
-        }
-
-        channelMinValues = minValues;
-        channelMulipliers = new float[nColorChannels];
-        invChannelMulipliers = new float[nColorChannels];
-
-        for (int i = 0; i < nColorChannels; i++) {
-            channelMulipliers[i] =
-                MAX_SHORT / (maxValues[i] - channelMinValues[i]);
-
-            invChannelMulipliers[i] =
-                (maxValues[i] - channelMinValues[i]) / MAX_SHORT;
-        }
-    }
-
-    /**
-     * Extracts scaling data from the color space
-     * @param cs - color space
-     */
-    public void loadScalingData(ColorSpace cs) {
-        nColorChannels = cs.getNumComponents();
-
-        channelMinValues = new float[nColorChannels];
-        channelMulipliers = new float[nColorChannels];
-        invChannelMulipliers = new float[nColorChannels];
-
-        for (int i = 0; i < nColorChannels; i++) {
-            channelMinValues[i] = cs.getMinValue(i);
-
-            channelMulipliers[i] =
-                MAX_SHORT / (cs.getMaxValue(i) - channelMinValues[i]);
-
-            invChannelMulipliers[i] =
-                (cs.getMaxValue(i) - channelMinValues[i]) / MAX_SHORT;
-        }
-    }
-
-    /**
-     * Scales and normalizes the whole raster and returns the result
-     * in the float array
-     * @param r - source raster
-     * @return scaled and normalized raster data
-     */
-    public float[][] scaleNormalize(Raster r) {
-        int width = r.getWidth();
-        int height = r.getHeight();
-        float result[][] = new float[width*height][nColorChannels];
-        float normMultipliers[] = new float[nColorChannels];
-
-        int pos = 0;
-        if (isTTypeIntegral) {
-            // Change max value from MAX_SHORT to 1f
-            for (int i=0; i<nColorChannels; i++) {
-                normMultipliers[i] = channelMulipliers[i] / MAX_SHORT;
-            }
-
-            int sample;
-            for (int row=r.getMinX(); row<width; row++) {
-                for (int col=r.getMinY(); col<height; col++) {
-                    for (int chan = 0; chan < nColorChannels; chan++) {
-                        sample = r.getSample(row, col, chan);
-                        result[pos][chan] = (sample * normMultipliers[chan]);
-                    }
-                    pos++;
-                }
-            }
-        } else { // Just get the samples...
-            for (int row=r.getMinX(); row<width; row++) {
-                for (int col=r.getMinY(); col<height; col++) {
-                    for (int chan = 0; chan < nColorChannels; chan++) {
-                        result[pos][chan] = r.getSampleFloat(row, col, chan);
-                    }
-                    pos++;
-                }
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Unscale the whole float array and put the result
-     * in the raster
-     * @param r - destination raster
-     * @param data - input pixels
-     */
-    public void unscaleNormalized(WritableRaster r, float data[][]) {
-        int width = r.getWidth();
-        int height = r.getHeight();
-        float normMultipliers[] = new float[nColorChannels];
-
-        int pos = 0;
-        if (isTTypeIntegral) {
-            // Change max value from MAX_SHORT to 1f
-            for (int i=0; i<nColorChannels; i++) {
-                normMultipliers[i] = invChannelMulipliers[i] * MAX_SHORT;
-            }
-
-            int sample;
-            for (int row=r.getMinX(); row<width; row++) {
-                for (int col=r.getMinY(); col<height; col++) {
-                    for (int chan = 0; chan < nColorChannels; chan++) {
-                        sample = (int) (data[pos][chan] * normMultipliers[chan] + 0.5f);
-                        r.setSample(row, col, chan, sample);
-                    }
-                    pos++;
-                }
-            }
-        } else { // Just set the samples...
-            for (int row=r.getMinX(); row<width; row++) {
-                for (int col=r.getMinY(); col<height; col++) {
-                    for (int chan = 0; chan < nColorChannels; chan++) {
-                        r.setSample(row, col, chan, data[pos][chan]);
-                    }
-                    pos++;
-                }
-            }
-        }
-    }
-
-    /**
-     * Scales the whole raster to short and returns the result
-     * in the array
-     * @param r - source raster
-     * @return scaled and normalized raster data
-     */
-    public short[] scale(Raster r) {
-        int width = r.getWidth();
-        int height = r.getHeight();
-        short result[] = new short[width*height*nColorChannels];
-
-        int pos = 0;
-        if (isTTypeIntegral) {
-            int sample;
-            for (int row=r.getMinX(); row<width; row++) {
-                for (int col=r.getMinY(); col<height; col++) {
-                    for (int chan = 0; chan < nColorChannels; chan++) {
-                        sample = r.getSample(row, col, chan);
-                        result[pos++] =
-                            (short) (sample * channelMulipliers[chan] + 0.5f);
-                    }
-                }
-            }
-        } else {
-            float sample;
-            for (int row=r.getMinX(); row<width; row++) {
-                for (int col=r.getMinY(); col<height; col++) {
-                    for (int chan = 0; chan < nColorChannels; chan++) {
-                        sample = r.getSampleFloat(row, col, chan);
-                        result[pos++] = (short) ((sample - channelMinValues[chan])
-                            * channelMulipliers[chan] + 0.5f);
-                    }
-                }
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Unscales the whole data array and puts obtained values to the raster
-     * @param data - input data
-     * @param wr - destination raster
-     */
-    public void unscale(short[] data, WritableRaster wr) {
-        int width = wr.getWidth();
-        int height = wr.getHeight();
-
-        int pos = 0;
-        if (isTTypeIntegral) {
-            int sample;
-            for (int row=wr.getMinX(); row<width; row++) {
-                for (int col=wr.getMinY(); col<height; col++) {
-                    for (int chan = 0; chan < nColorChannels; chan++) {
-                         sample = (int) ((data[pos++] & 0xFFFF) *
-                                invChannelMulipliers[chan] + 0.5f);
-                         wr.setSample(row, col, chan, sample);
-                    }
-                }
-            }
-        } else {
-            float sample;
-            for (int row=wr.getMinX(); row<width; row++) {
-                for (int col=wr.getMinY(); col<height; col++) {
-                    for (int chan = 0; chan < nColorChannels; chan++) {
-                         sample = (data[pos++] & 0xFFFF) *
-                            invChannelMulipliers[chan] + channelMinValues[chan];
-                         wr.setSample(row, col, chan, sample);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Scales one pixel and puts obtained values to the chanData
-     * @param pixelData - input pixel
-     * @param chanData - output buffer
-     * @param chanDataOffset - output buffer offset
-     */
-    public void scale(float[] pixelData, short[] chanData, int chanDataOffset) {
-        for (int chan = 0; chan < nColorChannels; chan++) {
-            chanData[chanDataOffset + chan] =
-                    (short) ((pixelData[chan] - channelMinValues[chan]) *
-                        channelMulipliers[chan] + 0.5f);
-        }
-    }
-
-    /**
-     * Unscales one pixel and puts obtained values to the pixelData
-     * @param pixelData - output pixel
-     * @param chanData - input buffer
-     * @param chanDataOffset - input buffer offset
-     */
-    public void unscale(float[] pixelData, short[] chanData, int chanDataOffset) {
-        for (int chan = 0; chan < nColorChannels; chan++) {
-            pixelData[chan] = (chanData[chanDataOffset + chan] & 0xFFFF)
-                * invChannelMulipliers[chan] + channelMinValues[chan];
-        }
-    }
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/color/ICC_ProfileHelper.java b/awt/org/apache/harmony/awt/gl/color/ICC_ProfileHelper.java
deleted file mode 100644
index 2f7e519..0000000
--- a/awt/org/apache/harmony/awt/gl/color/ICC_ProfileHelper.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.color;
-
-import java.awt.color.ICC_Profile;
-
-/**
- * Includes utility methods for reading ICC profile data.
- * Created to provide public access to ICC_Profile methods
- * for classes outside of java.awt.color
- */
-public class ICC_ProfileHelper {
-    /**
-     * Utility method.
-     * Gets integer value from the byte array
-     * @param byteArray - byte array
-     * @param idx - byte offset
-     * @return integer value
-     */
-    public static int getIntFromByteArray(byte[] byteArray, int idx) {
-        return (byteArray[idx] & 0xFF)|
-               ((byteArray[idx+1] & 0xFF) << 8) |
-               ((byteArray[idx+2] & 0xFF) << 16)|
-               ((byteArray[idx+3] & 0xFF) << 24);
-    }
-
-    /**
-     * Utility method.
-     * Gets big endian integer value from the byte array
-     * @param byteArray - byte array
-     * @param idx - byte offset
-     * @return integer value
-     */
-    public static int getBigEndianFromByteArray(byte[] byteArray, int idx) {
-        return ((byteArray[idx] & 0xFF) << 24)   |
-               ((byteArray[idx+1] & 0xFF) << 16) |
-               ((byteArray[idx+2] & 0xFF) << 8)  |
-               ( byteArray[idx+3] & 0xFF);
-    }
-
-    /**
-     * Utility method.
-     * Gets short value from the byte array
-     * @param byteArray - byte array
-     * @param idx - byte offset
-     * @return short value
-     */
-    public static short getShortFromByteArray(byte[] byteArray, int idx) {
-        return (short) ((byteArray[idx] & 0xFF) |
-                       ((byteArray[idx+1] & 0xFF) << 8));
-    }
-
-    /**
-     * Used in ICC_Transform class to check the rendering intent of the profile
-     * @param profile - ICC profile
-     * @return rendering intent
-     */
-    public static int getRenderingIntent(ICC_Profile profile) {
-        return getIntFromByteArray(
-                profile.getData(ICC_Profile.icSigHead), // pf header
-                ICC_Profile.icHdrRenderingIntent
-            );
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/color/ICC_Transform.java b/awt/org/apache/harmony/awt/gl/color/ICC_Transform.java
deleted file mode 100644
index 27646c4..0000000
--- a/awt/org/apache/harmony/awt/gl/color/ICC_Transform.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.color;
-
-import java.awt.color.ICC_Profile;
-
-import org.apache.harmony.awt.gl.color.NativeCMM;
-
-/**
- * This class encapsulates native ICC transform object, is responsible for its
- * creation, destruction and passing its handle to the native CMM.
- */
-public class ICC_Transform {
-    private long transformHandle;
-    private int numInputChannels;
-    private int numOutputChannels;
-    private ICC_Profile src;
-    private ICC_Profile dst;
-
-
-    /**
-     * @return Returns the number of input channels.
-     */
-    public int getNumInputChannels() {
-        return numInputChannels;
-    }
-
-    /**
-     * @return Returns the number of output channels.
-     */
-    public int getNumOutputChannels() {
-        return numOutputChannels;
-    }
-
-    /**
-     * @return Returns the dst.
-     */
-    public ICC_Profile getDst() {
-        return dst;
-    }
-
-    /**
-     * @return Returns the src.
-     */
-    public ICC_Profile getSrc() {
-        return src;
-    }
-
-    /**
-     * Constructs a multiprofile ICC transform
-     * @param profiles - list of ICC profiles
-     * @param renderIntents - only hints for CMM
-     */
-    public ICC_Transform(ICC_Profile[] profiles, int[] renderIntents) {
-        int numProfiles = profiles.length;
-
-        long[] profileHandles = new long[numProfiles];
-        for (int i=0; i<numProfiles; i++) {
-            profileHandles[i] = NativeCMM.getHandle(profiles[i]);
-        }
-
-        transformHandle = NativeCMM.cmmCreateMultiprofileTransform(
-                profileHandles,
-                renderIntents);
-
-        src = profiles[0];
-        dst = profiles[numProfiles-1];
-        numInputChannels = src.getNumComponents();
-        numOutputChannels = dst.getNumComponents();
-    }
-
-    /**
-     * This constructor is able to set intents by default
-     * @param profiles - list of ICC profiles
-     */
-    public ICC_Transform(ICC_Profile[] profiles) {
-        int numProfiles = profiles.length;
-        int[] renderingIntents = new int[numProfiles];
-
-        // Default is perceptual
-        int currRenderingIntent = ICC_Profile.icPerceptual;
-
-        // render as colorimetric for output device
-        if (profiles[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) {
-            currRenderingIntent = ICC_Profile.icRelativeColorimetric;
-        }
-
-        // get the transforms from each profile
-        for (int i = 0; i < numProfiles; i++) {
-            // first or last profile cannot be abstract
-            // if profile is abstract, the only possible way is
-            // use AToB0Tag (perceptual), see ICC spec
-            if (i != 0 &&
-               i != numProfiles - 1 &&
-               profiles[i].getProfileClass() == ICC_Profile.CLASS_ABSTRACT
-            ) {
-                currRenderingIntent = ICC_Profile.icPerceptual;
-            }
-
-            renderingIntents[i] = currRenderingIntent;
-            // use current rendering intent
-            // to select LUT from the next profile (chaining)
-            currRenderingIntent =
-                ICC_ProfileHelper.getRenderingIntent(profiles[i]);
-        }
-
-        // Get the profile handles and go ahead
-        long[] profileHandles = new long[numProfiles];
-        for (int i=0; i<numProfiles; i++) {
-            profileHandles[i] = NativeCMM.getHandle(profiles[i]);
-        }
-
-        transformHandle = NativeCMM.cmmCreateMultiprofileTransform(
-                profileHandles,
-                renderingIntents);
-
-        src = profiles[0];
-        dst = profiles[numProfiles-1];
-        numInputChannels = src.getNumComponents();
-        numOutputChannels = dst.getNumComponents();
-    }
-
-    @Override
-    protected void finalize() {
-        if (transformHandle != 0) {
-            NativeCMM.cmmDeleteTransform(transformHandle);
-        }
-    }
-
-    /**
-     * Invokes native color conversion
-     * @param src - source image format
-     * @param dst - destination image format
-     */
-    public void translateColors(NativeImageFormat src, NativeImageFormat dst) {
-        NativeCMM.cmmTranslateColors(transformHandle, src, dst);
-    }
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/color/LUTColorConverter.java b/awt/org/apache/harmony/awt/gl/color/LUTColorConverter.java
deleted file mode 100644
index 5ea6d25..0000000
--- a/awt/org/apache/harmony/awt/gl/color/LUTColorConverter.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-/*
- * Created on 02.11.2004
- *
- */
-package org.apache.harmony.awt.gl.color;
-
-import java.awt.color.ColorSpace;
-
-public class LUTColorConverter {
-
-    private static byte from8lRGBtosRGB_LUT[];
-
-    private static byte from16lRGBtosRGB_LUT[];
-
-    private static byte fromsRGBto8lRGB_LUT[];
-
-    private static short fromsRGBto16lRGB_LUT[];
-
-    private static byte fromsRGBto8sRGB_LUTs[][];
-
-    public static ColorSpace LINEAR_RGB_CS;
-
-    public static ColorSpace LINEAR_GRAY_CS;
-
-    public static ColorSpace sRGB_CS;
-
-    public LUTColorConverter() {
-    }
-
-    /*
-     * This class prepared and returned lookup tables for conversion color 
-     * values from Linear RGB Color Space to sRGB and vice versa.
-     * Conversion is producing according to sRGB Color Space definition.
-     * "A Standard Default Color Space for the Internet - sRGB",
-     *  Michael Stokes (Hewlett-Packard), Matthew Anderson (Microsoft), 
-     * Srinivasan Chandrasekar (Microsoft), Ricardo Motta (Hewlett-Packard) 
-     * Version 1.10, November 5, 1996 
-     * This document is available: http://www.w3.org/Graphics/Color/sRGB
-     */
-    public static byte[] getFrom8lRGBtosRGB_LUT() {
-        if (from8lRGBtosRGB_LUT == null) {
-            from8lRGBtosRGB_LUT = new byte[256];
-            float v;
-            for (int i = 0; i < 256; i++) {
-                v = (float)i / 255;
-                v = (v <= 0.04045f) ? v / 12.92f :
-                    (float) Math.pow((v + 0.055) / 1.055, 2.4);
-                from8lRGBtosRGB_LUT[i] = (byte) Math.round(v * 255.0f);
-            }
-        }
-        return from8lRGBtosRGB_LUT;
-    }
-
-    public static byte[] getFrom16lRGBtosRGB_LUT() {
-        if (from16lRGBtosRGB_LUT == null) {
-            from16lRGBtosRGB_LUT = new byte[65536];
-            float v;
-            for (int i = 0; i < 65536; i++) {
-                v = (float) i / 65535;
-                v = (v <= 0.04045f) ? v / 12.92f :
-                    (float) Math.pow((v + 0.055) / 1.055, 2.4);
-                from16lRGBtosRGB_LUT[i] = (byte) Math.round(v * 255.0f);
-            }
-        }
-        return from16lRGBtosRGB_LUT;
-    }
-
-    public static byte[] getFromsRGBto8lRGB_LUT() {
-        if (fromsRGBto8lRGB_LUT == null) {
-            fromsRGBto8lRGB_LUT = new byte[256];
-            float v;
-            for (int i = 0; i < 256; i++) {
-                v = (float) i / 255;
-                v = (v <= 0.0031308f) ? v * 12.92f :
-                    ((float) Math.pow(v, 1.0 / 2.4)) * 1.055f - 0.055f;
-                fromsRGBto8lRGB_LUT[i] = (byte) Math.round(v * 255.0f);
-            }
-        }
-        return fromsRGBto8lRGB_LUT;
-    }
-
-    public static short[] getFromsRGBto16lRGB_LUT() {
-        if (fromsRGBto16lRGB_LUT == null) {
-            fromsRGBto16lRGB_LUT = new short[256];
-            float v;
-            for (int i = 0; i < 256; i++) {
-                v = (float) i / 255;
-                v = (v <= 0.0031308f) ? v * 12.92f :
-                    ((float) Math.pow(v, 1.0 / 2.4)) * 1.055f - 0.055f;
-                fromsRGBto16lRGB_LUT[i] = (short) Math.round(v * 65535.0f);
-            }
-        }
-        return fromsRGBto16lRGB_LUT;
-    }
-
-    public static byte[] getsRGBLUT(int bits) {
-        if (bits < 1) return null;
-        int idx = bits -1;
-        if(fromsRGBto8sRGB_LUTs == null) fromsRGBto8sRGB_LUTs = new byte[16][];
-
-        if(fromsRGBto8sRGB_LUTs[idx] == null){
-            fromsRGBto8sRGB_LUTs[idx] = createLUT(bits);
-        }
-        return fromsRGBto8sRGB_LUTs[idx];
-    }
-
-    private static byte[] createLUT(int bits) {
-        int lutSize = (1 << bits);
-        byte lut[] = new byte[lutSize];
-        for (int i = 0; i < lutSize; i++) {
-            lut[i] = (byte) (255.0f / (lutSize - 1) + 0.5f);
-        }
-        return lut;
-    }
-
-    public static boolean is_LINEAR_RGB_CS(ColorSpace cs) {
-        return (cs == LINEAR_RGB_CS);
-    }
-
-    public static boolean is_LINEAR_GRAY_CS(ColorSpace cs) {
-        return (cs == LINEAR_GRAY_CS);
-    }
-
-    public static boolean is_sRGB_CS(ColorSpace cs) {
-        return (cs == sRGB_CS);
-    }
-
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/color/NativeCMM.java b/awt/org/apache/harmony/awt/gl/color/NativeCMM.java
deleted file mode 100644
index 7f8c7e6..0000000
--- a/awt/org/apache/harmony/awt/gl/color/NativeCMM.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.color;
-
-import java.awt.color.ICC_Profile;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.HashMap;
-
-/**
- * This class is a wrapper for the native CMM library
- */
-public class NativeCMM {
-
-    /**
-     * Storage for profile handles, since they are private
-     * in ICC_Profile, but we need access to them.
-     */
-    private static HashMap<ICC_Profile, Long> profileHandles = new HashMap<ICC_Profile, Long>();
-
-    private static boolean isCMMLoaded;
-
-    public static void addHandle(ICC_Profile key, long handle) {
-        profileHandles.put(key, new Long(handle));
-    }
-
-    public static void removeHandle(ICC_Profile key) {
-        profileHandles.remove(key);
-    }
-
-    public static long getHandle(ICC_Profile key) {
-        return profileHandles.get(key).longValue();
-    }
-
-    /* ICC profile management */
-    public static native long cmmOpenProfile(byte[] data);
-    public static native void cmmCloseProfile(long profileID);
-    public static native int cmmGetProfileSize(long profileID);
-    public static native void cmmGetProfile(long profileID, byte[] data);
-    public static native int cmmGetProfileElementSize(long profileID, int signature);
-    public static native void cmmGetProfileElement(long profileID, int signature,
-                                           byte[] data);
-    public static native void cmmSetProfileElement(long profileID, int tagSignature,
-                                           byte[] data);
-
-
-    /* ICC transforms */
-    public static native long cmmCreateMultiprofileTransform(
-            long[] profileHandles,
-            int[] renderingIntents
-        );
-    public static native void cmmDeleteTransform(long transformHandle);
-    public static native void cmmTranslateColors(long transformHandle,
-            NativeImageFormat src,
-            NativeImageFormat dest);
-
-    static void loadCMM() {
-        if (!isCMMLoaded) {
-            AccessController.doPrivileged(
-                  new PrivilegedAction<Void>() {
-                    public Void run() {
-                        System.loadLibrary("lcmm"); //$NON-NLS-1$
-                        return null;
-                    }
-            } );
-            isCMMLoaded = true;
-        }
-    }
-
-    /* load native CMM library */
-    static {
-        loadCMM();
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/color/NativeImageFormat.java b/awt/org/apache/harmony/awt/gl/color/NativeImageFormat.java
deleted file mode 100644
index 9594047..0000000
--- a/awt/org/apache/harmony/awt/gl/color/NativeImageFormat.java
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.color;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentSampleModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-import java.awt.image.SampleModel;
-import java.awt.image.SinglePixelPackedSampleModel;
-import java.util.ArrayList;
-
-import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-
-/**
- * This class converts java color/sample models to the LCMS pixel formats.
- * It also encapsulates all the information about the image format, which native CMM
- * needs to have in order to read/write data.
- *
- * At present planar formats (multiple bands) are not supported
- * and they are handled as a common (custom) case.
- * Samples other than 1 - 7 bytes and multiple of 8 bits are
- * also handled as custom (and won't be supported in the nearest future).
- */
-class NativeImageFormat {
-    //////////////////////////////////////////////
-    //  LCMS Pixel types
-    private static final int PT_ANY = 0;    // Don't check colorspace
-    // 1 & 2 are reserved
-    private static final int PT_GRAY     = 3;
-    private static final int PT_RGB      = 4;
-    // Skipping other since we don't use them here
-    ///////////////////////////////////////////////
-
-    // Conversion of predefined BufferedImage formats to LCMS formats
-    private static final int INT_RGB_LCMS_FMT =
-        colorspaceSh(PT_RGB)|
-        extraSh(1)|
-        channelsSh(3)|
-        bytesSh(1)|
-        doswapSh(1)|
-        swapfirstSh(1);
-
-    private static final int INT_ARGB_LCMS_FMT = INT_RGB_LCMS_FMT;
-
-    private static final int INT_BGR_LCMS_FMT =
-        colorspaceSh(PT_RGB)|
-        extraSh(1)|
-        channelsSh(3)|
-        bytesSh(1);
-
-    private static final int THREE_BYTE_BGR_LCMS_FMT =
-        colorspaceSh(PT_RGB)|
-        channelsSh(3)|
-        bytesSh(1)|
-        doswapSh(1);
-
-    private static final int FOUR_BYTE_ABGR_LCMS_FMT =
-        colorspaceSh(PT_RGB)|
-        extraSh(1)|
-        channelsSh(3)|
-        bytesSh(1)|
-        doswapSh(1);
-
-    private static final int BYTE_GRAY_LCMS_FMT =
-        colorspaceSh(PT_GRAY)|
-        channelsSh(1)|
-        bytesSh(1);
-
-    private static final int USHORT_GRAY_LCMS_FMT =
-        colorspaceSh(PT_GRAY)|
-        channelsSh(1)|
-        bytesSh(2);
-
-    // LCMS format packed into 32 bit value. For description
-    // of this format refer to LCMS documentation.
-    private int cmmFormat = 0;
-
-    // Dimensions
-    private int rows = 0;
-    private int cols = 0;
-
-    //  Scanline may contain some padding in the end
-    private int scanlineStride = -1;
-
-    private Object imageData;
-    // It's possible to have offset from the beginning of the array
-    private int dataOffset;
-
-    // Has the image alpha channel? If has - here its band band offset goes
-    private int alphaOffset = -1;
-
-    // initializes proper field IDs
-    private static native void initIDs();
-
-    static {
-        NativeCMM.loadCMM();
-        initIDs();
-    }
-
-    ////////////////////////////////////
-    // LCMS image format encoders
-    ////////////////////////////////////
-    private static int colorspaceSh(int s) {
-        return (s << 16);
-    }
-
-    private static int swapfirstSh(int s) {
-        return (s << 14);
-    }
-
-    private static int flavorSh(int s) {
-        return (s << 13);
-    }
-
-    private static int planarSh(int s) {
-        return (s << 12);
-    }
-
-    private static int endianSh(int s) {
-        return (s << 11);
-    }
-
-    private static int doswapSh(int s) {
-        return (s << 10);
-    }
-
-    private static int extraSh(int s) {
-        return (s << 7);
-    }
-
-    private static int channelsSh(int s) {
-        return (s << 3);
-    }
-
-    private static int bytesSh(int s) {
-        return s;
-    }
-    ////////////////////////////////////
-    // End of LCMS image format encoders
-    ////////////////////////////////////
-
-    // Accessors
-    Object getChannelData() {
-        return imageData;
-    }
-
-    int getNumCols() {
-        return cols;
-    }
-
-    int getNumRows() {
-        return rows;
-    }
-
-    // Constructors
-    public NativeImageFormat() {
-    }
-
-    /**
-     * Simple image layout for common case with
-     * not optimized workflow.
-     *
-     * For hifi colorspaces with 5+ color channels imgData
-     * should be <code>byte</code> array.
-     *
-     * For common colorspaces with up to 4 color channels it
-     * should be <code>short</code> array.
-     *
-     * Alpha channel is handled by caller, not by CMS.
-     *
-     * Color channels are in their natural order (not BGR but RGB).
-     *
-     * @param imgData - array of <code>byte</code> or <code>short</code>
-     * @param nChannels - number of channels
-     * @param nRows - number of scanlines in the image
-     * @param nCols - number of pixels in one row of the image
-     */
-    public NativeImageFormat(Object imgData, int nChannels, int nRows, int nCols) {
-        if (imgData instanceof short[]) {
-            cmmFormat |= bytesSh(2);
-        }
-        else if (imgData instanceof byte[]) {
-            cmmFormat |= bytesSh(1);
-        }
-        else
-            // awt.47=First argument should be byte or short array
-            throw new IllegalArgumentException(Messages.getString("awt.47")); //$NON-NLS-1$
-
-        cmmFormat |= channelsSh(nChannels);
-
-        rows = nRows;
-        cols = nCols;
-
-        imageData = imgData;
-
-        dataOffset = 0;
-    }
-
-    /**
-     * Deduces image format from the buffered image type
-     * or color and sample models.
-     * @param bi - image
-     * @return image format object
-     */
-    public static NativeImageFormat createNativeImageFormat(BufferedImage bi) {
-        NativeImageFormat fmt = new NativeImageFormat();
-
-        switch (bi.getType()) {
-            case BufferedImage.TYPE_INT_RGB: {
-                fmt.cmmFormat = INT_RGB_LCMS_FMT;
-                break;
-            }
-
-            case BufferedImage.TYPE_INT_ARGB:
-            case BufferedImage.TYPE_INT_ARGB_PRE: {
-                fmt.cmmFormat = INT_ARGB_LCMS_FMT;
-                fmt.alphaOffset = 3;
-                break;
-            }
-
-            case BufferedImage.TYPE_INT_BGR: {
-                fmt.cmmFormat = INT_BGR_LCMS_FMT;
-                break;
-            }
-
-            case BufferedImage.TYPE_3BYTE_BGR: {
-                fmt.cmmFormat = THREE_BYTE_BGR_LCMS_FMT;
-                break;
-            }
-
-            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
-            case BufferedImage.TYPE_4BYTE_ABGR: {
-                fmt.cmmFormat = FOUR_BYTE_ABGR_LCMS_FMT;
-                fmt.alphaOffset = 0;
-                break;
-            }
-
-            case BufferedImage.TYPE_BYTE_GRAY: {
-                fmt.cmmFormat = BYTE_GRAY_LCMS_FMT;
-                break;
-            }
-
-            case BufferedImage.TYPE_USHORT_GRAY: {
-                fmt.cmmFormat = USHORT_GRAY_LCMS_FMT;
-                break;
-            }
-
-            case BufferedImage.TYPE_BYTE_BINARY:
-            case BufferedImage.TYPE_USHORT_565_RGB:
-            case BufferedImage.TYPE_USHORT_555_RGB:
-            case BufferedImage.TYPE_BYTE_INDEXED: {
-                // A bunch of unsupported formats
-                return null;
-            }
-
-            default:
-                break; // Try to look at sample model and color model
-        }
-
-
-        if (fmt.cmmFormat == 0) {
-            ColorModel cm = bi.getColorModel();
-            SampleModel sm = bi.getSampleModel();
-
-            if (sm instanceof ComponentSampleModel) {
-                ComponentSampleModel csm = (ComponentSampleModel) sm;
-                fmt.cmmFormat = getFormatFromComponentModel(csm, cm.hasAlpha());
-                fmt.scanlineStride = calculateScanlineStrideCSM(csm, bi.getRaster());
-            } else if (sm instanceof SinglePixelPackedSampleModel) {
-                SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
-                fmt.cmmFormat = getFormatFromSPPSampleModel(sppsm, cm.hasAlpha());
-                fmt.scanlineStride = calculateScanlineStrideSPPSM(sppsm, bi.getRaster());
-            }
-
-            if (cm.hasAlpha())
-                fmt.alphaOffset = calculateAlphaOffset(sm, bi.getRaster());
-        }
-
-        if (fmt.cmmFormat == 0)
-            return null;
-
-        if (!fmt.setImageData(bi.getRaster().getDataBuffer())) {
-            return null;
-        }
-
-        fmt.rows = bi.getHeight();
-        fmt.cols = bi.getWidth();
-
-        fmt.dataOffset = bi.getRaster().getDataBuffer().getOffset();
-
-        return fmt;
-    }
-
-    /**
-     * Deduces image format from the raster sample model.
-     * @param r - raster
-     * @return image format object
-     */
-    public static NativeImageFormat createNativeImageFormat(Raster r) {
-        NativeImageFormat fmt = new NativeImageFormat();
-        SampleModel sm = r.getSampleModel();
-
-        // Assume that there's no alpha
-        if (sm instanceof ComponentSampleModel) {
-            ComponentSampleModel csm = (ComponentSampleModel) sm;
-            fmt.cmmFormat = getFormatFromComponentModel(csm, false);
-            fmt.scanlineStride = calculateScanlineStrideCSM(csm, r);
-        } else if (sm instanceof SinglePixelPackedSampleModel) {
-            SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
-            fmt.cmmFormat = getFormatFromSPPSampleModel(sppsm, false);
-            fmt.scanlineStride = calculateScanlineStrideSPPSM(sppsm, r);
-        }
-
-        if (fmt.cmmFormat == 0)
-            return null;
-
-        fmt.cols = r.getWidth();
-        fmt.rows = r.getHeight();
-        fmt.dataOffset = r.getDataBuffer().getOffset();
-
-        if (!fmt.setImageData(r.getDataBuffer()))
-            return null;
-
-        return fmt;
-    }
-
-    /**
-     * Obtains LCMS format from the component sample model
-     * @param sm - sample model
-     * @param hasAlpha - true if there's an alpha channel
-     * @return LCMS format
-     */
-    private static int getFormatFromComponentModel(ComponentSampleModel sm, boolean hasAlpha) {
-        // Multiple data arrays (banks) not supported
-        int bankIndex = sm.getBankIndices()[0];
-        for (int i=1; i < sm.getNumBands(); i++) {
-            if (sm.getBankIndices()[i] != bankIndex) {
-                return 0;
-            }
-        }
-
-        int channels = hasAlpha ? sm.getNumBands()-1 : sm.getNumBands();
-        int extra = hasAlpha ? 1 : 0;
-        int bytes = 1;
-        switch (sm.getDataType()) {
-            case DataBuffer.TYPE_BYTE:
-                bytes = 1; break;
-            case DataBuffer.TYPE_SHORT:
-            case DataBuffer.TYPE_USHORT:
-                bytes = 2; break;
-            case DataBuffer.TYPE_INT:
-                bytes = 4; break;
-            case DataBuffer.TYPE_DOUBLE:
-                bytes = 0; break;
-            default:
-                return 0; // Unsupported data type
-        }
-
-        int doSwap = 0;
-        int swapFirst = 0;
-        boolean knownFormat = false;
-
-        int i;
-
-        // "RGBA"
-        for (i=0; i < sm.getNumBands(); i++) {
-            if (sm.getBandOffsets()[i] != i) break;
-        }
-        if (i == sm.getNumBands()) { // Ok, it is it
-            doSwap = 0;
-            swapFirst = 0;
-            knownFormat = true;
-        }
-
-        // "ARGB"
-        if (!knownFormat) {
-            for (i=0; i < sm.getNumBands()-1; i++) {
-                if (sm.getBandOffsets()[i] != i+1) break;
-            }
-            if (sm.getBandOffsets()[i] == 0) i++;
-            if (i == sm.getNumBands()) { // Ok, it is it
-                doSwap = 0;
-                swapFirst = 1;
-                knownFormat = true;
-            }
-        }
-
-        // "BGRA"
-        if (!knownFormat) {
-            for (i=0; i < sm.getNumBands()-1; i++) {
-                if (sm.getBandOffsets()[i] != sm.getNumBands() - 2 - i) break;
-            }
-            if (sm.getBandOffsets()[i] == sm.getNumBands()-1) i++;
-            if (i == sm.getNumBands()) { // Ok, it is it
-                doSwap = 1;
-                swapFirst = 1;
-                knownFormat = true;
-            }
-        }
-
-        // "ABGR"
-        if (!knownFormat) {
-            for (i=0; i < sm.getNumBands(); i++) {
-                if (sm.getBandOffsets()[i] != sm.getNumBands() - 1 - i) break;
-            }
-            if (i == sm.getNumBands()) { // Ok, it is it
-                doSwap = 1;
-                swapFirst = 0;
-                knownFormat = true;
-            }
-        }
-
-        // XXX - Planar formats are not supported yet
-        if (!knownFormat)
-            return 0;
-
-        return
-            channelsSh(channels) |
-            bytesSh(bytes) |
-            extraSh(extra) |
-            doswapSh(doSwap) |
-            swapfirstSh(swapFirst);
-    }
-
-    /**
-     * Obtains LCMS format from the single pixel packed sample model
-     * @param sm - sample model
-     * @param hasAlpha - true if there's an alpha channel
-     * @return LCMS format
-     */
-    private static int getFormatFromSPPSampleModel(SinglePixelPackedSampleModel sm,
-            boolean hasAlpha) {
-        // Can we extract bytes?
-        int mask = sm.getBitMasks()[0] >>> sm.getBitOffsets()[0];
-        if (!(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF))
-            return 0;
-
-        // All masks are same?
-        for (int i = 1; i < sm.getNumBands(); i++) {
-            if ((sm.getBitMasks()[i] >>> sm.getBitOffsets()[i]) != mask)
-                return 0;
-        }
-
-        int pixelSize = 0;
-        // Check if data type is supported
-        if (sm.getDataType() == DataBuffer.TYPE_USHORT)
-            pixelSize = 2;
-        else if (sm.getDataType() == DataBuffer.TYPE_INT)
-            pixelSize = 4;
-        else
-            return 0;
-
-
-        int bytes = 0;
-        switch (mask) {
-            case 0xFF:
-                bytes = 1;
-                break;
-            case 0xFFFF:
-                bytes = 2;
-                break;
-            case 0xFFFFFFFF:
-                bytes = 4;
-                break;
-            default: return 0;
-        }
-
-
-        int channels = hasAlpha ? sm.getNumBands()-1 : sm.getNumBands();
-        int extra = hasAlpha ? 1 : 0;
-        extra +=  pixelSize/bytes - sm.getNumBands(); // Unused bytes?
-
-        // Form an ArrayList containing offset for each band
-        ArrayList<Integer> offsetsLst = new ArrayList<Integer>();
-        for (int k=0; k < sm.getNumBands(); k++) {
-            offsetsLst.add(new Integer(sm.getBitOffsets()[k]/(bytes*8)));
-        }
-
-        // Add offsets for unused space
-        for (int i=0; i<pixelSize/bytes; i++) {
-            if (offsetsLst.indexOf(new Integer(i)) < 0)
-                offsetsLst.add(new Integer(i));
-        }
-
-        int offsets[] = new int[pixelSize/bytes];
-        for (int i=0; i<offsetsLst.size(); i++) {
-            offsets[i] = offsetsLst.get(i).intValue();
-        }
-
-        int doSwap = 0;
-        int swapFirst = 0;
-        boolean knownFormat = false;
-
-        int i;
-
-        // "RGBA"
-        for (i=0; i < pixelSize; i++) {
-            if (offsets[i] != i) break;
-        }
-        if (i == pixelSize) { // Ok, it is it
-            doSwap = 0;
-            swapFirst = 0;
-            knownFormat = true;
-        }
-
-        // "ARGB"
-        if (!knownFormat) {
-            for (i=0; i < pixelSize-1; i++) {
-                if (offsets[i] != i+1) break;
-            }
-            if (offsets[i] == 0) i++;
-            if (i == pixelSize) { // Ok, it is it
-                doSwap = 0;
-                swapFirst = 1;
-                knownFormat = true;
-            }
-        }
-
-        // "BGRA"
-        if (!knownFormat) {
-            for (i=0; i < pixelSize-1; i++) {
-                if (offsets[i] != pixelSize - 2 - i) break;
-            }
-            if (offsets[i] == pixelSize-1) i++;
-            if (i == pixelSize) { // Ok, it is it
-                doSwap = 1;
-                swapFirst = 1;
-                knownFormat = true;
-            }
-        }
-
-        // "ABGR"
-        if (!knownFormat) {
-            for (i=0; i < pixelSize; i++) {
-                if (offsets[i] != pixelSize - 1 - i) break;
-            }
-            if (i == pixelSize) { // Ok, it is it
-                doSwap = 1;
-                swapFirst = 0;
-                knownFormat = true;
-            }
-        }
-
-        // XXX - Planar formats are not supported yet
-        if (!knownFormat)
-            return 0;
-
-        return
-            channelsSh(channels) |
-            bytesSh(bytes) |
-            extraSh(extra) |
-            doswapSh(doSwap) |
-            swapfirstSh(swapFirst);
-    }
-
-    /**
-     * Obtains data array from the DataBuffer object
-     * @param db - data buffer
-     * @return - true if successful
-     */
-    private boolean setImageData(DataBuffer db) {
-        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
-        try {
-            imageData = dbAccess.getData(db);
-        } catch (IllegalArgumentException e) {
-            return false; // Unknown data buffer type
-        }
-
-        return true;
-    }
-
-    /**
-     * Calculates scanline stride in bytes
-     * @param csm - component sample model
-     * @param r - raster
-     * @return scanline stride in bytes
-     */
-    private static int calculateScanlineStrideCSM(ComponentSampleModel csm, Raster r) {
-        if (csm.getScanlineStride() != csm.getPixelStride()*csm.getWidth()) {
-            int dataTypeSize = DataBuffer.getDataTypeSize(r.getDataBuffer().getDataType()) / 8;
-            return csm.getScanlineStride()*dataTypeSize;
-        }
-        return -1;
-    }
-
-    /**
-     * Calculates scanline stride in bytes
-     * @param sppsm - sample model
-     * @param r - raster
-     * @return scanline stride in bytes
-     */
-    private static int calculateScanlineStrideSPPSM(SinglePixelPackedSampleModel sppsm, Raster r) {
-        if (sppsm.getScanlineStride() != sppsm.getWidth()) {
-            int dataTypeSize = DataBuffer.getDataTypeSize(r.getDataBuffer().getDataType()) / 8;
-            return sppsm.getScanlineStride()*dataTypeSize;
-        }
-        return -1;
-    }
-
-    /**
-     * Calculates byte offset of the alpha channel from the beginning of the pixel data
-     * @param sm - sample model
-     * @param r - raster
-     * @return byte offset of the alpha channel
-     */
-    private static int calculateAlphaOffset(SampleModel sm, Raster r) {
-        if (sm instanceof ComponentSampleModel) {
-            ComponentSampleModel csm = (ComponentSampleModel) sm;
-            int dataTypeSize =
-                DataBuffer.getDataTypeSize(r.getDataBuffer().getDataType()) / 8;
-            return
-                csm.getBandOffsets()[csm.getBandOffsets().length - 1] * dataTypeSize;
-        } else if (sm instanceof SinglePixelPackedSampleModel) {
-            SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
-            return sppsm.getBitOffsets()[sppsm.getBitOffsets().length - 1] / 8;
-        } else {
-            return -1; // No offset, don't copy alpha
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidFont.java b/awt/org/apache/harmony/awt/gl/font/AndroidFont.java
deleted file mode 100644
index e8ad1bb..0000000
--- a/awt/org/apache/harmony/awt/gl/font/AndroidFont.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.Font;
-import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
-import java.awt.font.LineMetrics;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.io.File;
-import java.util.Hashtable;
-import java.util.Locale;
-
-import org.apache.harmony.awt.gl.font.FontManager;
-import org.apache.harmony.awt.gl.font.FontPeerImpl;
-import org.apache.harmony.awt.gl.font.Glyph;
-import org.apache.harmony.awt.gl.font.LineMetricsImpl;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * Linux platform font peer implementation based on Xft and FreeType libraries.
- */
-public class AndroidFont extends FontPeerImpl {
-
-    // Pairs of [begin, end],[..].. unicode ranges values 
-    private int[] fontUnicodeRanges;
-    
-    // table with loaded cached Glyphs
-    private Hashtable glyphs = new Hashtable();
-    
-    // X11 display value
-    private long display = 0;
-
-    // X11 screen value
-    private int screen = 0;
-    
-    public AndroidFont(String fontName, int fontStyle, int fontSize) {
-        /*
-         * Workaround : to initialize awt platform-dependent fields and libraries.
-         */
-        Toolkit.getDefaultToolkit();
-        this.name = fontName;
-        this.size = fontSize;
-        this.style = fontStyle;
-       
-        initAndroidFont();
-    }
-
-    /**
-     * Initializes some native dependent font information, e.g. number of glyphs, 
-     * font metrics, italic angle etc. 
-     */
-    public void initAndroidFont(){
-        this.nlm = new AndroidLineMetrics(this, null, " "); //$NON-NLS-1$
-        this.ascent = nlm.getLogicalAscent();
-        this.descent = nlm.getLogicalDescent();
-        this.height = nlm.getHeight();
-        this.leading = nlm.getLogicalLeading();
-        this.maxAdvance = nlm.getLogicalMaxCharWidth();
-
-        if (this.fontType == FontManager.FONT_TYPE_T1){
-            this.defaultChar = 1;
-        } else {
-            this.defaultChar = 0;
-        }
-
-        this.maxCharBounds = new Rectangle2D.Float(0, -nlm.getAscent(), nlm.getMaxCharWidth(), this.height);
-    }
-
-
-    public boolean canDisplay(char chr) {
-        // TODO: to improve performance there is a sence to implement get
-        // unicode ranges to check if char can be displayed without
-        // native calls in isGlyphExists() method
-
-        return isGlyphExists(chr);
-    }
-
-    public LineMetrics getLineMetrics(String str, FontRenderContext frc, AffineTransform at) {
-
-        // Initialize baseline offsets
-        nlm.getBaselineOffsets();
-        
-        LineMetricsImpl lm = (LineMetricsImpl)(this.nlm.clone());
-        lm.setNumChars(str.length());
-
-        if ((at != null) && (!at.isIdentity())){
-            lm.scale((float)at.getScaleX(), (float)at.getScaleY());
-        }
-
-        return lm;
-    }
-
-    public String getPSName() {
-        return psName;
-    }
-
-    public String getFamily(Locale l) {
-        // TODO: implement localized family
-        if (fontType == FontManager.FONT_TYPE_TT){
-            return this.getFamily();
-        }
-
-        return this.fontFamilyName;
-    }
-
-    public String getFontName(Locale l) {
-        if ((pFont == 0) || (this.fontType == FontManager.FONT_TYPE_T1)){
-            return this.name;
-        }
-
-        return this.getFontName();
-    }
-
-
-    public int getMissingGlyphCode() {
-        return getDefaultGlyph().getGlyphCode();
-    }
-
-    public Glyph getGlyph(char index) {
-        Glyph result = null;
-
-        Object key = new Integer(index);
-        if (glyphs.containsKey(key)) {
-            result = (Glyph) glyphs.get(key);
-        } else {
-            if (this.addGlyph(index)) {
-                result = (Glyph) glyphs.get(key);
-            } else {
-                result = this.getDefaultGlyph();
-            }
-        }
-
-        return result;
-    }
-
-    public Glyph getDefaultGlyph() {
-    	throw new RuntimeException("DefaultGlyphs not implemented!");
-    }
-
-    /**
-     * Disposes native font handle. If this font peer was created from InputStream 
-     * temporary created font resource file is deleted.
-     */
-    public void dispose(){
-        String tempDirName;
-        if (pFont != 0){
-            pFont = 0;
-
-            if (isCreatedFromStream()) {
-                File fontFile = new File(getTempFontFileName());
-                tempDirName = fontFile.getParent();
-                fontFile.delete();
-            }
-        }
-    }
-
-    /**
-     * Add glyph to cached Glyph objects in this LinuxFont object.
-     * 
-     * @param uChar the specified character
-     * @return true if glyph of the specified character exists in this
-     * LinuxFont or this character is escape sequence character.
-     */
-    public boolean addGlyph(char uChar) {
-    	throw new RuntimeException("Not implemented!");    	
-    }
-
-   /**
-    * Adds range of existing glyphs to this LinuxFont object
-    * 
-    * @param uFirst the lowest range's bound, inclusive 
-    * @param uLast the highest range's bound, exclusive
-    */
-    public void addGlyphs(char uFirst, char uLast) {
-    	
-        char index = uFirst;
-        if (uLast < uFirst) {
-            // awt.09=min range bound value is grater than max range bound
-            throw new IllegalArgumentException(Messages.getString("awt.09")); //$NON-NLS-1$
-        }
-        while (index < uLast) {
-            addGlyph(index);
-            index++;
-        }
-        
-    }
-
-    /**
-     * Returns true if specified character has corresopnding glyph, false otherwise.  
-     * 
-     * @param uIndex specified char
-     */
-    public boolean isGlyphExists(char uIndex) {
-    	throw new RuntimeException("DefaultGlyphs not implemented!");
-    }
-
-    /**
-     *  Returns an array of unicode ranges that are supported by this LinuxFont. 
-     */
-    public int[] getUnicodeRanges() {
-        int[] ranges = new int[fontUnicodeRanges.length];
-        System.arraycopy(fontUnicodeRanges, 0, ranges, 0,
-                fontUnicodeRanges.length);
-
-        return ranges;
-    }
-
-    /**
-     * Return Font object if it was successfully embedded in System
-     */
-    public static Font embedFont(String absolutePath){
-    	throw new RuntimeException("embedFont not implemented!");
-    }
-
-    public String getFontName(){
-        if ((pFont != 0) && (faceName == null)){
-            if (this.fontType == FontManager.FONT_TYPE_T1){
-                faceName = getFamily();
-            }
-        }
-        return faceName;
-    }
-
-    public String getFamily() {
-        return fontFamilyName;
-    }
-    
-    /**
-     * Returns initiated FontExtraMetrics instance of this WindowsFont.
-     */
-    public FontExtraMetrics getExtraMetrics(){
-    	throw new RuntimeException("Not implemented!");
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidFontManager.java b/awt/org/apache/harmony/awt/gl/font/AndroidFontManager.java
deleted file mode 100644
index 063a256..0000000
--- a/awt/org/apache/harmony/awt/gl/font/AndroidFontManager.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.Font;
-import java.awt.peer.FontPeer;
-import java.io.File;
-import java.io.IOException;
-import java.util.Properties;
-import java.util.Vector;
-
-import org.apache.harmony.awt.gl.font.FontManager;
-import org.apache.harmony.awt.gl.font.FontProperty;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-import android.util.Log;
-
-public class AndroidFontManager extends FontManager {
-
-    // set of all available faces supported by a system
-    String faces[];
-
-    // weight names according to xlfd structure
-    public static final String[] LINUX_WEIGHT_NAMES = {
-            "black", "bold", "demibold", "medium", "light" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-    };
-
-    // slant names according to xlfd structure
-    public static final String[] LINUX_SLANT_NAMES = {
-            "i", "o", "r" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    };
-
-    /** Singleton AndroidFontManager instance */
-    public static final AndroidFontManager inst = new AndroidFontManager();
-
-    private AndroidFontManager() {
-        super();
-        faces = new String[] {/*"PLAIN",*/ "NORMAL", "BOLD", "ITALIC", "BOLDITALIC"};
-        initFontProperties();
-    }
-
-    public void initLCIDTable(){
-    	throw new RuntimeException("Not implemented!");
-    }
-
-    /**
-     * Returns temporary File object to store data from InputStream.
-     * This File object saved to `~/.fonts/' folder that is included in the 
-     * list of folders searched for font files, and this is where user-specific 
-     * font files should be installed.
-     */
-    public File getTempFontFile()throws IOException{
-        File fontFile = File.createTempFile("jFont", ".ttf", new File(System.getProperty("user.home") +"/.fonts")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-        fontFile.deleteOnExit();
-
-        return fontFile;
-    }
-
-    /**
-     * Initializes fProperties array field for the current system configuration font
-     * property file.
-     * 
-     * RuntimeException is thrown if font property contains incorrect format of 
-     * xlfd string.
-     * 
-     * @return true is success, false if font property doesn't exist or doesn't
-     * contain roperties. 
-     */
-    public boolean initFontProperties(){
-        File fpFile = getFontPropertyFile();
-        if (fpFile == null){
-            return false;
-        }
-
-        Properties props = getProperties(fpFile);
-        if (props == null){
-            return false;
-        }
-
-        for (int i=0; i < LOGICAL_FONT_NAMES.length; i++){
-            String lName = LOGICAL_FONT_NAMES[i];
-            for (int j=0; j < STYLE_NAMES.length; j++){
-                String styleName = STYLE_NAMES[j];
-                Vector propsVector = new Vector();
-
-                // Number of entries for a logical font
-                int numComp = 0;
-                // Is more entries for this style and logical font name left
-                boolean moreEntries = true;
-                String value = null;
-
-                while(moreEntries){
-                    // Component Font Mappings property name
-                    String property = FONT_MAPPING_KEYS[0].replaceAll("LogicalFontName", lName).replaceAll("StyleName", styleName).replaceAll("ComponentIndex", String.valueOf(numComp)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-                    value = props.getProperty(property);
-
-                    // If the StyleName is omitted, it's assumed to be plain
-                    if ((j == 0) && (value == null)){
-                        property = FONT_MAPPING_KEYS[1].replaceAll("LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp)); //$NON-NLS-1$ //$NON-NLS-2$
-                        value = props.getProperty(property);
-                    }
-
-                    if (value != null){
-                        String[] fields = parseXLFD(value);
-
-                        if (fields == null){
-                            // awt.08=xfld parse string error: {0}
-                            throw new RuntimeException(Messages.getString("awt.08", value)); //$NON-NLS-1$
-                        }
-                        
-                        String fontName = fields[1];
-                        String weight = fields[2];
-                        String italic = fields[3];
-
-                        int style = getBoldStyle(weight) | getItalicStyle(italic);
-                        // Component Font Character Encodings property value
-                        String encoding = props.getProperty(FONT_CHARACTER_ENCODING.replaceAll("LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp))); //$NON-NLS-1$ //$NON-NLS-2$
-
-                        // Exclusion Ranges property value
-                        String exclString = props.getProperty(EXCLUSION_RANGES.replaceAll("LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp))); //$NON-NLS-1$ //$NON-NLS-2$
-                        int[] exclRange = parseIntervals(exclString);
-
-                        FontProperty fp = new AndroidFontProperty(lName, styleName, null, fontName, value, style, exclRange, encoding);
-
-                        propsVector.add(fp);
-                        numComp++;
-                    } else {
-                        moreEntries = false;
-                    }
-                }
-                fProperties.put(LOGICAL_FONT_NAMES[i] + "." + j, propsVector); //$NON-NLS-1$
-            }
-        }
-
-        return true;
-
-    }
-
-    /**
-     * Returns style according to the xlfd weight string.
-     * If weight string is incorrect returned value is Font.PLAIN
-     * 
-     * @param str weight name String
-     */
-    private int getBoldStyle(String str){
-        for (int i = 0; i < LINUX_WEIGHT_NAMES.length;i++){
-            if (str.equalsIgnoreCase(LINUX_WEIGHT_NAMES[i])){
-                return (i < 3) ? Font.BOLD : Font.PLAIN;
-            }
-        }
-        return Font.PLAIN;
-    }
-    
-    /**
-     * Returns style according to the xlfd slant string.
-     * If slant string is incorrect returned value is Font.PLAIN
-     * 
-     * @param str slant name String
-     */
-    private int getItalicStyle(String str){
-        for (int i = 0; i < LINUX_SLANT_NAMES.length;i++){
-            if (str.equalsIgnoreCase(LINUX_SLANT_NAMES[i])){
-                return (i < 2) ? Font.ITALIC : Font.PLAIN;
-            }
-        }
-        return Font.PLAIN;
-    }
-
-    /**
-     * Parse xlfd string and returns array of Strings with separate xlfd 
-     * elements.<p>
-     * 
-     * xlfd format:
-     *      -Foundry-Family-Weight-Slant-Width-Style-PixelSize-PointSize-ResX-ResY-Spacing-AvgWidth-Registry-Encoding
-     * @param xlfd String parameter in xlfd format
-     */
-    public static String[] parseXLFD(String xlfd){
-        int fieldsCount = 14;
-        String fieldsDelim = "-"; //$NON-NLS-1$
-        String[] res = new String[fieldsCount];
-        if (!xlfd.startsWith(fieldsDelim)){
-            return null;
-        }
-
-        xlfd = xlfd.substring(1);
-        int i=0;
-        int pos;
-        for (i=0; i < fieldsCount-1; i++){
-            pos = xlfd.indexOf(fieldsDelim);
-            if (pos != -1){
-                res[i] = xlfd.substring(0, pos);
-                xlfd = xlfd.substring(pos + 1);
-            } else {
-                return null;
-            }
-        }
-        pos = xlfd.indexOf(fieldsDelim);
-
-        // check if no fields left
-        if(pos != -1){
-            return null;
-        }
-        res[fieldsCount-1] = xlfd;
-
-        return res;
-    }
-
-    public int getFaceIndex(String faceName){
-    	
-        for (int i = 0; i < faces.length; i++) {
-            if(faces[i].equals(faceName)){
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    public String[] getAllFamilies(){
-        if (allFamilies == null){
-        	allFamilies = new String[]{"sans-serif", "serif", "monospace"};
-        }
-        return allFamilies;
-    }
-
-    public Font[] getAllFonts(){
-        Font[] fonts = new Font[faces.length];
-        for (int i =0; i < fonts.length;i++){
-            fonts[i] = new Font(faces[i], Font.PLAIN, 1);
-        }
-        return fonts;
-    }
-
-    public FontPeer createPhysicalFontPeer(String name, int style, int size) {
-        AndroidFont peer;
-        int familyIndex = getFamilyIndex(name);
-        if (familyIndex != -1){
-            // !! we use family names from the list with cached families because 
-            // they are differ from the family names in xlfd structure, in xlfd 
-            // family names mostly in lower case.
-            peer = new AndroidFont(getFamily(familyIndex), style, size);
-            peer.setFamily(getFamily(familyIndex));
-            return peer;
-        }
-        int faceIndex = getFaceIndex(name); 
-        if (faceIndex != -1){
-
-            peer = new AndroidFont(name, style, size);
-            return peer;
-        }
-        
-        return null;
-    }
-
-    public FontPeer createDefaultFont(int style, int size) {
-    	Log.i("DEFAULT FONT", Integer.toString(style));
-        return new AndroidFont(DEFAULT_NAME, style, size);
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidFontProperty.java b/awt/org/apache/harmony/awt/gl/font/AndroidFontProperty.java
deleted file mode 100644
index 0cfdc43..0000000
--- a/awt/org/apache/harmony/awt/gl/font/AndroidFontProperty.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- *
- */
-package org.apache.harmony.awt.gl.font;
-
-/**
- * Android FontProperty implementation, applicable for Linux formats of 
- * font property files. 
- */
-public class AndroidFontProperty extends FontProperty {
-    
-    /** xlfd string that is applicable for Linux font.properties */ 
-    String xlfd;
-
-    /** logical name of the font corresponding to this FontProperty */ 
-    String logicalName;
-    
-    /** style name of the font corresponding to this FontProperty */
-    String styleName;
-
-    public AndroidFontProperty(String _logicalName, String _styleName, String _fileName, String _name, String _xlfd, int _style, int[] exclusionRange, String _encoding){
-        this.logicalName = _logicalName;
-        this.styleName = _styleName;
-        this.name = _name;
-        this.encoding = _encoding;
-        this.exclRange = exclusionRange;
-        this.fileName = _fileName;
-        this.xlfd = _xlfd;
-        this.style = _style;
-    }
-    
-    /**
-     * Returns logical name of the font corresponding to this FontProperty. 
-     */
-    public String getLogicalName(){
-        return logicalName;
-    }
-    
-    /**
-     * Returns style name of the font corresponding to this FontProperty. 
-     */
-    public String getStyleName(){
-        return styleName;
-    }
-    
-    /**
-     * Returns xlfd string of this FontProperty. 
-     */
-    public String getXLFD(){
-        return xlfd;
-    }
-
-    public String toString(){
-        return new String(this.getClass().getName() +
-                "[name=" + name + //$NON-NLS-1$
-                ",fileName="+ fileName + //$NON-NLS-1$
-                ",Charset=" + encoding + //$NON-NLS-1$
-                ",exclRange=" + exclRange + //$NON-NLS-1$
-                ",xlfd=" + xlfd + "]"); //$NON-NLS-1$ //$NON-NLS-2$
-
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidGlyphVector.java b/awt/org/apache/harmony/awt/gl/font/AndroidGlyphVector.java
deleted file mode 100644
index f3b2e28..0000000
--- a/awt/org/apache/harmony/awt/gl/font/AndroidGlyphVector.java
+++ /dev/null
@@ -1,235 +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 org.apache.harmony.awt.gl.font;
-
-import com.android.internal.awt.AndroidGraphics2D;
-
-import java.awt.Font;
-import java.awt.Shape;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphJustificationInfo;
-import java.awt.font.GlyphMetrics;
-import java.awt.font.GlyphVector;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-
-import android.util.Log;
-import android.graphics.Path;
-
-public class AndroidGlyphVector extends GlyphVector {
-
-    // array of chars defined in constructor
-    public char[] charVector;
-
-    // array of Glyph objects, that describe information about glyphs
-    public Glyph[] vector;
-
-    // array of default positions of glyphs in GlyphVector
-    // without applying GlyphVector's transform
-    float[] defaultPositions;
-
-    // array of logical positions of glyphs in GlyphVector
-
-    float[] logicalPositions;
-
-    // array of visual (real) positions of glyphs in GlyphVector
-    public float[] visualPositions;
-
-    // FontRenderContext for this vector.
-    protected FontRenderContext vectorFRC;
-
-    // layout flags mask
-    protected int layoutFlags = 0;
-
-    // array of cached glyph outlines 
-    protected Shape[] gvShapes;
-
-    FontPeerImpl peer;
-
-    // font corresponding to the GlyphVector 
-    Font font;
-
-    // ascent of the font
-    float ascent;
-
-    // height of the font
-    float height;
-    
-    // leading of the font
-    float leading;
-    
-    // descent of the font
-    float descent;
-
-    // transform of the GlyphVector
-    AffineTransform transform;
-
-    @SuppressWarnings("deprecation")
-    public AndroidGlyphVector(char[] chars, FontRenderContext frc, Font fnt,
-            int flags) {
-        int len = chars.length;
-        this.font = fnt;
-        LineMetricsImpl lmImpl = (LineMetricsImpl)fnt.getLineMetrics(String.valueOf(chars), frc);     	
-        this.ascent = lmImpl.getAscent();
-        this.height = lmImpl.getHeight();
-        this.leading = lmImpl.getLeading();
-        this.descent = lmImpl.getDescent();
-        this.charVector = chars;
-        this.vectorFRC = frc;
-    }
-
-    public AndroidGlyphVector(char[] chars, FontRenderContext frc, Font fnt) {
-        this(chars, frc, fnt, 0);
-    }
-
-    public AndroidGlyphVector(String str, FontRenderContext frc, Font fnt) {
-        this(str.toCharArray(), frc, fnt, 0);
-    }
-
-    public AndroidGlyphVector(String str, FontRenderContext frc, Font fnt, int flags) {
-        this(str.toCharArray(), frc, fnt, flags);
-    }
-
-	@Override
-	public boolean equals(GlyphVector glyphVector) {
-		return false;
-	}
-
-	public char[] getGlyphs() {
-		return this.charVector;
-	}
-	
-	@Override
-	public Font getFont() {
-		return this.font;
-	}
-
-	@Override
-	public FontRenderContext getFontRenderContext() {
-		return this.vectorFRC;
-	}
-
-	@Override
-	public int getGlyphCode(int glyphIndex) {
-		return charVector[glyphIndex];
-	}
-
-	@Override
-	public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
-			int[] codeReturn) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public Shape getGlyphLogicalBounds(int glyphIndex) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public GlyphMetrics getGlyphMetrics(int glyphIndex) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	public Path getAndroidGlyphOutline(int glyphIndex) {
-		AndroidGraphics2D g = AndroidGraphics2D.getInstance();
-        Path path = new Path();
-        char tmp[] = new char[1];
-        tmp[0] = charVector[glyphIndex];
-        ((AndroidGraphics2D)g).getAndroidPaint().getTextPath(new String(tmp), 0, 1, 0, 0, path);
-        return path;
-	}
-	
-	@Override
-	public Shape getGlyphOutline(int glyphIndex) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public Point2D getGlyphPosition(int glyphIndex) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
-			float[] positionReturn) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public AffineTransform getGlyphTransform(int glyphIndex) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public Shape getGlyphVisualBounds(int glyphIndex) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public Rectangle2D getLogicalBounds() {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public int getNumGlyphs() {
-		return charVector.length;
-	}
-
-	@Override
-	public Shape getOutline(float x, float y) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public Shape getOutline() {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	public Path getAndroidOutline() {
-		AndroidGraphics2D g = AndroidGraphics2D.getInstance();
-        Path path = new Path();
-        ((AndroidGraphics2D)g).getAndroidPaint().getTextPath(new String(charVector), 0, charVector.length, 0, 0, path);
-        return path;
-	}
-
-	@Override
-	public Rectangle2D getVisualBounds() {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public void performDefaultLayout() {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public void setGlyphPosition(int glyphIndex, Point2D newPos) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-	@Override
-	public void setGlyphTransform(int glyphIndex, AffineTransform trans) {
-		throw new RuntimeException("Not implemented!");
-	}
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidLineMetrics.java b/awt/org/apache/harmony/awt/gl/font/AndroidLineMetrics.java
deleted file mode 100644
index f37be6d..0000000
--- a/awt/org/apache/harmony/awt/gl/font/AndroidLineMetrics.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.font.FontRenderContext;
-import org.apache.harmony.awt.gl.font.LineMetricsImpl;
-
-
-/**
- *
- * Linux implementation of LineMetrics class
- */
-public class AndroidLineMetrics extends LineMetricsImpl {
-    
-    /**
-     * Constructor
-     */
-    public AndroidLineMetrics(    AndroidFont fnt,
-                                FontRenderContext frc,
-                                String str){
-        numChars = str.length();
-        baseLineIndex = 0;
-
-        ascent = fnt.ascent;    // Ascent of the font
-        descent = -fnt.descent;  // Descent of the font
-        leading = fnt.leading;  // External leading
-
-        height = ascent + descent + leading;    // Height of the font ( == (ascent + descent + leading))
-        underlineThickness = 0.0f;
-        underlineOffset = 0.0f;
-        strikethroughThickness = 0.0f;
-        strikethroughOffset = 0.0f;
-        maxCharWidth = 0.0f;
-
-        //    TODO: Find out pixel metrics
-        /*
-         * positive metrics rounded to the smallest int that is bigger than value
-         * negative metrics rounded to the smallest int that is lesser than value
-         * thicknesses rounded to int ((int)round(value + 0.5))
-         *
-         */
-
-        lAscent = (int)Math.ceil(fnt.ascent);//   // Ascent of the font
-        lDescent = -(int)Math.ceil(fnt.descent);// Descent of the font
-        lLeading = (int)Math.ceil(leading);  // External leading
-
-        lHeight = lAscent + lDescent + lLeading;    // Height of the font ( == (ascent + descent + leading))
-
-        lUnderlineThickness = Math.round(underlineThickness);//(int)metrics[11];
-
-        if (underlineOffset >= 0){
-            lUnderlineOffset = (int)Math.ceil(underlineOffset);
-        } else {
-            lUnderlineOffset = (int)Math.floor(underlineOffset);
-        }
-
-        lStrikethroughThickness = Math.round(strikethroughThickness); //(int)metrics[13];
-
-        if (strikethroughOffset >= 0){
-            lStrikethroughOffset = (int)Math.ceil(strikethroughOffset);
-        } else {
-            lStrikethroughOffset = (int)Math.floor(strikethroughOffset);
-        }
-
-        lMaxCharWidth = (int)Math.ceil(maxCharWidth); //(int)metrics[15];
-        units_per_EM = 0;
-
-    }
-
-    public float[] getBaselineOffsets() {
-        // TODO: implement baseline offsets for TrueType fonts
-        if (baselineOffsets == null){
-            float[] baselineData = null;
-
-            // Temporary workaround:
-            // Commented out native data initialization, since it can 
-            // cause failures with opening files in multithreaded applications.
-            //
-            // TODO: support work with truetype data in multithreaded
-            // applications.
-
-            // If font TrueType data is taken from BASE table
-//            if ((this.font.getFontHandle() != 0) && (font.getFontType() == FontManager.FONT_TYPE_TT)){
-//                baselineData = LinuxNativeFont.getBaselineOffsetsNative(font.getFontHandle(), font.getSize(), ascent, descent, units_per_EM);
-//            }
-//
-                baseLineIndex = 0;
-                baselineOffsets = new float[]{0, (-ascent+descent)/2, -ascent};
-        }
-
-        return baselineOffsets;
-    }
-
-    public int getBaselineIndex() {
-        if (baselineOffsets == null){
-            // get offsets and set correct index
-            getBaselineOffsets();
-        }
-        return baseLineIndex;
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/BasicMetrics.java b/awt/org/apache/harmony/awt/gl/font/BasicMetrics.java
deleted file mode 100644
index c0fb390..0000000
--- a/awt/org/apache/harmony/awt/gl/font/BasicMetrics.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- */
-
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.font.LineMetrics;
-import java.awt.font.GraphicAttribute;
-import java.awt.*;
-
-/**
- * Date: May 14, 2005
- * Time: 7:44:13 PM
- *
- * This class incapsulates text metrics specific for the text layout or
- * for the separate text segment. Text segment is a text run with the constant direction
- * and attributes like font, decorations, etc. BasicMetrics is also used to store
- * calculated text metrics like advance, ascent or descent. this class is very similar to
- * LineMetrics, but provides some additional info, constructors and is more transparent.
- */
-public class BasicMetrics {
-    int baseLineIndex;
-
-    float ascent;   // Ascent of the font
-    float descent;  // Descent of the font
-    float leading;  // External leading
-    float advance;
-
-    float italicAngle;
-    float superScriptOffset;
-
-    float underlineOffset;
-    float underlineThickness;
-
-    float strikethroughOffset;
-    float strikethroughThickness;
-
-    /**
-     * Constructs BasicMetrics from LineMetrics and font
-     * @param lm
-     * @param font
-     */
-    BasicMetrics(LineMetrics lm, Font font) {
-        ascent = lm.getAscent();
-        descent = lm.getDescent();
-        leading = lm.getLeading();
-
-        underlineOffset = lm.getUnderlineOffset();
-        underlineThickness = lm.getUnderlineThickness();
-
-        strikethroughOffset = lm.getStrikethroughOffset();
-        strikethroughThickness = lm.getStrikethroughThickness();
-
-        baseLineIndex = lm.getBaselineIndex();
-
-        italicAngle = font.getItalicAngle();
-        superScriptOffset = (float) font.getTransform().getTranslateY();
-    }
-
-    /**
-     * Constructs BasicMetrics from GraphicAttribute.
-     * It gets ascent and descent from the graphic attribute and
-     * computes reasonable defaults for other metrics.
-     * @param ga - graphic attribute
-     */
-    BasicMetrics(GraphicAttribute ga) {
-        ascent = ga.getAscent();
-        descent = ga.getDescent();
-        leading = 2;
-
-        baseLineIndex = ga.getAlignment();
-
-        italicAngle = 0;
-        superScriptOffset = 0;
-
-        underlineOffset = Math.max(descent/2, 1);
-
-        // Just suggested, should be cap_stem_width or something like that
-        underlineThickness = Math.max(ascent/13, 1);
-
-        strikethroughOffset = -ascent/2; // Something like middle of the line
-        strikethroughThickness = underlineThickness;
-    }
-
-    /**
-     * Copies metrics from the TextMetricsCalculator object.
-     * @param tmc - TextMetricsCalculator object
-     */
-    BasicMetrics(TextMetricsCalculator tmc) {
-        ascent = tmc.ascent;
-        descent = tmc.descent;
-        leading = tmc.leading;
-        advance = tmc.advance;
-        baseLineIndex = tmc.baselineIndex;
-    }
-
-    public float getAscent() {
-        return ascent;
-    }
-
-    public float getDescent() {
-        return descent;
-    }
-
-    public float getLeading() {
-        return leading;
-    }
-
-    public float getAdvance() {
-        return advance;
-    }
-
-    public int getBaseLineIndex() {
-        return baseLineIndex;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/CaretManager.java b/awt/org/apache/harmony/awt/gl/font/CaretManager.java
deleted file mode 100644
index b18bdd5..0000000
--- a/awt/org/apache/harmony/awt/gl/font/CaretManager.java
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Jun 14, 2005
- */
-
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.font.TextHitInfo;
-import java.awt.font.TextLayout;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Line2D;
-import java.awt.*;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * This class provides functionality for creating caret and highlight shapes
- * (bidirectional text is also supported, but, unfortunately, not tested yet).
- */
-public class CaretManager {
-    private TextRunBreaker breaker;
-
-    public CaretManager(TextRunBreaker breaker) {
-        this.breaker = breaker;
-    }
-
-    /**
-     * Checks if TextHitInfo is not out of the text range and throws the
-     * IllegalArgumentException if it is.
-     * @param info - text hit info
-     */
-    private void checkHit(TextHitInfo info) {
-        int idx = info.getInsertionIndex();
-
-        if (idx < 0 || idx > breaker.getCharCount()) {
-            // awt.42=TextHitInfo out of range
-            throw new IllegalArgumentException(Messages.getString("awt.42")); //$NON-NLS-1$
-        }
-    }
-
-    /**
-     * Calculates and returns visual position from the text hit info.
-     * @param hitInfo - text hit info
-     * @return visual index
-     */
-    private int getVisualFromHitInfo(TextHitInfo hitInfo) {
-        final int idx = hitInfo.getCharIndex();
-
-        if (idx >= 0 && idx < breaker.getCharCount()) {
-            int visual = breaker.getVisualFromLogical(idx);
-            // We take next character for (LTR char + TRAILING info) and (RTL + LEADING)
-            if (hitInfo.isLeadingEdge() ^ ((breaker.getLevel(idx) & 0x1) == 0x0)) {
-                visual++;
-            }
-            return visual;
-        } else if (idx < 0) {
-            return breaker.isLTR() ? 0: breaker.getCharCount();
-        } else {
-            return breaker.isLTR() ? breaker.getCharCount() : 0;
-        }
-    }
-
-    /**
-     * Calculates text hit info from the visual position
-     * @param visual - visual position
-     * @return text hit info
-     */
-    private TextHitInfo getHitInfoFromVisual(int visual) {
-        final boolean first = visual == 0;
-
-        if (!(first || visual == breaker.getCharCount())) {
-            int logical = breaker.getLogicalFromVisual(visual);
-            return (breaker.getLevel(logical) & 0x1) == 0x0 ?
-                    TextHitInfo.leading(logical) : // LTR
-                    TextHitInfo.trailing(logical); // RTL
-        } else if (first) {
-            return breaker.isLTR() ?
-                    TextHitInfo.trailing(-1) :
-                    TextHitInfo.leading(breaker.getCharCount());
-        } else { // Last
-            return breaker.isLTR() ?
-                    TextHitInfo.leading(breaker.getCharCount()) :
-                    TextHitInfo.trailing(-1);
-        }
-    }
-
-    /**
-     * Creates caret info. Required for the getCaretInfo
-     * methods of the TextLayout
-     * @param hitInfo - specifies caret position
-     * @return caret info, see TextLayout.getCaretInfo documentation
-     */
-    public float[] getCaretInfo(TextHitInfo hitInfo) {
-        checkHit(hitInfo);
-        float res[] = new float[2];
-
-        int visual = getVisualFromHitInfo(hitInfo);
-        float advance, angle;
-        TextRunSegment seg;
-
-        if (visual < breaker.getCharCount()) {
-            int logIdx = breaker.getLogicalFromVisual(visual);
-            int segmentIdx = breaker.logical2segment[logIdx];
-            seg = breaker.runSegments.get(segmentIdx);
-            advance = seg.x + seg.getAdvanceDelta(seg.getStart(), logIdx);
-            angle = seg.metrics.italicAngle;
-
-        } else { // Last character
-            int logIdx = breaker.getLogicalFromVisual(visual-1);
-            int segmentIdx = breaker.logical2segment[logIdx];
-            seg = breaker.runSegments.get(segmentIdx);
-            advance = seg.x + seg.getAdvanceDelta(seg.getStart(), logIdx+1);
-        }
-
-        angle = seg.metrics.italicAngle;
-
-        res[0] = advance;
-        res[1] = angle;
-
-        return res;
-    }
-
-    /**
-     * Returns the next position to the right from the current caret position
-     * @param hitInfo - current position
-     * @return next position to the right
-     */
-    public TextHitInfo getNextRightHit(TextHitInfo hitInfo) {
-        checkHit(hitInfo);
-        int visual = getVisualFromHitInfo(hitInfo);
-
-        if (visual == breaker.getCharCount()) {
-            return null;
-        }
-
-        TextHitInfo newInfo;
-
-        while(visual <= breaker.getCharCount()) {
-            visual++;
-            newInfo = getHitInfoFromVisual(visual);
-
-            if (newInfo.getCharIndex() >= breaker.logical2segment.length) {
-                return newInfo;
-            }
-
-            if (hitInfo.getCharIndex() >= 0) { // Don't check for leftmost info
-                if (
-                        breaker.logical2segment[newInfo.getCharIndex()] !=
-                        breaker.logical2segment[hitInfo.getCharIndex()]
-                ) {
-                    return newInfo; // We crossed segment boundary
-                }
-            }
-
-            TextRunSegment seg = breaker.runSegments.get(breaker.logical2segment[newInfo
-                    .getCharIndex()]);
-            if (!seg.charHasZeroAdvance(newInfo.getCharIndex())) {
-                return newInfo;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the next position to the left from the current caret position
-     * @param hitInfo - current position
-     * @return next position to the left
-     */
-    public TextHitInfo getNextLeftHit(TextHitInfo hitInfo) {
-        checkHit(hitInfo);
-        int visual = getVisualFromHitInfo(hitInfo);
-
-        if (visual == 0) {
-            return null;
-        }
-
-        TextHitInfo newInfo;
-
-        while(visual >= 0) {
-            visual--;
-            newInfo = getHitInfoFromVisual(visual);
-
-            if (newInfo.getCharIndex() < 0) {
-                return newInfo;
-            }
-
-            // Don't check for rightmost info
-            if (hitInfo.getCharIndex() < breaker.logical2segment.length) {
-                if (
-                        breaker.logical2segment[newInfo.getCharIndex()] !=
-                        breaker.logical2segment[hitInfo.getCharIndex()]
-                ) {
-                    return newInfo; // We crossed segment boundary
-                }
-            }
-
-            TextRunSegment seg = breaker.runSegments.get(breaker.logical2segment[newInfo
-                    .getCharIndex()]);
-            if (!seg.charHasZeroAdvance(newInfo.getCharIndex())) {
-                return newInfo;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * For each visual caret position there are two hits. For the simple LTR text one is
-     * a trailing of the previous char and another is the leading of the next char. This
-     * method returns the opposite hit for the given hit.
-     * @param hitInfo - given hit
-     * @return opposite hit
-     */
-    public TextHitInfo getVisualOtherHit(TextHitInfo hitInfo) {
-        checkHit(hitInfo);
-
-        int idx = hitInfo.getCharIndex();
-
-        int resIdx;
-        boolean resIsLeading;
-
-        if (idx >= 0 && idx < breaker.getCharCount()) { // Hit info in the middle
-            int visual = breaker.getVisualFromLogical(idx);
-
-            // Char is LTR + LEADING info
-            if (((breaker.getLevel(idx) & 0x1) == 0x0) ^ hitInfo.isLeadingEdge()) {
-                visual++;
-                if (visual == breaker.getCharCount()) {
-                    if (breaker.isLTR()) {
-                        resIdx = breaker.getCharCount();
-                        resIsLeading = true;
-                    } else {
-                        resIdx = -1;
-                        resIsLeading = false;
-                    }
-                } else {
-                    resIdx = breaker.getLogicalFromVisual(visual);
-                    if ((breaker.getLevel(resIdx) & 0x1) == 0x0) {
-                        resIsLeading = true;
-                    } else {
-                        resIsLeading = false;
-                    }
-                }
-            } else {
-                visual--;
-                if (visual == -1) {
-                    if (breaker.isLTR()) {
-                        resIdx = -1;
-                        resIsLeading = false;
-                    } else {
-                        resIdx = breaker.getCharCount();
-                        resIsLeading = true;
-                    }
-                } else {
-                    resIdx = breaker.getLogicalFromVisual(visual);
-                    if ((breaker.getLevel(resIdx) & 0x1) == 0x0) {
-                        resIsLeading = false;
-                    } else {
-                        resIsLeading = true;
-                    }
-                }
-            }
-        } else if (idx < 0) { // before "start"
-            if (breaker.isLTR()) {
-                resIdx = breaker.getLogicalFromVisual(0);
-                resIsLeading = (breaker.getLevel(resIdx) & 0x1) == 0x0; // LTR char?
-            } else {
-                resIdx = breaker.getLogicalFromVisual(breaker.getCharCount() - 1);
-                resIsLeading = (breaker.getLevel(resIdx) & 0x1) != 0x0; // RTL char?
-            }
-        } else { // idx == breaker.getCharCount()
-            if (breaker.isLTR()) {
-                resIdx = breaker.getLogicalFromVisual(breaker.getCharCount() - 1);
-                resIsLeading = (breaker.getLevel(resIdx) & 0x1) != 0x0; // LTR char?
-            } else {
-                resIdx = breaker.getLogicalFromVisual(0);
-                resIsLeading = (breaker.getLevel(resIdx) & 0x1) == 0x0; // RTL char?
-            }
-        }
-
-        return resIsLeading ? TextHitInfo.leading(resIdx) : TextHitInfo.trailing(resIdx);
-    }
-
-    public Line2D getCaretShape(TextHitInfo hitInfo, TextLayout layout) {
-        return getCaretShape(hitInfo, layout, true, false, null);
-    }
-
-    /**
-     * Creates a caret shape.
-     * @param hitInfo - hit where to place a caret
-     * @param layout - text layout
-     * @param useItalic - unused for now, was used to create
-     * slanted carets for italic text
-     * @param useBounds - true if the cared should fit into the provided bounds
-     * @param bounds - bounds for the caret
-     * @return caret shape
-     */
-    public Line2D getCaretShape(
-            TextHitInfo hitInfo, TextLayout layout,
-            boolean useItalic, boolean useBounds, Rectangle2D bounds
-    ) {
-        checkHit(hitInfo);
-
-        float x1, x2, y1, y2;
-
-        int charIdx = hitInfo.getCharIndex();
-
-        if (charIdx >= 0 && charIdx < breaker.getCharCount()) {
-            TextRunSegment segment = breaker.runSegments.get(breaker.logical2segment[charIdx]);
-            y1 = segment.metrics.descent;
-            y2 = - segment.metrics.ascent - segment.metrics.leading;
-
-            x1 = x2 = segment.getCharPosition(charIdx) + (hitInfo.isLeadingEdge() ?
-                    0 : segment.getCharAdvance(charIdx));
-            // Decided that straight cursor looks better even for italic fonts,
-            // especially combined with highlighting
-            /*
-            // Not graphics, need to check italic angle and baseline
-            if (layout.getBaseline() >= 0) {
-                if (segment.metrics.italicAngle != 0 && useItalic) {
-                    x1 -= segment.metrics.italicAngle * segment.metrics.descent;
-                    x2 += segment.metrics.italicAngle *
-                        (segment.metrics.ascent + segment.metrics.leading);
-
-                    float baselineOffset =
-                        layout.getBaselineOffsets()[layout.getBaseline()];
-                    y1 += baselineOffset;
-                    y2 += baselineOffset;
-                }
-            }
-            */
-        } else {
-            y1 = layout.getDescent();
-            y2 = - layout.getAscent() - layout.getLeading();
-            x1 = x2 = ((breaker.getBaseLevel() & 0x1) == 0 ^ charIdx < 0) ?
-                    layout.getAdvance() : 0;
-        }
-
-        if (useBounds) {
-            y1 = (float) bounds.getMaxY();
-            y2 = (float) bounds.getMinY();
-
-            if (x2 > bounds.getMaxX()) {
-                x1 = x2 = (float) bounds.getMaxX();
-            }
-            if (x1 < bounds.getMinX()) {
-                x1 = x2 = (float) bounds.getMinX();
-            }
-        }
-
-        return new Line2D.Float(x1, y1, x2, y2);
-    }
-
-    /**
-     * Creates caret shapes for the specified offset. On the boundaries where
-     * the text is changing its direction this method may return two shapes
-     * for the strong and the weak carets, in other cases it would return one.
-     * @param offset - offset in the text.
-     * @param bounds - bounds to fit the carets into
-     * @param policy - caret policy
-     * @param layout - text layout
-     * @return one or two caret shapes
-     */
-    public Shape[] getCaretShapes(
-            int offset, Rectangle2D bounds,
-            TextLayout.CaretPolicy policy, TextLayout layout
-    ) {
-        TextHitInfo hit1 = TextHitInfo.afterOffset(offset);
-        TextHitInfo hit2 = getVisualOtherHit(hit1);
-
-        Shape caret1 = getCaretShape(hit1, layout);
-
-        if (getVisualFromHitInfo(hit1) == getVisualFromHitInfo(hit2)) {
-            return new Shape[] {caret1, null};
-        }
-        Shape caret2 = getCaretShape(hit2, layout);
-
-        TextHitInfo strongHit = policy.getStrongCaret(hit1, hit2, layout);
-        return strongHit.equals(hit1) ?
-                new Shape[] {caret1, caret2} :
-                new Shape[] {caret2, caret1};
-    }
-
-    /**
-     * Connects two carets to produce a highlight shape.
-     * @param caret1 - 1st caret
-     * @param caret2 - 2nd caret
-     * @return highlight shape
-     */
-    GeneralPath connectCarets(Line2D caret1, Line2D caret2) {
-        GeneralPath path = new GeneralPath(GeneralPath.WIND_NON_ZERO);
-        path.moveTo((float) caret1.getX1(), (float) caret1.getY1());
-        path.lineTo((float) caret2.getX1(), (float) caret2.getY1());
-        path.lineTo((float) caret2.getX2(), (float) caret2.getY2());
-        path.lineTo((float) caret1.getX2(), (float) caret1.getY2());
-
-        path.closePath();
-
-        return path;
-    }
-
-    /**
-     * Creates a highlight shape from given two hits. This shape
-     * will always be visually contiguous
-     * @param hit1 - 1st hit
-     * @param hit2 - 2nd hit
-     * @param bounds - bounds to fit the shape into
-     * @param layout - text layout
-     * @return highlight shape
-     */
-    public Shape getVisualHighlightShape(
-            TextHitInfo hit1, TextHitInfo hit2,
-            Rectangle2D bounds, TextLayout layout
-    ) {
-        checkHit(hit1);
-        checkHit(hit2);
-
-        Line2D caret1 = getCaretShape(hit1, layout, false, true, bounds);
-        Line2D caret2 = getCaretShape(hit2, layout, false, true, bounds);
-
-        return connectCarets(caret1, caret2);
-    }
-
-    /**
-     * Suppose that the user visually selected a block of text which has
-     * several different levels (mixed RTL and LTR), so, in the logical
-     * representation of the text this selection may be not contigous.
-     * This methods returns a set of logical ranges for the arbitrary
-     * visual selection represented by two hits.
-     * @param hit1 - 1st hit
-     * @param hit2 - 2nd hit
-     * @return logical ranges for the selection
-     */
-    public int[] getLogicalRangesForVisualSelection(TextHitInfo hit1, TextHitInfo hit2) {
-        checkHit(hit1);
-        checkHit(hit2);
-
-        int visual1 = getVisualFromHitInfo(hit1);
-        int visual2 = getVisualFromHitInfo(hit2);
-
-        if (visual1 > visual2) {
-            int tmp = visual2;
-            visual2 = visual1;
-            visual1 = tmp;
-        }
-
-        // Max level is 255, so we don't need more than 512 entries
-        int results[] = new int[512];
-
-        int prevLogical, logical, runStart, numRuns = 0;
-
-        logical = runStart = prevLogical = breaker.getLogicalFromVisual(visual1);
-
-        // Get all the runs. We use the fact that direction is constant in all runs.
-        for (int i=visual1+1; i<=visual2; i++) {
-            logical = breaker.getLogicalFromVisual(i);
-            int diff = logical-prevLogical;
-
-            // Start of the next run encountered
-            if (diff > 1 || diff < -1) {
-                results[(numRuns)*2] = Math.min(runStart, prevLogical);
-                results[(numRuns)*2 + 1] = Math.max(runStart, prevLogical);
-                numRuns++;
-                runStart = logical;
-            }
-
-            prevLogical = logical;
-        }
-
-        // The last unsaved run
-        results[(numRuns)*2] = Math.min(runStart, logical);
-        results[(numRuns)*2 + 1] = Math.max(runStart, logical);
-        numRuns++;
-
-        int retval[] = new int[numRuns*2];
-        System.arraycopy(results, 0, retval, 0, numRuns*2);
-        return retval;
-    }
-
-    /**
-     * Creates a highlight shape from given two endpoints in the logical
-     * representation. This shape is not always visually contiguous
-     * @param firstEndpoint - 1st logical endpoint
-     * @param secondEndpoint - 2nd logical endpoint
-     * @param bounds - bounds to fit the shape into
-     * @param layout - text layout
-     * @return highlight shape
-     */
-    public Shape getLogicalHighlightShape(
-            int firstEndpoint, int secondEndpoint,
-            Rectangle2D bounds, TextLayout layout
-    ) {
-        GeneralPath res = new GeneralPath();
-
-        for (int i=firstEndpoint; i<=secondEndpoint; i++) {
-            int endRun = breaker.getLevelRunLimit(i, secondEndpoint);
-            TextHitInfo hit1 = TextHitInfo.leading(i);
-            TextHitInfo hit2 = TextHitInfo.trailing(endRun-1);
-
-            Line2D caret1 = getCaretShape(hit1, layout, false, true, bounds);
-            Line2D caret2 = getCaretShape(hit2, layout, false, true, bounds);
-
-            res.append(connectCarets(caret1, caret2), false);
-
-            i = endRun;
-        }
-
-        return res;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/CommonGlyphVector.java b/awt/org/apache/harmony/awt/gl/font/CommonGlyphVector.java
deleted file mode 100644
index 4040a60..0000000
--- a/awt/org/apache/harmony/awt/gl/font/CommonGlyphVector.java
+++ /dev/null
@@ -1,954 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.Font;
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphJustificationInfo;
-import java.awt.font.GlyphMetrics;
-import java.awt.font.GlyphVector;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * GlyphVector implementation
- */
-public class CommonGlyphVector extends GlyphVector {
-
-    // array of transforms of glyphs in GlyphVector
-    protected AffineTransform[] glsTransforms;
-
-    // array of chars defined in constructor
-    public char[] charVector;
-
-    // array of Glyph objects, that describe information about glyphs
-    public Glyph[] vector;
-
-    // array of default positions of glyphs in GlyphVector
-    // without applying GlyphVector's transform
-    float[] defaultPositions;
-
-    // array of logical positions of glyphs in GlyphVector
-
-    float[] logicalPositions;
-
-    // array of visual (real) positions of glyphs in GlyphVector
-    public float[] visualPositions;
-
-    // FontRenderContext for this vector.
-    protected FontRenderContext vectorFRC;
-
-    // layout flags mask
-    protected int layoutFlags = 0;
-
-    // array of cached glyph outlines 
-    protected Shape[] gvShapes;
-
-    FontPeerImpl peer;
-
-    // font corresponding to the GlyphVector 
-    Font font;
-
-    // ascent of the font
-    float ascent;
-
-    // height of the font
-    float height;
-    
-    // leading of the font
-    float leading;
-    
-    // descent of the font
-    float descent;
-
-    // transform of the GlyphVector
-    AffineTransform transform;
-
-    /**
-     * Creates new CommonGlyphVector object from the specified parameters.
-     * 
-     * @param chars an array of chars
-     * @param frc FontRenderContext object
-     * @param fnt Font object
-     * @param flags layout flags
-     */
-    @SuppressWarnings("deprecation")
-    public CommonGlyphVector(char[] chars, FontRenderContext frc, Font fnt,
-            int flags) {
-        int len = chars.length;
-
-        this.font = fnt;
-        this.transform = fnt.getTransform();
-        this.peer = (FontPeerImpl) fnt.getPeer();
-
-        gvShapes = new Shape[len];
-
-        // !! As pointed in API documentation for the 
-        // getGlyphPosisitions(int index,int numEntries, float[] positionReturn) 
-        // and getGlyphPosition(int index) methods, if the index is equals to 
-        // the number of glyphs the position after the last glyph must be 
-        // returned, thus there are n+1 positions and last (n+1) position 
-        // points to the end of GlyphVector.
-
-        logicalPositions = new float[(len+1)<<1];
-        visualPositions = new float[(len+1)<<1];
-        defaultPositions = new float[(len+1)<<1];
-
-        glsTransforms = new AffineTransform[len];
-
-        this.charVector = chars;
-        this.vectorFRC = frc;
-        //LineMetricsImpl lmImpl = (LineMetricsImpl)peer.getLineMetrics();
-
-        LineMetricsImpl lmImpl = (LineMetricsImpl)fnt.getLineMetrics(String.valueOf(chars), frc);
-
-        this.ascent = lmImpl.getAscent();
-        this.height = lmImpl.getHeight();
-        this.leading = lmImpl.getLeading();
-        this.descent = lmImpl.getDescent();
-        this.layoutFlags = flags;
-
-        if ((flags & Font.LAYOUT_RIGHT_TO_LEFT) != 0){
-            char vector[] = new char[len];
-            for(int i=0; i < len; i++){
-                vector[i] = chars[len-i-1];
-            }
-            this.vector = peer.getGlyphs(vector);
-
-        } else {
-            this.vector = peer.getGlyphs(chars);
-        }
-
-        this.glsTransforms = new AffineTransform[len];
-
-        setDefaultPositions();
-        performDefaultLayout();
-    }
-
-    /**
-     * Creates new CommonGlyphVector object from the specified parameters. 
-     * Layout flags set to default.
-     * 
-     * @param chars an array of chars
-     * @param frc FontRenderContext object
-     * @param fnt Font object
-     */
-    public CommonGlyphVector(char[] chars, FontRenderContext frc, Font fnt) {
-        this(chars, frc, fnt, 0);
-    }
-
-    /**
-     * Creates new CommonGlyphVector object from the specified parameters. 
-     * Layout flags set to default.
-     * 
-     * @param str specified string
-     * @param frc FontRenderContext object
-     * @param fnt Font object
-     */
-    public CommonGlyphVector(String str, FontRenderContext frc, Font fnt) {
-        this(str.toCharArray(), frc, fnt, 0);
-    }
-
-    /**
-     * Creates new CommonGlyphVector object from the specified parameters.
-     * 
-     * @param str specified string
-     * @param frc FontRenderContext object
-     * @param fnt Font object
-     * @param flags layout flags
-     */
-    public CommonGlyphVector(String str, FontRenderContext frc, Font fnt, int flags) {
-        this(str.toCharArray(), frc, fnt, flags);
-    }
-
-    /**
-     * Set array of logical positions of the glyphs to
-     * default with their default advances and height.
-     */
-    void setDefaultPositions(){
-        int len = getNumGlyphs();
-
-        // First [x,y] is set into [0,0] position
-        // for this reason start index is 1
-        for (int i=1; i <= len; i++ ){
-                int idx = i << 1;
-                float advanceX = vector[i-1].getGlyphPointMetrics().getAdvanceX();
-                float advanceY = vector[i-1].getGlyphPointMetrics().getAdvanceY();
-
-                defaultPositions[idx] = defaultPositions[idx-2] + advanceX;
-                defaultPositions[idx+1] = defaultPositions[idx-1] + advanceY;
-
-        }
-        transform.transform(defaultPositions, 0, logicalPositions, 0, getNumGlyphs()+1);
-
-    }
-
-    /**
-     * Returnes the pixel bounds of this GlyphVector rendered at the 
-     * specified x,y location with the given FontRenderContext.
-     *  
-     * @param frc a FontRenderContext that is used
-     * @param x specified x coordinate value
-     * @param y specified y coordinate value
-     * @return a Rectangle that bounds pixels of this GlyphVector
-     */
-    @Override
-    public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
-
-        double xM, yM, xm, ym;
-
-        double minX = 0;
-        double minY = 0;
-        double maxX = 0;
-        double maxY = 0;
-
-        for (int i = 0; i < this.getNumGlyphs(); i++) {
-            Rectangle glyphBounds = this.getGlyphPixelBounds(i, frc, 0, 0);
-            xm = glyphBounds.getMinX();
-            ym = glyphBounds.getMinY();
-            xM = glyphBounds.getMaxX();
-            yM = glyphBounds.getMaxY();
-
-            if (i == 0) {
-                minX = xm;
-                minY = ym;
-                maxX = xM;
-                maxY = yM;
-            }
-
-            if (minX > xm) {
-                minX = xm;
-            }
-            if (minY > ym) {
-                minY = ym;
-            }
-            if (maxX < xM) {
-                maxX = xM;
-            }
-            if (maxY < yM) {
-                maxY = yM;
-            }
-        }
-        return new Rectangle((int)(minX + x), (int)(minY + y), (int)(maxX - minX), (int)(maxY - minY));
-
-    }
-
-    /**
-     * Returns the visual bounds of this GlyphVector.
-     * The visual bounds is the bounds of the total outline of 
-     * this GlyphVector.
-     * @return a Rectangle2D that id the visual bounds of this GlyphVector
-     */
-    @Override
-    public Rectangle2D getVisualBounds() {
-        float xM, yM, xm, ym;
-        float minX = 0;
-        float minY = 0;
-        float maxX = 0;
-        float maxY = 0;
-        boolean firstIteration = true;
-
-        for (int i = 0; i < this.getNumGlyphs(); i++) {
-            Rectangle2D bounds = this.getGlyphVisualBounds(i).getBounds2D();
-            if (bounds.getWidth() == 0){
-                continue;
-            }
-            xm = (float)bounds.getX();
-            ym = (float)bounds.getY();
-
-            xM = (float)(xm + bounds.getWidth());
-
-            yM = ym + (float) bounds.getHeight();
-
-            if (firstIteration) {
-                minX = xm;
-                minY = ym;
-                maxX = xM;
-                maxY = yM;
-                firstIteration = false;
-            } else {
-                if (minX > xm) {
-                    minX = xm;
-                }
-                if (minY > ym) {
-                    minY = ym;
-                }
-                if (maxX < xM) {
-                    maxX = xM;
-                }
-                if (maxY < yM) {
-                    maxY = yM;
-                }
-
-            }
-        }
-
-        return (this.getNumGlyphs() != 0) ? new Rectangle2D.Float(minX, minY,
-                (maxX - minX), (maxY - minY)) : null;
-    }
-
-    /**
-     * Sets new position to the specified glyph.
-     */
-    @Override
-    public void setGlyphPosition(int glyphIndex, Point2D newPos) {
-        if ((glyphIndex > vector.length) || (glyphIndex < 0)) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-        float x = (float)newPos.getX();
-        float y = (float)newPos.getY();
-        int index = glyphIndex << 1;
-
-        if ((x != visualPositions[index]) || (y != visualPositions[index + 1])){
-            visualPositions[index] = x;
-            visualPositions[index+1] = y;
-            layoutFlags = layoutFlags | FLAG_HAS_POSITION_ADJUSTMENTS;
-        }
-
-    }
-
-    /**
-     * Returns the position of the specified glyph relative to the origin of
-     * this GlyphVector
-     * @return a Point2D that the origin of the glyph with specified index
-     */
-    @Override
-    public Point2D getGlyphPosition(int glyphIndex) {
-        if ((glyphIndex > vector.length) || (glyphIndex < 0)) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-        int index = glyphIndex << 1;
-        Point2D pos = new Point2D.Float(visualPositions[index], visualPositions[index+1]);
-
-        // For last position we don't have to transform !!
-        if(glyphIndex==vector.length){
-            return pos;
-        }
-
-        AffineTransform at = getGlyphTransform(glyphIndex);
-        if ((at == null) || (at.isIdentity())){
-            return pos;
-        }
-
-        pos.setLocation(pos.getX() + at.getTranslateX(), pos.getY() + at.getTranslateY());
-
-        return pos;
-    }
-
-    /**
-     * Sets new transform to the specified glyph.
-     * 
-     * @param glyphIndex specified index of the glyph
-     * @param trans AffineTransform of the glyph with specified index
-     */
-    @Override
-    public void setGlyphTransform(int glyphIndex, AffineTransform trans) {
-        if ((glyphIndex >= vector.length) || (glyphIndex < 0)) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-
-        if ((trans == null) || (trans.isIdentity())) {
-            glsTransforms[glyphIndex] = null;
-        } else {
-            glsTransforms[glyphIndex] = new AffineTransform(trans);
-            layoutFlags = layoutFlags | FLAG_HAS_TRANSFORMS;
-        }
-    }
-
-    /**
-     * Returns the affine transform of the specified glyph.
-     * 
-     * @param glyphIndex specified index of the glyph
-     * @return an AffineTransform of the glyph with specified index
-     */
-    @Override
-    public AffineTransform getGlyphTransform(int glyphIndex) {
-        if ((glyphIndex >= this.vector.length) || (glyphIndex < 0)) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-        return this.glsTransforms[glyphIndex];
-    }
-
-    /**
-     * Returns the metrics of the specified glyph.
-     * 
-     * @param glyphIndex specified index of the glyph
-     */
-    @Override
-    public GlyphMetrics getGlyphMetrics(int glyphIndex) {
-
-        if ((glyphIndex < 0) || ((glyphIndex) >= this.getNumGlyphs())) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-        // TODO: is there a sence in GlyphMetrics
-        // if certain glyph or Font has a transform??
-        return this.vector[glyphIndex].getGlyphMetrics();
-    }
-
-    /**
-     * Returns a justification information for the glyph with specified glyph 
-     * index.
-     * @param glyphIndex index of a glyph which GlyphJustificationInfo is to be 
-     * received   
-     * @return a GlyphJustificationInfo object that contains glyph justification 
-     * properties of the specified glyph
-     */
-    @Override
-    public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex) {
-        // TODO : Find out the source of Justification info
-        if (true) {
-            throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
-        }
-        return null;
-    }
-
-    /**
-     * Returns the FontRenderContext parameter of this GlyphVector.
-     */
-    @Override
-    public FontRenderContext getFontRenderContext() {
-        return this.vectorFRC;
-    }
-
-    /**
-     * Returns the visual bounds of the specified glyph.
-     * 
-     * @param glyphIndex specified index of the glyph
-     */
-    @Override
-    public Shape getGlyphVisualBounds(int glyphIndex) {
-        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-
-        int idx  = glyphIndex << 1;
-
-        AffineTransform fontTransform = this.transform;
-        double xOffs = fontTransform.getTranslateX();
-        double yOffs = fontTransform.getTranslateY();
-
-        if (vector[glyphIndex].getWidth() == 0){
-            return new Rectangle2D.Float((float)xOffs, (float)yOffs, 0, 0);
-        }
-
-        AffineTransform at = AffineTransform.getTranslateInstance(xOffs, yOffs);
-        AffineTransform glyphTransform = getGlyphTransform(glyphIndex);
-
-        if (transform.isIdentity() && ((glyphTransform == null) || glyphTransform.isIdentity())){
-            Rectangle2D blackBox = vector[glyphIndex].getGlyphMetrics().getBounds2D();
-            at.translate(visualPositions[idx], visualPositions[idx+1]);
-            return(at.createTransformedShape(blackBox));
-        }
-
-        GeneralPath shape = (GeneralPath)this.getGlyphOutline(glyphIndex);
-        shape.transform(at);
-        return shape.getBounds2D();
-    }
-
-    /**
-     * Returnes the pixel bounds of the specified glyph within GlyphVector 
-     * rendered at the specified x,y location.
-     *  
-     * @param glyphIndex index of the glyph
-     * @param frc a FontRenderContext that is used
-     * @param x specified x coordinate value
-     * @param y specified y coordinate value
-     * @return a Rectangle that bounds pixels of the specified glyph
-     */
-    @Override
-    public Rectangle getGlyphPixelBounds(int glyphIndex, FontRenderContext frc,
-            float x, float y) {
-        // TODO : need to be implemented with FontRenderContext
-        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-
-        int idx  = glyphIndex << 1;
-
-        if (vector[glyphIndex].getWidth() == 0){
-            AffineTransform fontTransform = this.transform;
-            double xOffs = x + visualPositions[idx] + fontTransform.getTranslateX();
-            double yOffs = y + visualPositions[idx+1] + fontTransform.getTranslateY();
-            return new Rectangle((int)xOffs, (int)yOffs, 0, 0);
-        }
-
-        GeneralPath shape = (GeneralPath)this.getGlyphOutline(glyphIndex);
-
-        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
-
-        if (frc != null){
-            at.concatenate(frc.getTransform());
-        }
-
-        shape.transform(at);
-
-        Rectangle bounds = shape.getBounds();
-        return new Rectangle((int)bounds.getX(), (int)bounds.getY(),
-                            (int)bounds.getWidth()-1, (int)bounds.getHeight()-1);
-        }
-
-    /**
-     * Returns a Shape that encloses specified glyph.
-     * 
-     * @param glyphIndex specified index of the glyph
-     */
-    @Override
-    public Shape getGlyphOutline(int glyphIndex) {
-        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-
-        if (gvShapes[glyphIndex] == null) {
-            gvShapes[glyphIndex] = vector[glyphIndex].getShape();
-        }
-
-        GeneralPath gp = (GeneralPath)((GeneralPath)gvShapes[glyphIndex]).clone();
-
-        /* Applying GlyphVector font transform */
-        AffineTransform at = (AffineTransform)this.transform.clone();
-
-        /* Applying Glyph transform */
-        AffineTransform glyphAT = getGlyphTransform(glyphIndex);
-        if (glyphAT != null){
-            at.preConcatenate(glyphAT);
-        }
-
-        int idx  = glyphIndex << 1;
-
-        gp.transform(at);
-        gp.transform(AffineTransform.getTranslateInstance(visualPositions[idx], visualPositions[idx+1]));
-        return gp;
-    }
-
-
-    /**
-     * Returns a Shape that is the outline representation of this GlyphVector 
-     * rendered at the specified x,y coordinates.
-     * 
-     * @param x specified x coordinate value
-     * @param y specified y coordinate value
-     * @return a Shape object that is the outline of this GlyphVector
-     * at the specified coordinates.
-     */
-    @Override
-    public Shape getOutline(float x, float y) {
-        GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
-        for (int i = 0; i < this.vector.length; i++) {
-            GeneralPath outline = (GeneralPath)getGlyphOutline(i);
-
-            /* Applying translation to actual visual bounds */
-            outline.transform(AffineTransform.getTranslateInstance(x, y));
-            gp.append(outline, false);
-        }
-
-        return gp;
-    }
-
-    /**
-     * Returns a Shape that is the outline representation of this GlyphVector.
-     * 
-     * @return a Shape object that is the outline of this GlyphVector
-     */
-    @Override
-    public Shape getOutline() {
-        return this.getOutline(0, 0);
-    }
-
-    /**
-     * Returns an array of glyphcodes for the specified glyphs.
-     * 
-     * @param beginGlyphIndex the start index
-     * @param numEntries the number of glyph codes to get
-     * @param codeReturn the array that receives glyph codes' values
-     * @return an array that receives glyph codes' values
-     */
-    @Override
-    public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
-            int[] codeReturn) {
-
-        if ((beginGlyphIndex < 0) || ((numEntries + beginGlyphIndex) > this.getNumGlyphs())) {
-            // awt.44=beginGlyphIndex is out of vector's range
-            throw new IndexOutOfBoundsException(Messages.getString("awt.44")); //$NON-NLS-1$
-        }
-
-        if (numEntries < 0) {
-            // awt.45=numEntries is out of vector's range
-            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
-        }
-
-        if (codeReturn == null) {
-            codeReturn = new int[numEntries];
-        }
-
-        for (int i = beginGlyphIndex; i < beginGlyphIndex + numEntries; i++) {
-            codeReturn[i-beginGlyphIndex] = this.vector[i].getGlyphCode();
-        }
-
-        return codeReturn;
-    }
-
-    /**
-     * Returns an array of numEntries character indices for the specified glyphs.
-     * 
-     * @param beginGlyphIndex the start index
-     * @param numEntries the number of glyph codes to get
-     * @param codeReturn the array that receives glyph codes' values
-     * @return an array that receives glyph char indices
-     */
-    @Override
-    public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries,
-            int[] codeReturn) {
-        if ((beginGlyphIndex < 0) || (beginGlyphIndex >= this.getNumGlyphs())) {
-            // awt.44=beginGlyphIndex is out of vector's range
-            throw new IllegalArgumentException(Messages.getString("awt.44")); //$NON-NLS-1$
-        }
-
-        if ((numEntries < 0)
-                || ((numEntries + beginGlyphIndex) > this.getNumGlyphs())) {
-            // awt.45=numEntries is out of vector's range
-            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
-        }
-
-        if (codeReturn == null) {
-            codeReturn = new int[numEntries];
-        }
-
-        for (int i = 0; i < numEntries; i++) {
-            codeReturn[i] = this.getGlyphCharIndex(i + beginGlyphIndex);
-        }
-        return codeReturn;
-    }
-
-    /**
-     * Returns an array of numEntries glyphs positions from beginGlyphIndex
-     * glyph in Glyph Vector.
-     * 
-     * @param beginGlyphIndex the start index
-     * @param numEntries the number of glyph codes to get
-     * @param positionReturn the array that receives glyphs' positions
-     * @return an array of floats that receives glyph char indices
-     */
-    @Override
-    public float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
-            float[] positionReturn) {
-
-        int len = (this.getNumGlyphs()+1) << 1;
-        beginGlyphIndex *= 2;
-        numEntries *= 2;
-
-        if ((beginGlyphIndex < 0) || ((numEntries + beginGlyphIndex) > len)) {
-            // awt.44=beginGlyphIndex is out of vector's range
-            throw new IndexOutOfBoundsException(Messages.getString("awt.44")); //$NON-NLS-1$
-        }
-
-        if (numEntries < 0) {
-            // awt.45=numEntries is out of vector's range
-            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
-        }
-
-        if (positionReturn == null) {
-            positionReturn = new float[numEntries];
-        }
-
-        System.arraycopy(visualPositions, beginGlyphIndex, positionReturn, 0, numEntries);
-
-        return positionReturn;
-    }
-
-    /**
-     * Set numEntries elements of the visualPositions array from beginGlyphIndex
-     * of numEntries glyphs positions from beginGlyphIndex glyph in Glyph Vector.
-     * 
-     * @param beginGlyphIndex the start index
-     * @param numEntries the number of glyph codes to get
-     * @param setPositions the array of positions to set
-     */
-    public void setGlyphPositions(int beginGlyphIndex, int numEntries,
-            float[] setPositions) {
-
-        int len = (this.getNumGlyphs()+1) << 1;
-        beginGlyphIndex *= 2;
-        numEntries *= 2;
-
-        if ((beginGlyphIndex < 0) || ((numEntries + beginGlyphIndex) > len)) {
-            // awt.44=beginGlyphIndex is out of vector's range
-            throw new IndexOutOfBoundsException(Messages.getString("awt.44")); //$NON-NLS-1$
-        }
-
-        if (numEntries < 0) {
-            // awt.45=numEntries is out of vector's range
-            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
-        }
-
-        System.arraycopy(setPositions, 0, visualPositions, beginGlyphIndex, numEntries);
-        layoutFlags = layoutFlags & FLAG_HAS_POSITION_ADJUSTMENTS;
-
-    }
-
-    /**
-     * Set elements of the visualPositions array.
-     * 
-     * @param setPositions the array of positions to set
-     */
-    public void setGlyphPositions(float[] setPositions) {
-
-        int len = (this.getNumGlyphs()+1) << 1;
-        if (len != setPositions.length){
-            // awt.46=length of setPositions array differs from the length of positions array
-            throw new IllegalArgumentException(Messages.getString("awt.46")); //$NON-NLS-1$
-        }
-
-        System.arraycopy(setPositions, 0, visualPositions, 0, len);
-        layoutFlags = layoutFlags & FLAG_HAS_POSITION_ADJUSTMENTS;
-
-    }
-
-
-    /**
-     * Returns glyph code of the specified glyph.
-     * 
-     * @param glyphIndex specified index of the glyph
-     */
-    @Override
-    public int getGlyphCode(int glyphIndex) {
-        if (glyphIndex >= this.vector.length || glyphIndex < 0) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-        return this.vector[glyphIndex].getGlyphCode();
-    }
-
-    /**
-     * Returns character index of the specified glyph.
-     * 
-     * @param glyphIndex specified index of the glyph
-     */
-    @Override
-    public int getGlyphCharIndex(int glyphIndex) {
-
-        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IllegalArgumentException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-
-        if ((this.layoutFlags & Font.LAYOUT_RIGHT_TO_LEFT) != 0) {
-            return this.charVector.length - glyphIndex - 1;
-        }
-
-        return glyphIndex;
-    }
-
-    /**
-     * Returns a character value of the specified glyph.
-     * 
-     * @param glyphIndex specified index of the glyph
-     */
-    public char getGlyphChar(int glyphIndex) {
-
-        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IllegalArgumentException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-        return this.charVector[glyphIndex];
-    }
-
-    /**
-     * Assigns default positions to each glyph in this GlyphVector.
-     */
-    @Override
-    public void performDefaultLayout() {
-
-        System.arraycopy(logicalPositions, 0, visualPositions, 0, logicalPositions.length);
-
-        // Set position changes flag to zero
-        clearLayoutFlags(GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
-    }
-
-    /**
-     * Returns the number of glyphs in this Glyph Vector
-     */
-    @Override
-    public int getNumGlyphs() {
-        return vector.length;
-    }
-
-    /**
-     * Returns the logical bounds of this GlyphVector
-     */
-    @Override
-    public Rectangle2D getLogicalBounds(){
-        // XXX: for transforms where an angle between basis vectors is not 90 degrees
-        // Rectanlge2D class doesn't fit as Logical bounds. For this reason we use
-        // only non-transformed bounds!!
-
-        float x = visualPositions[0];
-        float width = visualPositions[visualPositions.length-2];
-
-        double scaleY =  transform.getScaleY();
-
-        Rectangle2D bounds = new Rectangle2D.Float(x, (float)((-this.ascent-this.leading)*scaleY), width, (float)(this.height*scaleY));
-        return bounds;
-    }
-
-
-    /**
-     * Checks whether given GlyphVector equals to this GlyphVector.
-     * @param glyphVector GlyphVector object to compare
-     */
-    @Override
-    public boolean equals(GlyphVector glyphVector){
-        if (glyphVector == this){
-            return true;
-        }
-
-        if (glyphVector != null) {
-
-            if (!(glyphVector.getFontRenderContext().equals(this.vectorFRC) &&
-                      glyphVector.getFont().equals(this.font))){
-                return false;
-            }
-
-            try {
-                boolean eq = true;
-                for (int i = 0; i < getNumGlyphs(); i++) {
-
-                    int idx = i*2;
-                    eq = (((CommonGlyphVector)glyphVector).visualPositions[idx] == this.visualPositions[idx]) &&
-                        (((CommonGlyphVector)glyphVector).visualPositions[idx+1] == this.visualPositions[idx+1]) &&
-                        (glyphVector.getGlyphCharIndex(i) == this.getGlyphCharIndex(i));
-
-                    if (eq){
-                        AffineTransform trans = glyphVector.getGlyphTransform(i);
-                        if (trans == null){
-                            eq = (this.glsTransforms[i] == null);
-                        }else{
-                            eq = this.glsTransforms[i].equals(trans);
-                        }
-                    }
-
-                    if (!eq){
-                        return false;
-                    }
-                }
-
-                return  eq;
-            } catch (ClassCastException e) {
-            }
-        }
-
-        return false;
-    }
-
-
-    /**
-     * Returns flags describing the state of the GlyphVector.
-     */
-    @Override
-    public int getLayoutFlags() {
-        return layoutFlags;
-    }
-
-    /**
-     * Returns char with the specified index.
-     * 
-     * @param index specified index of the char
-     * 
-     */
-    public char getChar(int index) {
-        return this.charVector[index];
-
-    }
-
-    /**
-     * Clear desired flags in layout flags describing the state. 
-     * 
-     * @param clearFlags flags mask to clear 
-     */
-    
-    private void clearLayoutFlags(int clearFlags){
-        layoutFlags &= ~clearFlags;
-    }
-
-    /**
-     * Returns the logical bounds of the specified glyph within this CommonGlyphVector.
-     * 
-     * @param glyphIndex index of the glyph to get it's logical bounds
-     * @return logical bounds of the specified glyph
-     */
-    @Override
-    public Shape getGlyphLogicalBounds(int glyphIndex){
-        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())){
-            // awt.43=glyphIndex is out of vector's limits
-            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
-        }
-        Glyph glyph = this.vector[glyphIndex];
-
-        float x0 = visualPositions[glyphIndex*2];
-        float y0 = visualPositions[glyphIndex*2+1];
-        float advanceX = glyph.getGlyphPointMetrics().getAdvanceX();
-
-        GeneralPath gp = new GeneralPath();
-        gp.moveTo(0, -ascent - leading);
-        gp.lineTo(advanceX ,-ascent - leading);
-        gp.lineTo(advanceX, descent);
-        gp.lineTo(0, descent);
-        gp.lineTo(0, -ascent - leading);
-        gp.closePath();
-
-        /* Applying GlyphVector font transform */
-        AffineTransform at = (AffineTransform)this.transform.clone();
-
-        /* Applying Glyph transform */
-        AffineTransform glyphTransform = getGlyphTransform(glyphIndex);
-        if (glyphTransform != null){
-            at.concatenate(glyphTransform);
-        }
-
-        /* Applying translation to actual visual bounds */
-        at.preConcatenate(AffineTransform.getTranslateInstance(x0, y0));
-        gp.transform(at);
-        return gp;
-    }
-
-    /**
-     * Returns the Font parameter of this GlyphVector
-     */
-    @Override
-    public Font getFont(){
-        return this.font;
-    }
-
-
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/font/CompositeFont.java b/awt/org/apache/harmony/awt/gl/font/CompositeFont.java
deleted file mode 100644
index 70cb334..0000000
--- a/awt/org/apache/harmony/awt/gl/font/CompositeFont.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.font.FontRenderContext;
-import java.awt.font.LineMetrics;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.harmony.awt.gl.font.FontPeerImpl;
-import org.apache.harmony.awt.gl.font.FontProperty;
-
-/**
- * CompositeFont class is the implementation of logical font classes. 
- * Every logical font consists of several physical fonts that described 
- * in font.properties file according to the face name of this logical font.
- */
-public class CompositeFont extends FontPeerImpl{
-    
-    // a number of physical fonts that CompositeFont consist of 
-    int numFonts;
-
-    // font family name
-    String family;
-
-    // font face name
-    String face;
-
-    String[] fontNames;
-    
-    // an array of font properties applicable to this CompositeFont
-    FontProperty[] fontProperties;
-    
-    // an array of font peers applicable to this CompositeFont
-    public FontPeerImpl[] fPhysicalFonts;
-    
-    // missing glyph code field
-    int missingGlyphCode = -1;
-    
-    // line metrics of this font
-    LineMetricsImpl nlm = null;
-    
-    // cached num glyphs parameter of this font that is the sum of num glyphs of 
-    // font peers composing this font
-    int cachedNumGlyphs = -1;
-    /**
-     * Creates CompositeFont object that is corresponding to the specified logical 
-     * family name.
-     * 
-     * @param familyName logical family name CompositeFont is to be created from
-     * @param faceName logical face name CompositeFont is to be created from
-     * @param _style style of the CompositeFont to be created
-     * @param _size size of the CompositeFont to be created 
-     * @param fProperties an array of FontProperties describing physical fonts - 
-     * parts of logical font
-     * @param physFonts an array of physical font peers related to the CompositeFont
-     * to be created
-     */
-    public CompositeFont(String familyName, String faceName, int _style, int _size, FontProperty[] fProperties, FontPeerImpl[] physFonts){
-        this.size = _size;
-        this.name = faceName;
-        this.family = familyName;
-        this.style = _style;
-        this.face = faceName;
-        this.psName = faceName;
-        this.fontProperties = fProperties;// !! Supposed that fProperties parameter != null
-        fPhysicalFonts = physFonts;
-        numFonts = fPhysicalFonts.length; 
-        setDefaultLineMetrics("", null); //$NON-NLS-1$
-        this.uniformLM = false;
-    }
-
-    /**
-     * Returns the index of the FontPeer in array of physical fonts that is applicable 
-     * for the given character. This font has to have the highest priority among fonts
-     * that can display this character and don't have exclusion range covering 
-     * specified character. If there is no desired fonts -1 is returned.
-     * 
-     * @param chr specified character
-     * @return index of the font from the array of physical fonts that will be used 
-     * during processing of the specified character. 
-     */
-    public int getCharFontIndex(char chr){
-        for (int i = 0; i < numFonts; i++){
-            if (fontProperties[i].isCharExcluded(chr)){
-                continue;
-            }
-            if (fPhysicalFonts[i].canDisplay(chr)){
-                return i;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns the index of the FontPeer in array of physical fonts that is applicable 
-     * for the given character. This font has to have the highest priority among fonts
-     * that can display this character and don't have exclusion range covering 
-     * specified character. If there is no desired fonts default value is returned.
-     * 
-     * @param chr specified character
-     * @param defaultValue default index that is returned if the necessary font couldn't be found.
-     * @return index of the font from the array of physical fonts that will be used 
-     * during processing of the specified character. 
-     */
-     public int getCharFontIndex(char chr, int defaultValue){
-        for (int i = 0; i < numFonts; i++){
-            if (fontProperties[i].isCharExcluded(chr)){
-                continue;
-            }
-            if (fPhysicalFonts[i].canDisplay(chr)){
-                return i;
-            }
-        }
-
-        return defaultValue;
-    }
-
-    /**
-     * Returns true if one of the physical fonts composing this font CompositeFont 
-     * can display specified character.
-     *   
-     * @param chr specified character
-     */
-    @Override
-    public boolean canDisplay(char chr){
-        return (getCharFontIndex(chr) != -1);
-    }
-
-    /**
-     * Returns logical ascent (in pixels)
-     */
-    @Override
-    public int getAscent(){
-        return nlm.getLogicalAscent();
-    }
-
-    /**
-     * Returns LineMetrics instance scaled according to the specified transform.  
-     * 
-     * @param str specified String 
-     * @param frc specified FontRenderContext 
-     * @param at specified AffineTransform
-     */
-     @Override
-    public LineMetrics getLineMetrics(String str, FontRenderContext frc , AffineTransform at){
-        LineMetricsImpl lm = (LineMetricsImpl)(this.nlm.clone());
-        lm.setNumChars(str.length());
-
-        if ((at != null) && (!at.isIdentity())){
-            lm.scale((float)at.getScaleX(), (float)at.getScaleY());
-        }
-
-        return lm;
-    }
-
-    /**
-     * Returns cached LineMetrics instance for the null string or creates it if
-     * it wasn't cached yet.
-     */
-    @Override
-    public LineMetrics getLineMetrics(){
-        if (nlm == null){
-            setDefaultLineMetrics("", null); //$NON-NLS-1$
-        }
-
-        return this.nlm;
-    }
-
-    /**
-     * Creates LineMetrics instance and set cached LineMetrics field to it.
-     * Created LineMetrics has maximum values of the idividual metrics of all
-     * composing physical fonts. If there is only one physical font - it's 
-     * LineMetrics object is returned.
-     * 
-     * @param str specified String 
-     * @param frc specified FontRenderContext 
-     */
-    private void setDefaultLineMetrics(String str, FontRenderContext frc){
-        LineMetrics lm = fPhysicalFonts[0].getLineMetrics(str, frc, null);
-        float maxCharWidth = (float)fPhysicalFonts[0].getMaxCharBounds(frc).getWidth();
-
-        if (numFonts == 1) {
-            this.nlm = (LineMetricsImpl)lm;
-            return;
-        }
-
-        float[] baselineOffsets = lm.getBaselineOffsets();
-        int numChars = str.length();
-
-        // XXX: default value - common for all Fonts
-        int baseLineIndex = lm.getBaselineIndex();
-
-        float maxUnderlineThickness = lm.getUnderlineThickness();
-        float maxUnderlineOffset = lm.getUnderlineOffset();
-        float maxStrikethroughThickness = lm.getStrikethroughThickness();
-        float minStrikethroughOffset = lm.getStrikethroughOffset();
-        float maxLeading = lm.getLeading();  // External leading
-        float maxHeight = lm.getHeight();   // Height of the font ( == (ascent + descent + leading))
-        float maxAscent = lm.getAscent();   // Ascent of the font
-        float maxDescent = lm.getDescent(); // Descent of the font
-
-        for (int i = 1; i < numFonts; i++){
-            lm = fPhysicalFonts[i].getLineMetrics(str, frc, null);
-            if (maxUnderlineThickness < lm.getUnderlineThickness()){
-                maxUnderlineThickness = lm.getUnderlineThickness();
-            }
-
-            if (maxUnderlineOffset < lm.getUnderlineOffset()){
-                maxUnderlineOffset = lm.getUnderlineOffset();
-            }
-
-            if (maxStrikethroughThickness < lm.getStrikethroughThickness()){
-                maxStrikethroughThickness = lm.getStrikethroughThickness();
-            }
-
-            if (minStrikethroughOffset > lm.getStrikethroughOffset()){
-                minStrikethroughOffset = lm.getStrikethroughOffset();
-            }
-
-            if (maxLeading < lm.getLeading()){
-                maxLeading = lm.getLeading();
-            }
-
-            if (maxAscent < lm.getAscent()){
-                maxAscent = lm.getAscent();
-            }
-
-            if (maxDescent < lm.getDescent()){
-                maxDescent = lm.getDescent();
-            }
-
-            float width = (float)fPhysicalFonts[i].getMaxCharBounds(frc).getWidth();
-            if(maxCharWidth < width){
-                maxCharWidth = width;
-            }
-            for (int j =0; j < baselineOffsets.length; j++){
-                float[] offsets = lm.getBaselineOffsets();
-                if (baselineOffsets[j] > offsets[j]){
-                    baselineOffsets[j] = offsets[j];
-                }
-            }
-
-        }
-        maxHeight = maxAscent + maxDescent + maxLeading;
-
-        this.nlm =  new LineMetricsImpl(
-                numChars,
-                baseLineIndex,
-                baselineOffsets,
-                maxUnderlineThickness,
-                maxUnderlineOffset,
-                maxStrikethroughThickness,
-                minStrikethroughOffset,
-                maxLeading,
-                maxHeight,
-                maxAscent,
-                maxDescent,
-                maxCharWidth);
-
-    }
-
-    /**
-     * Returns the number of glyphs in this CompositeFont object.
-     */
-    @Override
-    public int getNumGlyphs(){
-        if (this.cachedNumGlyphs == -1){
-
-            this.cachedNumGlyphs = 0;
-
-            for (int i = 0; i < numFonts; i++){
-                this.cachedNumGlyphs += fPhysicalFonts[i].getNumGlyphs();
-            }
-        }
-
-        return this.cachedNumGlyphs;
-    }
-
-    /**
-     * Returns the italic angle of this object.
-     */
-    @Override
-    public float getItalicAngle(){
-        // !! only first physical font used to get this value
-        return fPhysicalFonts[0].getItalicAngle();
-    }
-
-    /**
-     * Returns rectangle that bounds the specified string in terms of composite line metrics.
-     * 
-     * @param chars an array of chars
-     * @param start the initial offset in array of chars
-     * @param end the end offset in array of chars
-     * @param frc specified FontRenderContext
-     */
-    public Rectangle2D getStringBounds(char[] chars, int start, int end, FontRenderContext frc){
-
-        LineMetrics lm = getLineMetrics();
-        float minY = -lm.getAscent();
-        float minX = 0;
-        float height = lm.getHeight();
-        float width = 0;
-
-        for (int i = start; i < end; i++){
-            width += charWidth(chars[i]);
-        }
-
-        Rectangle2D rect2D = new Rectangle2D.Float(minX, minY, width, height);
-        return rect2D;
-
-    }
-
-    /**
-     * Returns maximum rectangle that encloses all maximum char bounds of 
-     * physical fonts composing this CompositeFont.
-     *  
-     * @param frc specified FontRenderContext
-     */
-    @Override
-    public Rectangle2D getMaxCharBounds(FontRenderContext frc){
-
-        Rectangle2D rect2D = fPhysicalFonts[0].getMaxCharBounds(frc);
-        float minY = (float)rect2D.getY();
-        float maxWidth = (float)rect2D.getWidth();
-        float maxHeight = (float)rect2D.getHeight();
-        if (numFonts == 1){
-            return rect2D;
-        }
-
-        for (int i = 1; i < numFonts; i++){
-            if (fPhysicalFonts[i] != null){
-                rect2D = fPhysicalFonts[i].getMaxCharBounds(frc);
-                float y = (float)rect2D.getY();
-                float mWidth = (float)rect2D.getWidth();
-                float mHeight = (float)rect2D.getHeight();
-                if (y < minY){
-                    minY = y;
-                }
-                if (mWidth > maxWidth){
-                    maxHeight = mWidth;
-                }
-                
-                if (mHeight > maxHeight){
-                    maxHeight = mHeight;
-                }
-            }
-        }
-
-        rect2D = new Rectangle2D.Float(0, minY, maxWidth, maxHeight);
-
-        return rect2D;
-    }
-
-    /**
-     * Returns font name.
-     */
-    @Override
-    public String getFontName(){
-        return face;
-    }
-
-    /**
-     * Returns font postscript name.
-     */
-    @Override
-    public String getPSName(){
-        return psName;
-    }
-
-    /**
-     * Returns font family name.
-     */
-    @Override
-    public String getFamily(){
-        return family;
-    }
-
-    /**
-     * Returns the code of the missing glyph.
-     */
-    @Override
-    public int getMissingGlyphCode(){
-        // !! only first physical font used to get this value
-        return fPhysicalFonts[0].getMissingGlyphCode();
-    }
-
-    /**
-     * Returns Glyph object corresponding to the specified character.
-     * 
-     * @param ch specified char
-     */
-    @Override
-    public Glyph getGlyph(char ch){
-        for (int i = 0; i < numFonts; i++){
-            if (fontProperties[i].isCharExcluded(ch)){
-                    continue;
-            }
-            
-            /* Control symbols considered to be supported by the font peer */
-            if ((ch < 0x20) || fPhysicalFonts[i].canDisplay(ch)){
-                return fPhysicalFonts[i].getGlyph(ch);
-            }
-        }
-        return getDefaultGlyph();
-    }
-
-    /**
-     * Returns width of the char with specified index.
-     * 
-     * @param ind specified index of the character 
-     */
-    @Override
-    public int charWidth(int ind){
-        return charWidth((char)ind);
-    }
-
-    /**
-     * Returns width of the specified char.
-     * 
-     * @param c specified character 
-     */
-    @Override
-    public int charWidth(char c){
-        Glyph gl = this.getGlyph(c);
-        return (int)gl.getGlyphPointMetrics().getAdvanceX();
-    }
-
-    /**
-     * Returns debug information about this class.
-     */
-    @Override
-    public String toString(){
-    return new String(this.getClass().getName() +
-            "[name=" + this.name + //$NON-NLS-1$
-            ",style="+ this.style + //$NON-NLS-1$
-            ",fps=" + this.fontProperties + "]"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    /**
-     * Returns Glyph object corresponding to the default glyph.
-     */
-    @Override
-    public Glyph getDefaultGlyph(){
-        // !! only first physical font used to get this value
-        return fPhysicalFonts[0].getDefaultGlyph();
-    }
-    
-    /**
-     * Returns FontExtraMetrics object with extra metrics
-     * related to this CompositeFont.
-     */
-    @Override
-    public FontExtraMetrics getExtraMetrics(){
-        // Returns FontExtraMetrics instanse of the first physical 
-        // Font from the array of fonts.
-        return fPhysicalFonts[0].getExtraMetrics();
-    }
-
-    /**
-     * Disposes CompositeFont object's resources.
-     */
-    @Override
-    public void dispose() {
-        // Nothing to dispose
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontExtraMetrics.java b/awt/org/apache/harmony/awt/gl/font/FontExtraMetrics.java
deleted file mode 100644
index 047ba6d..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontExtraMetrics.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- * 
- */
-package org.apache.harmony.awt.gl.font;
-
-/**
- * Extra font metrics: sub/superscripts sizes, offsets, average char width.
- */
-public class FontExtraMetrics {
-    
-    /* !! Subscript/superscript metrics are undefined for Type1. As a possible 
-     * solution we can use values for Type1, that are proportionate to TrueType
-     * ones:
-     *  SubscriptSizeX == 0.7 * fontSize
-     *  SubscriptSizeY == 0.65 * fontSize
-     *  SubscriptOffsetX == 0;
-     *  SubscriptOffsetY == 0.15 * fontSize;
-     *  SuperscriptSizeX == 0.7 * fontSize
-     *  SuperscriptSizeY == 0.65 * fontSize
-     *  SuperscriptOffsetX == 0;
-     *  SuperscriptOffsetY == 0.45 * fontSize
-     *  
-     */
-    
-    /*
-     * The average width of characters in the font.
-     */
-    private float lAverageCharWidth;
-    
-    /*
-     * Horizontal size for subscripts.
-     */
-    private float lSubscriptSizeX;
-
-    /*
-     * Vertical size for subscripts.
-     */
-    private float lSubscriptSizeY; 
-    
-    /*
-     * Horizontal offset for subscripts, the offset from the character origin 
-     * to the origin of the subscript character.
-     */
-    private float lSubscriptOffsetX; 
-
-    /*
-     * Vertical offset for subscripts, the offset from the character origin 
-     * to the origin of the subscript character.
-     */
-    private float lSubscriptOffsetY;
-    
-    /*
-     * Horizontal size for superscripts.
-     */
-    private float lSuperscriptSizeX; 
-
-    /*
-     * Vertical size for superscripts.
-     */
-    private float lSuperscriptSizeY;
-    
-    /*
-     * Horizontal offset for superscripts, the offset from the character 
-     * base line to the base line of the superscript character.
-     */
-    private float lSuperscriptOffsetX;
-
-    /*
-     * Vertical offset for superscripts, the offset from the character 
-     * base line to the base line of the superscript character.
-     */
-    private float lSuperscriptOffsetY;
-    
-    public FontExtraMetrics(){
-        // default constructor
-    }
-
-    public FontExtraMetrics(float[] metrics){
-        lAverageCharWidth = metrics[0];
-        lSubscriptSizeX = metrics[1];
-        lSubscriptSizeY = metrics[2];
-        lSubscriptOffsetX = metrics[3];
-        lSubscriptOffsetY = metrics[4];
-        lSuperscriptSizeX = metrics[5];
-        lSuperscriptSizeY = metrics[6];
-        lSuperscriptOffsetX = metrics[7];
-        lSuperscriptOffsetY = metrics[8];
-    }
-
-    public float getAverageCharWidth(){
-        return lAverageCharWidth;
-    }
-    
-    public float getSubscriptSizeX(){
-        return lSubscriptSizeX;
-    }
-
-    public float getSubscriptSizeY(){
-        return lSubscriptSizeY;
-    }
-
-    public float getSubscriptOffsetX(){
-        return lSubscriptOffsetX;
-    }
-
-    public float getSubscriptOffsetY(){
-        return lSubscriptOffsetY;
-    }
-
-    public float getSuperscriptSizeX(){
-        return lSuperscriptSizeX;
-    }
-
-    public float getSuperscriptSizeY(){
-        return lSuperscriptSizeY;
-    }
-
-    public float getSuperscriptOffsetX(){
-        return lSuperscriptOffsetX;
-    }
-
-    public float getSuperscriptOffsetY(){
-        return lSuperscriptOffsetY;
-    }
-    
-    
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontFinder.java b/awt/org/apache/harmony/awt/gl/font/FontFinder.java
deleted file mode 100644
index 09bcf5c..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontFinder.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Jul 12, 2005
- */
-
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.Font;
-import java.awt.GraphicsEnvironment;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class chooses the default font for the given text.
- * If it finds the character which current font is unable to display
- * it starts the next font run and looks for the font which is able to
- * display the current character. It also caches the font mappings
- * (index in the array containing all fonts) for the characters,
- * using that fact that scripts are mainly contiguous in the UTF-16 encoding
- * and there's a high probability that the upper byte will be the same for the
- * next character as for the previous. This allows to save the space used for the cache.
- */
-public class FontFinder {
-    private static final float DEFAULT_FONT_SIZE = 12;
-
-    private static final Font fonts[] =
-            GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
-
-    private static final int NUM_BLOCKS = 256;
-    private static final int BLOCK_SIZE = 256;
-    private static final int INDEX_MASK = 0xFF;
-    private static final int BLOCK_SHIFT = 8;
-
-    // Maps characters into the fonts array
-    private static final int blocks[][] = new int[NUM_BLOCKS][];
-
-    /**
-     * Finds the font which is able to display the given character
-     * and saves the font mapping for this character
-     * @param c - character
-     * @return font
-     */
-    static Font findFontForChar(char c) {
-        int blockNum = c >> BLOCK_SHIFT;
-        int index = c & INDEX_MASK;
-
-        if (blocks[blockNum] == null) {
-            blocks[blockNum] = new int[BLOCK_SIZE];
-        }
-
-        if (blocks[blockNum][index] == 0) {
-            blocks[blockNum][index] = 1;
-
-            for (int i=0; i<fonts.length; i++) {
-                if (fonts[i].canDisplay(c)) {
-                    blocks[blockNum][index] = i+1;
-                    break;
-                }
-            }
-        }
-
-        return getDefaultSizeFont(blocks[blockNum][index]-1);
-    }
-
-    /**
-     * Derives the default size font
-     * @param i - index in the array of all fonts
-     * @return derived font
-     */
-    static Font getDefaultSizeFont(int i) {
-        if (fonts[i].getSize() != DEFAULT_FONT_SIZE) {
-            fonts[i] = fonts[i].deriveFont(DEFAULT_FONT_SIZE);
-        }
-
-        return fonts[i];
-    }
-
-    /**
-     * Assigns default fonts for the given text run.
-     * First three parameters are input, last three are output.
-     * @param text - given text
-     * @param runStart - start of the text run
-     * @param runLimit - end of the text run
-     * @param runStarts - starts of the resulting font runs
-     * @param fonts - mapping of the font run starts to the fonts
-     */
-    static void findFonts(char text[], int runStart, int runLimit, List<Integer> runStarts,
-            Map<Integer, Font> fonts) {
-        Font prevFont = null;
-        Font currFont;
-        for (int i = runStart; i < runLimit; i++) {
-            currFont = findFontForChar(text[i]);
-            if (currFont != prevFont) {
-                prevFont = currFont;
-                Integer idx = new Integer(i);
-                fonts.put(idx, currFont);
-                if (i != runStart) {
-                    runStarts.add(idx);
-                }
-            }
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontManager.java b/awt/org/apache/harmony/awt/gl/font/FontManager.java
deleted file mode 100644
index 8354e25..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontManager.java
+++ /dev/null
@@ -1,819 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.Font;
-import java.awt.peer.FontPeer;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Locale;
-import java.util.Properties;
-import java.util.Vector;
-
-import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
-import org.apache.harmony.luni.util.NotImplementedException;
-
-
-public abstract class FontManager {
-    
-    //???AWT
-    boolean NOT_IMP = false;
-    
-    /**
-     * array of font families names
-     */
-    public String[] allFamilies;
-
-    public static final String DEFAULT_NAME = "Default"; /* Default font name */ //$NON-NLS-1$
-    public static final String DIALOG_NAME = "Dialog";  /* Dialog font name */ //$NON-NLS-1$
-
-    /**
-     * Set of constants applicable to the TrueType 'name' table.
-     */
-    public static final byte  FAMILY_NAME_ID  = 1;      /* Family name identifier   */
-    public static final byte  FONT_NAME_ID  = 4;        /* Full font name identifier    */
-    public static final byte  POSTSCRIPT_NAME_ID = 6;   /* PostScript name identifier   */
-    public static final short ENGLISH_LANGID = 0x0409;  /* English (United States)language identifier   */
-
-    /**
-     * Set of constants describing font type.
-     */
-    public static final byte  FONT_TYPE_TT  = 4;        /* TrueType type (TRUETYPE_FONTTYPE)    */
-    public static final byte  FONT_TYPE_T1  = 2;        /* Type1 type    (DEVICE_FONTTYPE)      */
-    public static final byte  FONT_TYPE_UNDEF  = 0;     /* Undefined type                       */
-
-    // logical family types (indices in FontManager.LOGICAL_FONT_NAMES)
-    static final int DIALOG = 3;        // FF_SWISS
-    static final int SANSSERIF = 1;     // FF_SWISS
-    static final int DIALOGINPUT = 4;   // FF_MODERN
-    static final int MONOSPACED = 2;    // FF_MODERN
-    static final int SERIF = 0;         // FF_ROMAN
-
-
-    /**
-     * FontProperty related constants. 
-     */
-    public static final String PLATFORM_FONT_NAME = "PlatformFontName"; //$NON-NLS-1$
-    public static final String LOGICAL_FONT_NAME = "LogicalFontName"; //$NON-NLS-1$
-    public static final String COMPONENT_INDEX = "ComponentIndex"; //$NON-NLS-1$
-    public static final String STYLE_INDEX = "StyleIndex"; //$NON-NLS-1$
-
-    public static final String[] FONT_MAPPING_KEYS = {
-            "LogicalFontName.StyleName.ComponentIndex", "LogicalFontName.ComponentIndex" //$NON-NLS-1$ //$NON-NLS-2$
-    };
-
-    public static final String FONT_CHARACTER_ENCODING = "fontcharset.LogicalFontName.ComponentIndex"; //$NON-NLS-1$
-
-    public static final String EXCLUSION_RANGES = "exclusion.LogicalFontName.ComponentIndex"; //$NON-NLS-1$
-
-    public static final String FONT_FILE_NAME = "filename.PlatformFontName"; //$NON-NLS-1$
-
-    /**
-     * Available logical font families names.
-     */
-    public static final String[] LOGICAL_FONT_FAMILIES = {
-            "Serif", "SansSerif", "Monospaced", "Dialog", "DialogInput" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-    };
-
-    /**
-     * Available logical font names.
-     */
-    public static final String[] LOGICAL_FONT_NAMES = {
-            "serif", "serif.plain", "serif.bold", "serif.italic", "serif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-            "sansserif", "sansserif.plain", "sansserif.bold", "sansserif.italic", "sansserif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-            "monospaced", "monospaced.plain", "monospaced.bold", "monospaced.italic", "monospaced.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-            "dialog", "dialog.plain", "dialog.bold", "dialog.italic", "dialog.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-            "dialoginput", "dialoginput.plain", "dialoginput.bold", "dialoginput.italic", "dialoginput.bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-    };
-
-    /**
-     * Available logical font face names.
-     */
-    public static final String[] LOGICAL_FONT_FACES = {
-            "Serif", "Serif.plain", "Serif.bold", "Serif.italic", "Serif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-            "Sansserif", "Sansserif.plain", "Sansserif.bold", "Sansserif.italic", "Sansserif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-            "Monospaced", "Monospaced.plain", "Monospaced.bold", "Monospaced.italic", "Monospaced.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-            "Dialog", "Dialog.plain", "Dialog.bold", "Dialog.italic", "Dialog.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-            "Dialoginput", "Dialoginput.plain", "Dialoginput.bold", "Dialoginput.italic", "Dialoginput.bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-    };
-
-    /**
-     * Set of font style names.
-     * Font.getStyle() corresponds to indexes in STYLE_NAMES array.
-     */
-    public static final String[] STYLE_NAMES = {
-            "plain", "bold", "italic", "bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-    };
-
-    /**
-     * Logical font styles names table where font styles names used 
-     * as the key and the value is the index of this style name.
-     */
-    private static final Hashtable<String, Integer> style_keys = new Hashtable<String, Integer>(4);
-
-    /**
-     * Initialize font styles keys table.
-     */
-    static {
-        for (int i = 0; i < STYLE_NAMES.length; i++){
-            style_keys.put(STYLE_NAMES[i], Integer.valueOf(i));
-        }
-    }
-
-    /**
-     * Return font style from the logical style name.
-     * 
-     * @param lName style name of the logical face
-     */
-    public static int getLogicalStyle(String lName){
-        Integer value = style_keys.get(lName);
-        return value != null ? value.intValue(): -1;
-    }
-
-    /**
-     * Set of possible "os" property values.
-     */
-    public static final String[] OS_VALUES = {
-            "NT", "98", "2000", "Me", "XP", // For Windows //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-            "Redhat", "Turbo", "SuSE"       // For Linux //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-    };
-
-    /**
-     * Set of possible font.property file names.
-     * Language, Country, Encoding, OS, Version should be replaced with
-     * the values from current configuration.
-     */
-    public static final String[] FP_FILE_NAMES = {
-            "/lib/font.properties.Language_Country_Encoding.OSVersion", //$NON-NLS-1$
-            "/lib/font.properties.Language_Country_Encoding.OS", //$NON-NLS-1$
-            "/lib/font.properties.Language_Country_Encoding.Version", //$NON-NLS-1$
-            "/lib/font.properties.Language_Country_Encoding", //$NON-NLS-1$
-            "/lib/font.properties.Language_Country.OSVersion", //$NON-NLS-1$
-            "/lib/font.properties.Language_Country.OS", //$NON-NLS-1$
-            "/lib/font.properties.Language_Country.Version", //$NON-NLS-1$
-            "/lib/font.properties.Language_Country", //$NON-NLS-1$
-            "/lib/font.properties.Language_Encoding.OSVersion", //$NON-NLS-1$
-            "/lib/font.properties.Language_Encoding.OS", //$NON-NLS-1$
-            "/lib/font.properties.Language_Encoding.Version", //$NON-NLS-1$
-            "/lib/font.properties.Language_Encoding", //$NON-NLS-1$
-            "/lib/font.properties.Language.OSVersion", //$NON-NLS-1$
-            "/lib/font.properties.Language.OS", //$NON-NLS-1$
-            "/lib/font.properties.Language.Version", //$NON-NLS-1$
-            "/lib/font.properties.Language", //$NON-NLS-1$
-            "/lib/font.properties.Encoding.OSVersion", //$NON-NLS-1$
-            "/lib/font.properties.Encoding.OS", //$NON-NLS-1$
-            "/lib/font.properties.Encoding.Version", //$NON-NLS-1$
-            "/lib/font.properties.Encoding", //$NON-NLS-1$
-            "/lib/font.properties.OSVersion", //$NON-NLS-1$
-            "/lib/font.properties.OS", //$NON-NLS-1$
-            "/lib/font.properties.Version", //$NON-NLS-1$
-            "/lib/font.properties" //$NON-NLS-1$
-    };
-
-    /**
-     * Table with all available font properties corresponding
-     * to the current system configuration.
-     */
-    public Hashtable<String, Vector<FontProperty>> fProperties = new Hashtable<String, Vector<FontProperty>>();
-    
-    public FontManager(){
-        allFamilies = getAllFamilies();
-        /*
-         * Creating and registering shutdown hook to free resources
-         * before object is destroyed.
-         */
-        //???AWT
-        //DisposeNativeHook shutdownHook = new DisposeNativeHook();
-        //Runtime.getRuntime().addShutdownHook(shutdownHook);
-    }
-
-    /**
-     * Maximum number of unreferenced font peers to keep.
-     */
-    public static final int EMPTY_FONTS_CAPACITY = 10;
-
-    /**
-     * Locale - Language ID hash table.
-     */
-    Hashtable<String, Short> tableLCID = new Hashtable<String, Short>();
-
-    /**
-     * Hash table that contains FontPeers instances.
-     */
-    public Hashtable<String, HashMapReference> fontsTable = new Hashtable<String, HashMapReference>();
-    
-    /**
-     * ReferenceQueue for HashMapReference objects to check
-     * if they were collected by garbage collector. 
-     */
-    public ReferenceQueue<FontPeer> queue = new ReferenceQueue<FontPeer>();
-
-    /**
-     * Singleton instance
-     */
-    public final static FontManager inst = CommonGraphics2DFactory.inst.getFontManager();
-
-    /**
-     * Gets singleton instance of FontManager
-     * 
-     * @return instance of FontManager implementation
-     */
-    public static FontManager getInstance() {
-        return inst;
-    }
-
-    /**
-     * Returns platform-dependent Font peer created from the specified 
-     * Font object from the table with cached FontPeers instances.
-     * 
-     * Note, this method checks whether FontPeer with specified parameters 
-     * exists in the table with cached FontPeers' instances. If there is no needed 
-     * instance - it is created and cached.
-     * 
-     * @param fontName name of the font 
-     * @param _fontStyle style of the font 
-     * @param size font size
-     * 
-     * @return platform dependent FontPeer implementation created from 
-     * the specified parameters
-     */
-    public FontPeer getFontPeer(String fontName, int _fontStyle, int size) {
-        updateFontsTable();
-        
-        FontPeer peer = null;
-        String key; 
-        String name;
-        int fontStyle = _fontStyle;
-        
-        int logicalIndex = getLogicalFaceIndex(fontName);
-        
-        if (logicalIndex != -1){
-            name = getLogicalFaceFromFont(fontStyle, logicalIndex);
-            fontStyle = getStyleFromLogicalFace(name);
-            key = name.concat(String.valueOf(size));
-        } else {
-            name = fontName;
-            key = name.concat(String.valueOf(fontStyle)).
-                    concat(String.valueOf(size));
-        }
-        
-        HashMapReference hmr   = fontsTable.get(key);
-        if (hmr != null) {
-            peer = hmr.get();
-        }
-
-        if (peer == null) {
-            peer = createFontPeer(name, fontStyle, size, logicalIndex);
-            if (peer == null){
-                peer = getFontPeer(DIALOG_NAME, fontStyle, size);
-            }
-            fontsTable.put(key, new HashMapReference(key, peer, queue));
-        }
-
-        return peer;
-    }
-    
-    /**
-     * Returns instance of font peer (logical or physical) according to the 
-     * specified parameters.
-     * 
-     * @param name font face name
-     * @param style style of the font
-     * @param size size of the font
-     * @param logicalIndex index of the logical face name in LOGICAL_FONT_FACES 
-     * array or -1 if desired font peer is not logical.
-     */
-    private FontPeer createFontPeer(String name, int style, int size, int logicalIndex){
-        FontPeer peer;
-        if (logicalIndex != -1){
-            peer = createLogicalFontPeer(name, style, size);
-        }else {
-            peer = createPhysicalFontPeer(name, style, size);
-        }
-        
-        return peer;
-    }
-    
-    /**
-     * Returns family name for logical face names as a parameter.
-     * 
-     * @param faceName logical font face name
-     */
-    public String getFamilyFromLogicalFace(String faceName){
-        int pos = faceName.indexOf("."); //$NON-NLS-1$
-        if (pos == -1){
-            return faceName;
-        }
-            
-        return faceName.substring(0, pos);
-    }
-            
-    /**
-     * Returns new logical font peer for the parameters specified using font 
-     * properties.
-     * 
-     * @param faceName face name of the logical font 
-     * @param style style of the font 
-     * @param size font size
-     * 
-     */
-    private FontPeer createLogicalFontPeer(String faceName, int style, int size){
-        String family = getFamilyFromLogicalFace(faceName);
-        FontProperty[] fps = getFontProperties(family.toLowerCase() + "." + style); //$NON-NLS-1$
-        if (fps != null){
-            int numFonts = fps.length;
-            FontPeerImpl[] physicalFonts = new FontPeerImpl[numFonts];
-            for (int i = 0; i < numFonts; i++){
-                FontProperty fp = fps[i];
-                
-                String name = fp.getName();
-                int fpStyle = fp.getStyle();
-                String key = name.concat(String.valueOf(fpStyle)).
-                    concat(String.valueOf(size));
-                
-                HashMapReference hmr   = fontsTable.get(key);
-                if (hmr != null) {
-                    physicalFonts[i] = (FontPeerImpl)hmr.get();
-                }
-
-                if (physicalFonts[i] == null){
-                    physicalFonts[i] = (FontPeerImpl)createPhysicalFontPeer(name, fpStyle, size);
-                    fontsTable.put(key, new HashMapReference(key, physicalFonts[i], queue));
-                }
-
-                if (physicalFonts[i] == null){
-                    physicalFonts[i] = (FontPeerImpl)getDefaultFont(style, size);
-                }
-            }
-            return new CompositeFont(family, faceName, style, size, fps, physicalFonts); 
-        }
-        
-        // if there is no property for this logical font - default font is to be
-        // created
-        FontPeerImpl peer = (FontPeerImpl)getDefaultFont(style, size);
-        
-        return peer;
-    }
-
-    /**
-     * Returns new physical font peer for the parameters specified using font properties
-     * This method must be overridden by subclasses implementations.
-     *  
-     * @param faceName face name or family name of the font 
-     * @param style style of the font 
-     * @param size font size
-     * 
-     */
-    public abstract FontPeer createPhysicalFontPeer(String name, int style, int size);
-    
-    /**
-     * Returns default font peer class with "Default" name that is usually 
-     * used when font with specified font names and style doesn't exsist 
-     * on a system. 
-     * 
-     * @param style style of the font
-     * @param size size of the font
-     */
-    public FontPeer getDefaultFont(int style, int size){
-        updateFontsTable();
-        
-        FontPeer peer = null;
-        String key = DEFAULT_NAME.concat(String.valueOf(style)).
-                    concat(String.valueOf(size));
-        
-        HashMapReference hmr   = fontsTable.get(key);
-        if (hmr != null) {
-            peer = hmr.get();
-        }
-
-        if (peer == null) {
-            peer = createDefaultFont(style, size);
-            
-            ((FontPeerImpl)peer).setFamily(DEFAULT_NAME);
-            ((FontPeerImpl)peer).setPSName(DEFAULT_NAME);
-            ((FontPeerImpl)peer).setFontName(DEFAULT_NAME);
-
-            fontsTable.put(key, new HashMapReference(key, peer, queue));
-        }
-
-        return peer;
-    }
-    
-    /**
-     * 
-     * Returns new default font peer with "Default" name for the parameters 
-     * specified. This method must be overridden by subclasses implementations.
-     *  
-     * @param style style of the font
-     * @param size size of the font
-     */
-    public abstract FontPeer createDefaultFont(int style, int size);
-    
-    /**
-     * Returns face name of the logical font, which is the result
-     * of specified font style and face style union.   
-     * 
-     * @param fontStyle specified style of the font
-     * @param logicalIndex index of the specified face from the 
-     * LOGICAL_FONT_FACES array
-     * @return resulting face name
-     */
-    public String getLogicalFaceFromFont(int fontStyle, int logicalIndex){
-        int style = 0;
-        String name = LOGICAL_FONT_FACES[logicalIndex];
-        int pos = name.indexOf("."); //$NON-NLS-1$
-        
-        if (pos == -1){
-            return createLogicalFace(name, fontStyle);
-        }
-        
-        String styleName = name.substring(pos+1);
-        name = name.substring(0, pos);
-        
-        // appending font style to the face style
-        style = fontStyle | getLogicalStyle(styleName);
-        
-        return createLogicalFace(name, style);
-    }
-    
-    /**
-     * Function returns style value from logical face name.
-     *  
-     * @param name face name
-     * @return font style
-     */
-    public int getStyleFromLogicalFace(String name){
-        int style;
-        int pos = name.indexOf("."); //$NON-NLS-1$
-        
-        if (pos == -1){
-            return Font.PLAIN;
-        }
-        
-        String styleName = name.substring(pos+1);
-        
-        style = getLogicalStyle(styleName);
-        
-        return style;
-    }
-
-    /**
-     * Returns logical face name corresponding to the logical
-     * family name and style of the font.
-     * 
-     * @param family font family
-     * @param styleIndex index of the style name from the STYLE_NAMES array 
-     */
-    public String createLogicalFace(String family, int styleIndex){
-        return family + "." + STYLE_NAMES[styleIndex]; //$NON-NLS-1$
-    }
-    
-    /**
-     * Return language Id from LCID hash corresponding to the specified locale
-     * 
-     * @param l specified locale
-     */
-    public Short getLCID(Locale l){
-        if (this.tableLCID.size() == 0){
-            initLCIDTable();
-        }
-
-        return tableLCID.get(l.toString());
-    }
-
-    /**
-     * Platform-dependent LCID table init.
-     */
-    public abstract void initLCIDTable();
-
-    /**
-     * Freeing native resources. This hook is used to avoid 
-     * sudden application exit and to free resources created in native code.
-     */
-    private class DisposeNativeHook extends Thread {
-
-        @Override
-        public void run() {
-            try{
-                /* Disposing native font peer's resources */
-                Enumeration<String> kEnum = fontsTable.keys();
-
-                while(kEnum.hasMoreElements()){
-                    Object key = kEnum.nextElement();
-                    HashMapReference hmr = fontsTable.remove(key);
-                    FontPeerImpl delPeer = (FontPeerImpl)hmr.get();
-                    
-                    if ((delPeer != null) && (delPeer.getClass() != CompositeFont.class)){
-                        // there's nothing to dispose in CompositeFont objects
-                        delPeer.dispose();
-                    }
-                }
-            } catch (Throwable t){
-                throw new RuntimeException(t);
-            }
-        }
-      }
-
-    /**
-     * Returns File object, created in a directory
-     * according to the System, where JVM is being ran.
-     *
-     * In Linux case we use ".fonts" directory (for fontconfig purpose),
-     * where font file from the stream will be stored, hence in LinuxFontManager this
-     * method is overridden.
-     * In Windows case we use Windows temp directory (default implementation)
-     *
-     */
-    public File getTempFontFile()throws IOException{
-        //???AWT
-        /*
-        File fontFile = File.createTempFile("jFont", ".ttf"); //$NON-NLS-1$ //$NON-NLS-2$
-        fontFile.deleteOnExit();
-
-        return fontFile;
-         */
-        if(NOT_IMP)
-            throw new NotImplementedException("getTempFontFile not Implemented");
-        return null;
-    }
-
-    /**
-     * Returns File object with font properties. It's name obtained using current 
-     * system configuration properties and locale settings. If no appropriate 
-     * file is found method returns null. 
-     */
-    public static File getFontPropertyFile(){
-        File file = null;
-
-        String javaHome = System.getProperty("java.home"); //$NON-NLS-1$
-        Locale l = Locale.getDefault();
-        String language = l.getLanguage();
-        String country = l.getCountry();
-        String fileEncoding = System.getProperty("file.encoding"); //$NON-NLS-1$
-
-        String os = System.getProperty("os.name"); //$NON-NLS-1$
-
-        int i = 0;
-
-        // OS names from system properties don't match
-        // OS identifiers used in font.property files
-        for (; i < OS_VALUES.length; i++){
-            if (os.endsWith(OS_VALUES[i])){
-                os = OS_VALUES[i];
-                break;
-            }
-        }
-
-        if (i == OS_VALUES.length){
-            os = null;
-        }
-
-        String version = System.getProperty("os.version"); //$NON-NLS-1$
-        String pathname;
-
-        for (i = 0; i < FP_FILE_NAMES.length; i++){
-            pathname = FP_FILE_NAMES[i];
-            if (os != null){
-                pathname = pathname.replaceFirst("OS", os); //$NON-NLS-1$
-            }
-
-            pathname = javaHome + pathname;
-
-            pathname = pathname.replaceAll("Language", language). //$NON-NLS-1$
-                                replaceAll("Country", country). //$NON-NLS-1$
-                                replaceAll("Encoding", fileEncoding). //$NON-NLS-1$
-                                replaceAll("Version", version); //$NON-NLS-1$
-
-            file = new File(pathname);
-
-            if (file.exists()){
-                break;
-            }
-        }
-
-        return file.exists() ? file : null;
-    }
-
-    /**
-     * Returns an array of integer range values
-     * if the parameter exclusionString has format:
-     *          Range
-     *          Range [, exclusionString]
-     *
-     *          Range:
-     *              Char-Char
-     *
-     *          Char:
-     *              HexDigit HexDigit HexDigit HexDigit
-     * 
-     * Method returns null if the specified string is null.
-     *  
-     * @param exclusionString string parameter in specified format
-     */
-    public static int[] parseIntervals(String exclusionString){
-        int[] results = null;
-
-        if (exclusionString == null){
-            return null;
-        }
-
-        String[] intervals = exclusionString.split(","); //$NON-NLS-1$
-
-        if (intervals != null){
-            int num = intervals.length;
-            if (num > 0){
-                results = new int[intervals.length << 1];
-                for (int i = 0; i < intervals.length; i++){
-                    String ranges[] = intervals[i].split("-"); //$NON-NLS-1$
-                    results[i*2] = Integer.parseInt(ranges[0], 16);
-                    results[i*2+1] = Integer.parseInt(ranges[1], 16);
-
-                }
-            }
-        }
-        return results;
-    }
-
-    /**
-     * Returns Properties from the properties file or null if 
-     * there is an error with FileInputStream processing.
-     * 
-     * @param file File object containing properties
-     */
-    public static Properties getProperties(File file){
-        Properties props = null;
-        FileInputStream fis = null;
-        try{
-            fis = new FileInputStream(file);
-            props = new Properties();
-            props.load(fis);
-        } catch (Exception e){
-            System.out.println(e);
-        }
-        return props;
-    }
-
-    /**
-     * Returns an array of FontProperties from the properties file
-     * with the specified property name "logical face.style". E.g. 
-     * "dialog.2" corresponds to the font family Dialog with bold style. 
-     *
-     * @param fpName key of the font properties in the properties set
-     */
-    public FontProperty[] getFontProperties(String fpName){
-        Vector<FontProperty> props = fProperties.get(fpName);
-        
-        if (props == null){
-            return null;
-        }
-
-        int size =  props.size();
-        
-        if (size == 0){
-            return null;
-        }
-
-        FontProperty[] fps = new FontProperty[size];
-        for (int i=0; i < fps.length; i++){
-            fps[i] = props.elementAt(i);
-        }
-        return fps;
-    }
-
-    /**
-     * Returns index of the font name in array of font names or -1 if 
-     * this font is not logical.
-     * 
-     * @param fontName specified font name
-     */
-    public static int getLogicalFaceIndex(String fontName){
-        for (int i=0; i<LOGICAL_FONT_NAMES.length; i++ ){
-            if (LOGICAL_FONT_NAMES[i].equalsIgnoreCase(fontName)){
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Returns true if specified family name is available in this 
-     * GraphicsEnvironment. 
-     * 
-     * @param familyName the specified font family name
-     */
-    public boolean isFamilyExist(String familyName){
-        return (getFamilyIndex(familyName) != -1);
-    }
-
-    /**
-     * Returns index of family name from the array of family names available in 
-     * this GraphicsEnvironment or -1 if no family name was found.
-     * 
-     * @param familyName specified font family name 
-     */
-    public int getFamilyIndex(String familyName){
-        for (int i=0; i<allFamilies.length; i++ ){
-            if (familyName.equalsIgnoreCase(allFamilies[i])){
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Returns family with index specified from the array of family names available in 
-     * this GraphicsEnvironment.
-     * 
-     * @param index index of the family in families names array 
-     */
-    public String getFamily(int index){
-        return allFamilies[index];
-    }
-    /**
-     * Returns index of face name from the array of face names available in 
-     * this GraphicsEnvironment or -1 if no face name was found. Default return 
-     * value is -1, method must be overridden by FontManager implementation.
-     * 
-     * @param faceName font face name which index is to be searched
-     */
-    public int getFaceIndex(String faceName){
-        return -1;
-    }
-
-    public abstract String[] getAllFamilies();
-
-    public abstract Font[] getAllFonts();
-    
-    /**
-     * Class contains SoftReference instance that can be stored in the 
-     * Hashtable by means of key field corresponding to it.
-     */
-    private class HashMapReference extends SoftReference<FontPeer> {
-        
-        /**
-         * The key for Hashtable.
-         */
-        private final String key;
-
-        /**
-         * Creates a new soft reference with the key specified and 
-         * adding this reference in the reference queue specified.
-         *
-         * @param key the key in Hashtable
-         * @param value object that corresponds to the key
-         * @param queue reference queue where reference is to be added 
-         */
-        public HashMapReference(final String key, final FontPeer value,
-                              final ReferenceQueue<FontPeer> queue) {
-            super(value, queue);
-            this.key = key;
-        }
-
-        /**
-         * Returns the key that corresponds to the SoftReference instance 
-         *
-         * @return the key in Hashtable with cached references
-         */
-        public Object getKey() {
-            return key;
-        }
-    }
-
-    /**
-     * Removes keys from the Hashtable with font peers which corresponding 
-     * HashMapReference objects were garbage collected.
-     */
-    private void updateFontsTable() {
-        HashMapReference r;
-        //???AWT
-        //while ((r = (HashMapReference)queue.poll()) != null) {
-        //    fontsTable.remove(r.getKey());
-        //}
-    }
-
-}
-
-
diff --git a/awt/org/apache/harmony/awt/gl/font/FontMetricsImpl.java b/awt/org/apache/harmony/awt/gl/font/FontMetricsImpl.java
deleted file mode 100644
index 7783317..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontMetricsImpl.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.font;
-
-import com.android.internal.awt.AndroidGraphics2D;
-
-import java.awt.Font;
-import java.awt.FontMetrics;
-//import java.awt.Paint;
-import java.awt.geom.AffineTransform;
-
-import android.graphics.Paint;
-
-/**
- * FontMetrics implementation
- */
-
-public class FontMetricsImpl extends FontMetrics {
-
-	private static final long serialVersionUID = 844695615201925138L;
-
-	// ascent of the font
-	private int ascent;
-
-	// descent of the font
-	private int descent;
-
-	// leading of the font
-	private int leading;
-
-	// maximum ascent of the font
-	private int maxAscent;
-
-	// maximum descent of the font
-	private int maxDescent;
-
-	// maximum advance of the font
-	private int maxAdvance;
-
-	// array of char advance widths
-	private int[] widths = new int[256];
-
-	// font peer corresponding to this FontPeerImpl
-	private transient FontPeerImpl peer;
-
-	// X scale parameter of the font transform
-	private float scaleX = 1;
-
-	public AndroidGraphics2D mSg;
-
-	private Font mFn;
-
-	// Y scale parameter of the font transform
-	private float scaleY = 1;
-
-	/**
-	 * Creates new FontMericsImpl object described by the specified Font.
-	 * 
-	 * @param fnt
-	 *            the specified Font object
-	 */
-	public FontMetricsImpl(Font fnt) {
-		super(fnt);
-		this.mFn = fnt;
-		
-		mSg = AndroidGraphics2D.getInstance();
-		Paint p = mSg.getAndroidPaint();
-		
-		this.ascent = (int)-p.ascent();
-		this.descent = (int)p.descent();
-		this.leading = p.getFontMetricsInt().leading;
-		
-		AffineTransform at = fnt.getTransform();
-		if (!at.isIdentity()) {
-			scaleX = (float) at.getScaleX();
-			scaleY = (float) at.getScaleY();
-		}
-				
-	    /*
-	     * metrics[5] - strikethrough thickness<p>
-	     * -metrics[6] - strikethrough offset<p>
-	     * metrics[7] - maximum char width<p>
-	     * metrics[8] - ascent in pixels<p>
-	     * metrics[9] - descent in pixles<p>
-	     * metrics[10] - external leading in pixels<p>
-	     * metrics[11] - underline thickness in pixels<p>
-	     * -metrics[12] - underline offset in pixels<p>
-	     * metrics[13] - strikethrough thickness in pixels<p>
-	     * -metrics[14] - strikethrough offset in pixels<p>
-	     * metrics[15] - maximum char width in pixels<p>
-
-	     * @param _baselineData an array of 3 elements with baseline offsets metrics<p>
-	     * _baselineData[0] - roman baseline offset<p> 
-	     * _baselineData[1] - center baseline offset<p>
-	     * _baselineData[2] - hanging baseline offset<p>
-	     */
-	}
-
-
-	/**
-	 * Initialize the array of the first 256 chars' advance widths of the Font
-	 * describing this FontMetricsImpl object.
-	 */
-	private void initWidths() {
-
-		this.widths = new int[256];
-		for (int chr = 0; chr < 256; chr++) {
-			widths[chr] = (int) (getFontPeer().charWidth((char) chr) * scaleX);
-		}
-
-	}
-
-	/**
-	 * Returns the ascent of the Font describing this FontMetricsImpl object.
-	 */
-	@Override
-	public int getAscent() {
-		return this.ascent;
-	}
-
-	/**
-	 * Returns the descent of the Font describing this FontMetricsImpl object.
-	 */
-	@Override
-	public int getDescent() {
-		return this.descent;
-	}
-
-	/**
-	 * Returns the leading of the Font describing this FontMetricsImpl object.
-	 */
-	@Override
-	public int getLeading() {
-		return this.leading;
-	}
-
-	/**
-	 * Returns the advance width of the specified char of the Font describing
-	 * this FontMetricsImpl object.
-	 * 
-	 * @param ch
-	 *            the char which width is to be returned
-	 * @return the advance width of the specified char of the Font describing
-	 *         this FontMetricsImpl object
-	 */
-	@Override
-	public int charWidth(int ch) {
-		if (ch < 256) {
-			return widths[ch];
-		}
-
-		return getFontPeer().charWidth((char) ch);
-	}
-
-	/**
-	 * Returns the advance width of the specified char of the Font describing
-	 * this FontMetricsImpl object.
-	 * 
-	 * @param ch
-	 *            the char which width is to be returned
-	 * @return the advance width of the specified char of the Font describing
-	 *         this FontMetricsImpl object
-	 */
-	@Override
-	public int charWidth(char ch) {
-		if (ch < 256) {
-			return widths[ch];
-		}
-		return (int) (getFontPeer().charWidth(ch) * scaleX);
-	}
-
-	/**
-	 * Returns the maximum advance of the Font describing this FontMetricsImpl
-	 * object.
-	 */
-	@Override
-	public int getMaxAdvance() {
-		return this.maxAdvance;
-	}
-
-	/**
-	 * Returns the maximum ascent of the Font describing this FontMetricsImpl
-	 * object.
-	 */
-	@Override
-	public int getMaxAscent() {
-		return this.maxAscent;
-	}
-
-	/**
-	 * Returns the maximum descent of the Font describing this FontMetricsImpl
-	 * object.
-	 */
-	@SuppressWarnings("deprecation")
-	@Deprecated
-	@Override
-	public int getMaxDecent() {
-		return this.maxDescent;
-	}
-
-	/**
-	 * Returns the maximum descent of the Font describing this FontMetricsImpl
-	 * object.
-	 */
-	@Override
-	public int getMaxDescent() {
-		return this.maxDescent;
-	}
-
-	/**
-	 * Returns the advance widths of the first 256 characters in the Font
-	 * describing this FontMetricsImpl object.
-	 */
-	@Override
-	public int[] getWidths() {
-		return this.widths;
-	}
-
-	/**
-	 * Returns the total advance width of the specified string in the metrics of
-	 * the Font describing this FontMetricsImpl object.
-	 * 
-	 * @param str
-	 *            the String which width is to be measured
-	 * @return the total advance width of the specified string in the metrics of
-	 *         the Font describing this FontMetricsImpl object
-	 */
-	@Override
-	public int stringWidth(String str) {
-
-		int width = 0;
-		char chr;
-
-		for (int i = 0; i < str.length(); i++) {
-			chr = str.charAt(i);
-			width += charWidth(chr);
-		}
-		return width;
-
-		/*
-		 * float res = 0; int ln = str.length(); char[] c = new char[ln]; float[] f =
-		 * new float[ln]; str.getChars(0, ln, c, 0); mSg.getPaint().getTextWidths(c, 0,
-		 * ln, f);
-		 * 
-		 * for(int i = 0; i < f.length; i++) { res += f[i]; } return (int)res;
-		 */
-	}
-
-	/**
-	 * Returns FontPeer implementation of the Font describing this
-	 * FontMetricsImpl object.
-	 * 
-	 * @return a FontPeer object, that is the platform dependent FontPeer
-	 *         implementation for the Font describing this FontMetricsImpl
-	 *         object.
-	 */
-	@SuppressWarnings("deprecation")
-	public FontPeerImpl getFontPeer() {
-		if (peer == null) {
-			peer = (FontPeerImpl) font.getPeer();
-		}
-		return peer;
-	}
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontPeerImpl.java b/awt/org/apache/harmony/awt/gl/font/FontPeerImpl.java
deleted file mode 100644
index 14ff997..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontPeerImpl.java
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.font;
-
-
-import com.android.internal.awt.AndroidGraphics2D;
-import com.android.internal.awt.AndroidGraphicsFactory;
-
-import java.awt.Graphics2D;
-import java.awt.Toolkit;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.awt.peer.FontPeer;
-
-import java.awt.font.FontRenderContext;
-import java.awt.font.LineMetrics;
-import java.util.ArrayList;
-import java.util.Locale;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-import android.graphics.Paint;
-
-/**
- * Abstract class for platform dependent peer implementation of the Font class.
- */
-public abstract class FontPeerImpl implements FontPeer{
-
-    // ascent of this font peer (in pixels)
-    int ascent;
-
-    // descent of this font peer (in pixels)
-    int descent;
-
-    // leading of this font peer (in pixels) 
-    int leading;
-
-    // logical maximum advance of this font peer (in pixels)
-    int maxAdvance;
-
-    // the height of this font peer
-    float height;
-
-    // the style of this font peer
-    int style;
-
-    // the point size of this font peer (in pixels)
-    int size;
-
-    // the logical hight of this font peer (in pixels)
-    int logicalHeight;
-
-    // the name of this font peer
-    String name;
-
-    // family name of this font peer
-    String fontFamilyName;
-
-    // the Face name of this font peer
-    String faceName;
-
-    // bounds rectanlge of the largest character in this font peer
-    Rectangle2D maxCharBounds;
-
-    // italic angle value of this font peer
-    float italicAngle = 0.0f;
-
-    // the number of glyphs supported by this font peer
-    int numGlyphs = 0;
-
-    // native font handle
-    long pFont;
-
-    // cached line metrics object
-    LineMetricsImpl nlm;
-
-    // the postscript name of this font peer
-    String psName = null;
-
-    /**
-     * Default glyph index, that is used, when the desired glyph
-     * is unsupported in this Font.
-     */
-    public char defaultChar = (char)0xFFFF;
-
-    /**
-     * Uniform LineMetrics flag, that is false for CompositeFont.  
-     * Default value is true.
-     */
-    boolean uniformLM = true;
-
-    /**
-     * Flag of the type of this Font that is indicate is the Font
-     * has TrueType or Type1 type. Default value is FONT_TYPE_UNDEF. 
-     */
-    int fontType = FontManager.FONT_TYPE_UNDEF;
-
-    /**
-     * Flag if this Font was created from stream, 
-     * this parameter used in finilize method.
-     */ 
-    private boolean createdFromStream = false;  
-    
-    // temorary Font file name, if this FontPeerImpl was created from InputStream 
-    private String tempFontFileName = null;     
-    
-    // cached FontExtraMetrics object related to this font peer
-    FontExtraMetrics extraMetrix = null;
-
-    public abstract FontExtraMetrics getExtraMetrics();
-    
-    /**
-     * Returns LineMetrics object with specified parameters
-     * @param str specified String
-     * @param frc specified render context
-     * @param at specified affine transform
-     * @return
-     */
-    public abstract LineMetrics getLineMetrics(String str, FontRenderContext frc, AffineTransform at);
-
-    /**
-     * Returns postscript name of the font.  
-     */
-    public abstract String getPSName();
-    
-	//private Graphics2D g = ((AndroidGraphicsFactory)Toolkit.getDefaultToolkit().getGraphicsFactory()).getGraphics2D();
-    //private Graphics2D g = AndroidGraphics2D.getInstance();
-
-    /**
-     * Set postscript name of the font to the specified parameter.  
-     */
-    public void setPSName(String name){
-        this.psName = name;
-    }
-    
-    /**
-     * Returns code of the missing glyph. 
-     */
-    public abstract int getMissingGlyphCode();
-
-    /**
-     * Returns Glyph representation of the given char.
-     * @param ch specified char
-     */
-    public abstract Glyph getGlyph(char ch);
-
-    /**
-     * Disposes nesessary resources.
-     */
-    public abstract void dispose();
-
-    /**
-     * Returns Glyph represeting missing char. 
-     */
-    public abstract Glyph getDefaultGlyph();
-
-    /**
-     * Returns true if this FontPeerImpl can display the specified char
-     */
-    public abstract boolean canDisplay(char c);
-
-    /**
-     * Returns family name of the font in specified locale settings.
-     * @param l specified Locale
-     */
-    public String getFamily(Locale l){
-        return this.getFamily();
-    }
-
-    /**
-     * Sets family name of the font in specified locale settings.
-     */
-    public void setFamily(String familyName){
-        this.fontFamilyName = familyName;
-    }
-
-    /**
-     * Returns face name of the font in specified locale settings.
-     * @param l specified Locale
-     */
-    public String getFontName(Locale l){
-        return this.getFontName();
-    }
-
-    /**
-     * Sets font name of the font in specified locale settings.
-     */
-    public void setFontName(String fontName){
-        this.faceName = fontName;
-    }
-
-    /**
-     * Returns true, if this font peer was created from InputStream, false otherwise.
-     * In case of creating fonts from InputStream some font peer implementations 
-     * may need to free temporary resources.
-     */
-    public boolean isCreatedFromStream(){
-        return this.createdFromStream;
-    }
-
-    /**
-     * Sets createdFromStream flag to the specified parameter.
-     * If parameter is true it means font peer was created from InputStream.
-     * 
-     * @param value true, if font peer was created from InputStream 
-     */
-    public void setCreatedFromStream(boolean value){
-        this.createdFromStream = value;
-    }
-
-    /**
-     * Returns font file name of this font.
-     */
-    public String getTempFontFileName(){
-        return this.tempFontFileName;
-    }
-
-    /**
-     * Sets font file name of this font to the specified one.
-     * @param value String representing font file name
-     */
-    public void setFontFileName(String value){
-        this.tempFontFileName = value;
-    }
-
-    /**
-     * Returns the advance width of the specified char of this FontPeerImpl.
-     * Note, if glyph is absent in the font's glyphset - returned value 
-     * is the advance of the deafualt glyph. For escape-chars returned 
-     * width value is 0.
-     * 
-     * @param ch the char which width is to be returned
-     * @return the advance width of the specified char of this FontPeerImpl
-     */
-    public int charWidth(char ch) {
-    	Paint p;
-    	AndroidGraphics2D g = AndroidGraphics2D.getInstance();
-    	if(g == null) {
-    		throw new RuntimeException("AndroidGraphics2D not instantiated!");
-    	}
-   		p = ((AndroidGraphics2D)g).getAndroidPaint();
-   		char[] ca = {ch};
-   		float[] fa = new float[1];
-   		p.getTextWidths(ca, 0, 1, fa);
-   		return (int)fa[0];
-    }
-
-    /**
-     * Returns the advance width of the specified char of this FontPeerImpl.
-     * 
-     * @param ind the char which width is to be returned
-     * @return the advance width of the specified char of this FontPeerImpl
-     */
-    public int charWidth(int ind) {
-        return charWidth((char)ind);
-    }
-
-    /**
-     * Returns an array of Glyphs that represent characters from the specified 
-     * Unicode range.
-     * 
-     * @param uFirst start position in Unicode range
-     * @param uLast end position in Unicode range
-     * @return
-     */
-    public Glyph[] getGlyphs(char uFirst, char uLast) {
-
-        char i = uFirst;
-        int len = uLast - uFirst;
-        ArrayList<Glyph> lst = new ArrayList<Glyph>(len);
-
-        if (size < 0) {
-            // awt.09=min range bound value is greater than max range bound
-            throw new IllegalArgumentException(Messages.getString("awt.09")); //$NON-NLS-1$
-        }
-
-        while (i < uLast) {
-            lst.add(this.getGlyph(i));
-        }
-
-        return (Glyph[]) lst.toArray();
-    }
-
-    /**
-     * Returns an array of Glyphs representing given array of chars.
-     * 
-     * @param chars specified array of chars
-     */
-    public Glyph[] getGlyphs(char[] chars) {
-        if (chars == null){
-            return null;
-        }
-
-        Glyph[] result = new Glyph[chars.length];
-
-        for (int i = 0; i < chars.length; i++) {
-            result[i] = this.getGlyph(chars[i]);
-        }
-        return result;
-    }
-
-    /**
-     * Returns an array of Glyphs representing given string.
-     * 
-     * @param str specified string
-     */
-    public Glyph[] getGlyphs(String str) {
-        char[] chars = str.toCharArray();
-        return this.getGlyphs(chars);
-    }
-
-    /**
-     * Returns family name of this FontPeerImpl.
-     */
-    public String getFamily() {
-        return fontFamilyName;
-    }
-
-    /**
-     * Returns face name of this FontPeerImpl.
-     */
-    public String getFontName() {
-        if (this.fontType == FontManager.FONT_TYPE_T1){
-            return this.fontFamilyName;
-        }
-
-        return faceName;
-    }
-
-    /**
-     * Returns height of this font peer in pixels. 
-     */
-    public int getLogicalHeight() {
-        return logicalHeight;
-    }
-
-    /**
-     * Sets height of this font peer in pixels to the given value.
-     * 
-     * @param newHeight new height in pixels value
-     */
-    public void setLogicalHeight(int newHeight) {
-        logicalHeight = newHeight;
-    }
-
-    /**
-     * Returns font size. 
-     */
-    public int getSize() {
-        return size;
-    }
-
-    /**
-     * Returns font style. 
-     */
-    public int getStyle() {
-        return style;
-    }
-
-    /**
-     * Returns font name. 
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Returns the bounds of the largest char in this FontPeerImpl in 
-     * specified render context.
-     * 
-     * @param frc specified FontRenderContext
-     */
-    public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
-        return maxCharBounds;
-    }
-
-    /**
-     * Returns the number of glyphs in this FontPeerImpl.
-     */
-    public int getNumGlyphs() {
-        return  numGlyphs;
-    }
-
-    /**
-     * Returns tangens of the italic angle of this FontPeerImpl.
-     * If the FontPeerImpl has TrueType font type, italic angle value can be 
-     * calculated as (CharSlopeRun / CharSlopeRise) in terms of GDI.
-     */
-    public float getItalicAngle() {
-        return italicAngle;
-    }
-
-    /**
-     * Returns height of this font peer. 
-     */
-    public float getHeight(){
-        return height;
-    }
-
-    /**
-     * Returns cached LineMetrics object of this font peer. 
-     */
-    public LineMetrics getLineMetrics(){
-        return nlm;
-    }
-
-    /**
-     * Returns native font handle of this font peer. 
-     */
-    public long getFontHandle(){
-        return pFont;
-    }
-
-    /**
-     * Returns ascent of this font peer. 
-     */
-    public int getAscent(){
-    	Paint p;
-    	AndroidGraphics2D g = AndroidGraphics2D.getInstance();
-    	if(g == null) {
-    		throw new RuntimeException("AndroidGraphics2D not instantiated!");
-    	}
-   		p = ((AndroidGraphics2D)g).getAndroidPaint();
-   		return (int)p.ascent();
-        //return ascent;
-    }
-
-    /**
-     * Returns descent of this font peer. 
-     */
-    public int getDescent(){
-        return descent;
-    }
-
-    /**
-     * Returns leading of this font peer. 
-     */
-    public int getLeading(){
-        return leading;
-    }
-
-    /**
-     * Returns true if this font peer has uniform line metrics. 
-     */
-    public boolean hasUniformLineMetrics(){
-        return uniformLM;
-    }
-
-    /**
-     * Returns type of this font.
-     *  
-     * @return one of constant font type values. 
-     */    
-    public int getFontType(){
-        return fontType;
-    }
-
-    /**
-     * Sets new font type to the font object.
-     * 
-     * @param newType new type value
-     */
-    public void setFontType(int newType){
-        if (newType == FontManager.FONT_TYPE_T1 || newType == FontManager.FONT_TYPE_TT){
-            fontType = newType;
-        }
-    }
-
-    /**
-     * Sets new font type to the font object.
-     * 
-     * @param newType new type value
-     */
-    @Override
-    protected void finalize() throws Throwable {
-      super.finalize();
-      
-      dispose();
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontProperty.java b/awt/org/apache/harmony/awt/gl/font/FontProperty.java
deleted file mode 100644
index 4eb7cbb..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontProperty.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-
-package org.apache.harmony.awt.gl.font;
-
-
-/**
- * Class containing font property information. This information can be found 
- * in font.property files. See API documentation, logical fonts description part. 
- *
- */
-public class FontProperty {
-
-    // font file name 
-    String fileName = null;
-    
-    // name of the encoding to be used 
-    String encoding = null;
-    
-    // array of exclusion ranges (pairs of low and high unicode exclusion bounds)
-    int[] exclRange = null;
-    
-    // font face name
-    String name = null;
-    
-    // font style
-    int style = -1;
-
-    /**
-     * Returns font style of this font property. 
-     */
-    public int getStyle(){
-        return this.style;
-    }
-
-    /**
-     * Returns font name of this font property. 
-     */
-    public String getName(){
-        return this.name;
-    }
-
-    /**
-     * Returns encoding used in this font property. 
-     */
-    public String getEncoding(){
-        return this.encoding;
-    }
-    
-    /**
-     * Returns an array of exclusion ranges. This array contain pairs of 
-     * low and high bounds of the intervals of characters to ignore in 
-     * total Unicode characters range.   
-     */
-    public int[] getExclusionRange(){
-        return this.exclRange;
-    }
-
-    /**
-     * Returns file name of the font that is described by this font property. 
-     */
-    public String getFileName(){
-        return this.fileName;
-    }
-
-    /**
-     * Returns true if specified character covered by exclusion ranges of this 
-     * font property, false otherwise.
-     * 
-     * @param ch specified char to check
-     */
-    public boolean isCharExcluded(char ch){
-        if (exclRange == null ){
-            return false;
-        }
-
-        for (int i = 0; i < exclRange.length;){
-            int lb = exclRange[i++];
-            int hb = exclRange[i++];
-
-            if (ch >= lb && ch <= hb){
-                return true;
-            }
-        }
-
-        return false;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/Glyph.java b/awt/org/apache/harmony/awt/gl/font/Glyph.java
deleted file mode 100644
index 44b8809..0000000
--- a/awt/org/apache/harmony/awt/gl/font/Glyph.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.Shape;
-import java.awt.font.GlyphJustificationInfo;
-import java.awt.font.GlyphMetrics;
-import java.awt.image.BufferedImage;
-
-public abstract class Glyph{
-
-    // character of the glyph
-    char glChar;
-    
-    // precise glyph metrics
-    GlyphMetrics glMetrics;
-    
-    // glyph metrics in pixels
-    GlyphMetrics glPointMetrics;
-    
-    //  glyph code of this Glyph
-    int glCode;
-    
-    // justification info of this glyph
-    GlyphJustificationInfo glJustInfo;
-    
-    // native font handle of the font corresponding to this glyph
-    long pFont;
-    
-    // size of the font corresponding to this glyph
-    int fontSize;
-    
-    // bitmap representation of the glyph
-    byte[] bitmap = null;
-    
-    // Buffered image representation of the glyph
-    BufferedImage image;
-    
-    // shape that representing the outline of this glyph
-    Shape glOutline = null;
-
-    /**
-     * image bitmap parameters
-     */
-    
-    //  top side bearing
-    public int bmp_top = 0;
-    
-    // left side bearing
-    public int bmp_left = 0;
-
-    // number of bytes in row
-    public int bmp_pitch;
-    
-    // number of rows
-    public int bmp_rows;
-    
-    // width of the row
-    public int bmp_width;
-
-    /**
-     *  Retruns handle to Native Font object
-     */
-    public long getPFont(){
-        return this.pFont;
-    }
-
-    /**
-     *  Retruns char value of this glyph object
-     */
-    public char getChar(){
-        return glChar;
-    }
-
-    /**
-     *  Retruns precise width of this glyph object
-     */
-    public int getWidth(){
-        return Math.round((float)glMetrics.getBounds2D().getWidth());
-    }
-
-    /**
-     *  Retruns precise height of this glyph object
-     */
-    public int getHeight(){
-        return Math.round((float)glMetrics.getBounds2D().getHeight());
-    }
-
-    /**
-     *  Retruns glyph code of this glyph object
-     */
-    public int getGlyphCode(){
-        return glCode;
-    }
-
-    /**
-     *  Retruns GlyphMetrics of this glyph object with precise metrics.
-     */
-    public GlyphMetrics getGlyphMetrics(){
-        return glMetrics;
-    }
-
-    /**
-     *  Retruns GlyphMetrics of this glyph object in pixels.
-     */
-    public GlyphMetrics getGlyphPointMetrics(){
-        return glPointMetrics;
-    }
-
-    /**
-     *  Retruns GlyphJustificationInfo of this glyph object
-     */
-    public GlyphJustificationInfo getGlyphJustificationInfo(){
-        return glJustInfo;
-    }
-
-    /**
-     *  Sets JustificationInfo of this glyph object
-     * 
-     * @param newJustInfo GlyphJustificationInfo object to set to the Glyph object 
-     */
-    public void setGlyphJustificationInfo(GlyphJustificationInfo newJustInfo){
-        this.glJustInfo = newJustInfo;
-    }
-
-    /**
-     * Returns an int array of 3 elements, so-called ABC structure that contains 
-     * the width of the character:
-     * 1st element = left side bearing of the glyph
-     * 2nd element = width of the glyph
-     * 3d element = right side bearing of the glyph 
-     */
-    public int[] getABC(){
-        int[] abc = new int[3];
-        abc[0] = (int)glMetrics.getLSB();
-        abc[1] = (int)glMetrics.getBounds2D().getWidth();
-        abc[2] = (int)glMetrics.getRSB();
-
-        return abc;
-    }
-
-    /**
-     * Sets BufferedImage representation of this glyph to the specified parameter.
-     * 
-     * @param newImage new BufferedImage object to be set as BufferedImage 
-     * representation.
-     */
-    public void setImage(BufferedImage newImage){
-        this.image = newImage;
-    }
-
-    /**
-     * Returns true if this Glyph and specified object are equal.
-     */
-    @Override
-    public boolean equals(Object obj){
-         if (obj == this) {
-            return true;
-        }
-
-        if (obj != null) {
-          try {
-            Glyph gl = (Glyph)obj;
-
-            return  ((this.getChar() == gl.getChar())
-              && (this.getGlyphMetrics().equals(gl.getGlyphMetrics()))
-              && (this.getGlyphCode() == gl.getGlyphCode()));
-          } catch (ClassCastException e) {
-          }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns height of the glyph in points. 
-     */
-    public int getPointHeight(){
-        return (int)glPointMetrics.getBounds2D().getHeight();
-    }
-
-    /**
-     * Returns width of the glyph in points. 
-     */
-    public int getPointWidth(){
-        return (int)glPointMetrics.getBounds2D().getWidth();
-    }
-
-    public Shape getShape(){
-        if (glOutline == null){
-            glOutline = initOutline(this.glChar);
-        }
-        return glOutline;
-    }
-
-    /**
-     * Sets BufferedImage representation of this glyph.
-     */
-    public BufferedImage getImage(){
-        //!! Implementation classes must override this method
-        return null;
-    }
-
-    /**
-     *  Returns array of bytes, representing image of this glyph
-     */
-    public abstract byte[] getBitmap();
-
-    /**
-     * Returns shape that represents outline of the specified character. 
-     * 
-     * @param c specified character
-     */
-    public abstract Shape initOutline(char c);
-
-}
-
-
diff --git a/awt/org/apache/harmony/awt/gl/font/LineMetricsImpl.java b/awt/org/apache/harmony/awt/gl/font/LineMetricsImpl.java
deleted file mode 100644
index 370146d..0000000
--- a/awt/org/apache/harmony/awt/gl/font/LineMetricsImpl.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.font.LineMetrics;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- *
- * LineMetrics implementation class.
- */
-
-public class LineMetricsImpl extends LineMetrics implements Cloneable{
-
-    // array of baseline offsets
-    float[] baselineOffsets;
-
-    // the number of characters to measure
-    int numChars;
-
-    // baseline index of the font corresponding to this line metrics
-    int baseLineIndex;
-
-    // underline thickness
-    float underlineThickness;
-
-    // underline offset
-    float underlineOffset;
-
-    // strikethrough thickness
-    float strikethroughThickness;
-
-    // strikethrough offset
-    float strikethroughOffset;
-
-    // External leading
-    float leading;
-
-    // Height of the font ( == (ascent+descent+leading))
-    float height;
-
-    // Ascent of the font
-    float ascent;
-
-    // Descent of the font
-    float descent;
-
-    // Width of the widest char in the font
-    float maxCharWidth;
-
-    // underline thickness (in pixels)
-    int lUnderlineThickness;
-
-    // underline offset (in pixels)
-    int lUnderlineOffset;
-
-    // strikethrough thickness (in pixels)
-    int lStrikethroughThickness;
-
-    // strikethrough offset (in pixels)
-    int lStrikethroughOffset;
-
-    // External leading (in pixels)
-    int lLeading;
-
-    // Height of the font ( == (ascent+descent+leading)) (in pixels)
-    int lHeight;
-
-    // Ascent of the font (in pixels)
-    int lAscent;
-    
-    // Descent of the font (in pixels)
-    int lDescent;
-
-    //  Width of the widest char in the font (in pixels)
-    int lMaxCharWidth;
-
-    // units per EM square in font value
-    int units_per_EM = 0;
-
-    /**
-     * Creates LineMetricsImpl object from specified parameters. If baseline data parameter
-     * is null than {0, (-ascent+descent)/2, -ascent} values are used for baseline offsets.
-     *  
-     * @param len a number of characters 
-     * @param metrics an array of 16 elements with metrics values that can be 
-     * initialized in native code.<p>
-     * metrics[0] - ascent<p>
-     * metrics[1] - descent<p>
-     * metrics[2] - external leading<p>
-     * metrics[3] - underline thickness<p>
-     * -metrics[4] - underline offset<p>
-     * metrics[5] - strikethrough thickness<p>
-     * -metrics[6] - strikethrough offset<p>
-     * metrics[7] - maximum char width<p>
-     * metrics[8] - ascent in pixels<p>
-     * metrics[9] - descent in pixles<p>
-     * metrics[10] - external leading in pixels<p>
-     * metrics[11] - underline thickness in pixels<p>
-     * -metrics[12] - underline offset in pixels<p>
-     * metrics[13] - strikethrough thickness in pixels<p>
-     * -metrics[14] - strikethrough offset in pixels<p>
-     * metrics[15] - maximum char width in pixels<p>
-
-     * @param _baselineData an array of 3 elements with baseline offsets metrics<p>
-     * _baselineData[0] - roman baseline offset<p> 
-     * _baselineData[1] - center baseline offset<p>
-     * _baselineData[2] - hanging baseline offset<p>
-     */
-    public LineMetricsImpl(int len, float[] metrics, float[] _baselineData){
-        numChars = len;
-
-        ascent = metrics[0];    // Ascent of the font
-        descent = metrics[1];   // Descent of the font
-        leading = metrics[2];  // External leading
-        height = metrics[0] + metrics[1] + metrics[2];  // Height of the font ( == (ascent + descent + leading))
-    }
-
-    /**
-     * Creates LineMetricsImpl object from specified parameters. If baseline data parameter
-     * is null than {0, (-ascent+descent)/2, -ascent} values are used for baseline offsets.
-     *  
-     * @param _numChars number of chars 
-     * @param _baseLineIndex index of the baseline offset
-     * @param _baselineOffsets an array of baseline offsets
-     * @param _underlineThickness underline thickness
-     * @param _underlineOffset underline offset
-     * @param _strikethroughThickness strikethrough thickness
-     * @param _strikethroughOffset strinkethrough offset
-     * @param _leading leading of the font
-     * @param _height font height
-     * @param _ascent ascent of the font
-     * @param _descent descent of the font
-     * @param _maxCharWidth max char width
-     */
-    public LineMetricsImpl(int _numChars, int _baseLineIndex,
-            float[] _baselineOffsets, float _underlineThickness,
-            float _underlineOffset, float _strikethroughThickness,
-            float _strikethroughOffset, float _leading, float _height,
-            float _ascent, float _descent, float _maxCharWidth) {
-
-        numChars = _numChars;
-        baseLineIndex = _baseLineIndex;
-        underlineThickness = _underlineThickness;
-        underlineOffset = _underlineOffset;
-        strikethroughThickness = _strikethroughThickness;
-        strikethroughOffset = _strikethroughOffset;
-        leading = _leading;
-        height = _height;
-        ascent = _ascent;
-        descent = _descent;
-        baselineOffsets = _baselineOffsets;
-        lUnderlineThickness = (int) underlineThickness;
-        lUnderlineOffset = (int) underlineOffset;
-        lStrikethroughThickness = (int) strikethroughThickness;
-        lStrikethroughOffset = (int) strikethroughOffset;
-        lLeading = (int) leading;
-        lHeight = (int) height;
-        lAscent = (int) ascent;
-        lDescent = (int) descent;
-        maxCharWidth = _maxCharWidth;
-    }
-
-    public LineMetricsImpl(){
-
-    }
-
-    /**
-     * All metrics are scaled according to scaleX and scaleY values. 
-     * This function helps to recompute metrics according to the scale factors
-     * of desired AffineTransform.
-     * 
-     * @param scaleX scale X factor
-     * @param scaleY scale Y factor
-     */
-    public void scale(float scaleX, float scaleY){
-        float absScaleX = Math.abs(scaleX);
-        float absScaleY = Math.abs(scaleY);
-
-        underlineThickness *= absScaleY;
-        underlineOffset *= scaleY;
-        strikethroughThickness *= absScaleY;
-        strikethroughOffset *= scaleY;
-        leading *= absScaleY;
-        height *= absScaleY;
-        ascent *= absScaleY;
-        descent *= absScaleY;
-
-        if(baselineOffsets == null) {
-            getBaselineOffsets();
-        }
-
-        for (int i=0; i< baselineOffsets.length; i++){
-            baselineOffsets[i] *= scaleY;
-        }
-
-        lUnderlineThickness *= absScaleY;
-        lUnderlineOffset *= scaleY;
-        lStrikethroughThickness *= absScaleY;
-        lStrikethroughOffset *= scaleY;
-        lLeading  *= absScaleY;
-        lHeight *= absScaleY;
-        lAscent *= absScaleY;
-        lDescent *= absScaleY;
-        maxCharWidth *= absScaleX;
-
-    }
-
-
-    /**
-     * Returns offset of the baseline.
-     */
-    @Override
-    public float[] getBaselineOffsets() {
-        // XXX: at the moment there only horizontal metrics are taken into
-        // account. If there is no baseline information in TrueType font
-        // file default values used: {0, -ascent, (-ascent+descent)/2}
-
-        return baselineOffsets;
-    }
-
-    /**
-     * Returns a number of chars in specified text
-     */
-    @Override
-    public int getNumChars() {
-        return numChars;
-    }
-
-    /**
-     * Returns index of the baseline, one of predefined constants.
-     */
-    @Override
-    public int getBaselineIndex() {
-        // Baseline index is the deafult baseline index value
-        // taken from the TrueType table "BASE".
-        return baseLineIndex;
-    }
-
-    /**
-     * Returns thickness of the Underline.
-     */
-    @Override
-    public float getUnderlineThickness() {
-        return underlineThickness;
-    }
-
-    /**
-     * Returns offset of the Underline.
-     */
-    @Override
-    public float getUnderlineOffset() {
-        return underlineOffset;
-    }
-
-    /**
-     * Returns thickness of the Strikethrough line.
-     */
-    @Override
-    public float getStrikethroughThickness() {
-        return strikethroughThickness;
-    }
-
-    /**
-     * Returns offset of the Strikethrough line.
-     */
-    @Override
-    public float getStrikethroughOffset() {
-        return strikethroughOffset;
-    }
-
-    /**
-     * Returns the leading.
-     */
-    @Override
-    public float getLeading() {
-        return leading;
-    }
-
-    /**
-     * Returns the height of the font.
-     */
-    @Override
-    public float getHeight() {
-        //return height; // equals to (ascent + descent + leading);
-    	return ascent + descent + leading;
-    }
-
-    /**
-     * Returns the descent.
-     */
-    @Override
-    public float getDescent() {
-        return descent;
-    }
-
-    /**
-     * Returns the ascent.
-     */
-    @Override
-    public float getAscent() {
-        return ascent;
-    }
-
-    /**
-     * Returns logical thickness of the Underline.
-     */
-    public int getLogicalUnderlineThickness() {
-        return lUnderlineThickness;
-    }
-
-    /**
-     * Returns logical offset of the Underline.
-     */
-    public int getLogicalUnderlineOffset() {
-        return lUnderlineOffset;
-    }
-
-    /**
-     * Returns logical thickness of the Strikethrough line.
-     */
-    public int getLogicalStrikethroughThickness() {
-        return lStrikethroughThickness;
-    }
-
-    /**
-     * Returns logical offset of the Strikethrough line.
-     */
-    public int getLogicalStrikethroughOffset() {
-        return lStrikethroughOffset;
-    }
-
-    /**
-     * Returns the logical leading.
-     */
-    public int getLogicalLeading() {
-        return lLeading;
-    }
-
-    /**
-     * Returns the logical height of the font.
-     */
-    public int getLogicalHeight() {
-        return lHeight; // equals to (ascent + descent + leading);
-    }
-
-    /**
-     * Returns the logical descent.
-     */
-    public int getLogicalDescent() {
-        return lDescent;
-    }
-
-    /**
-     * Returns the logical ascent.
-     */
-    public int getLogicalAscent() {
-        return lAscent;
-    }
-
-    /**
-     * Returns the logical size of the widest char.
-     */
-    public int getLogicalMaxCharWidth() {
-        return lMaxCharWidth;
-    }
-
-    /**
-     * Returns the size of the widest char.
-     */
-    public float getMaxCharWidth() {
-        return maxCharWidth;
-    }
-
-    /**
-     * Set num chars to the desired value.
-     * 
-     * @param num specified number of chars
-     */
-    public void setNumChars(int num){
-        numChars = num;
-    }
-
-    @Override
-    public Object clone(){
-        try{
-            return super.clone();
-        }catch (CloneNotSupportedException e){
-            return null;
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/font/TextDecorator.java b/awt/org/apache/harmony/awt/gl/font/TextDecorator.java
deleted file mode 100644
index 81905fd..0000000
--- a/awt/org/apache/harmony/awt/gl/font/TextDecorator.java
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/*
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Paint;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.font.TextAttribute;
-import java.awt.geom.Area;
-import java.awt.geom.Line2D;
-import java.awt.geom.Rectangle2D;
-import java.text.AttributedCharacterIterator.Attribute;
-import java.util.Map;
-
-/**
- * This class is responsible for rendering text decorations like
- * underline, strikethrough, text with background, etc.
- */
-public class TextDecorator {
-    private static final TextDecorator inst = new TextDecorator();
-    private TextDecorator() {}
-    static TextDecorator getInstance() {
-        return inst;
-    }
-
-    /**
-     * This class encapsulates a set of decoration attributes for a single text run.
-     */
-    static class Decoration {
-        private static final BasicStroke UNDERLINE_LOW_ONE_PIXEL_STROKE =
-                new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10);
-
-        private static final BasicStroke UNDERLINE_LOW_TWO_PIXEL_STROKE =
-                new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10);
-
-        private static final BasicStroke UNDERLINE_LOW_DOTTED_STROKE =
-                new BasicStroke(
-                        1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
-                        new float[] { 1, 1 }, 0
-                );
-
-        private static final BasicStroke UNDERLINE_LOW_DOTTED_STROKE2 =
-                new BasicStroke(
-                        1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
-                        new float[] { 1, 1 }, 1
-                );
-
-        private static final BasicStroke UNDERLINE_LOW_DASHED_STROKE =
-                new BasicStroke(
-                        1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
-                        new float[] { 4, 4 }, 0
-                );
-
-        boolean ulOn = false; // Have standard underline?
-        BasicStroke ulStroke;
-
-        BasicStroke imUlStroke;  // Stroke for INPUT_METHOD_UNDERLINE
-        BasicStroke imUlStroke2; // Specially for UNDERLINE_LOW_GRAY
-
-        boolean strikeThrough;
-        BasicStroke strikeThroughStroke;
-
-        boolean haveStrokes = false; // Strokes already created?
-
-        boolean swapBfFg;
-        Paint bg; // background color
-        Paint fg; // foreground color
-
-        Paint graphicsPaint; // Slot for saving current paint
-
-        Decoration(
-                Integer imUl,
-                boolean swap,
-                boolean sth,
-                Paint bg, Paint fg,
-                boolean ulOn) {
-
-            if (imUl != null) {
-                // Determine which stroke to use
-                if (imUl == TextAttribute.UNDERLINE_LOW_ONE_PIXEL) {
-                    this.imUlStroke = Decoration.UNDERLINE_LOW_ONE_PIXEL_STROKE;
-                } else if (imUl == TextAttribute.UNDERLINE_LOW_TWO_PIXEL) {
-                    this.imUlStroke = Decoration.UNDERLINE_LOW_TWO_PIXEL_STROKE;
-                } else if (imUl == TextAttribute.UNDERLINE_LOW_DOTTED) {
-                    this.imUlStroke = Decoration.UNDERLINE_LOW_DOTTED_STROKE;
-                } else if (imUl == TextAttribute.UNDERLINE_LOW_GRAY) {
-                    this.imUlStroke = Decoration.UNDERLINE_LOW_DOTTED_STROKE;
-                    this.imUlStroke2 = Decoration.UNDERLINE_LOW_DOTTED_STROKE2;
-                } else if (imUl == TextAttribute.UNDERLINE_LOW_DASHED) {
-                    this.imUlStroke = Decoration.UNDERLINE_LOW_DASHED_STROKE;
-                }
-            }
-
-            this.ulOn = ulOn; // Has underline
-            this.swapBfFg = swap;
-            this.strikeThrough = sth;
-            this.bg = bg;
-            this.fg = fg;
-        }
-
-        /**
-         * Creates strokes of proper width according to the info
-         * stored in the BasicMetrics
-         * @param metrics - basic metrics
-         */
-        private void getStrokes(BasicMetrics metrics) {
-            if (!haveStrokes) {
-                if (strikeThrough) {
-                    strikeThroughStroke =
-                            new BasicStroke(
-                                    metrics.strikethroughThickness,
-                                    BasicStroke.CAP_BUTT,
-                                    BasicStroke.JOIN_MITER,
-                                    10
-                            );
-                }
-
-                if (ulOn) {
-                    ulStroke =
-                            new BasicStroke(
-                                    metrics.underlineThickness,
-                                    BasicStroke.CAP_BUTT,
-                                    BasicStroke.JOIN_MITER,
-                                    10
-                            );
-                }
-
-                haveStrokes = true;
-            }
-        }
-    }
-
-    /**
-     * Creates Decoration object from the set of text attributes
-     * @param attributes - text attributes
-     * @return Decoration object
-     */
-    static Decoration getDecoration(Map<? extends Attribute, ?> attributes) {
-        if (attributes == null) {
-            return null; // It is for plain text
-        }
-
-        Object underline = attributes.get(TextAttribute.UNDERLINE);
-        boolean hasStandardUnderline = underline == TextAttribute.UNDERLINE_ON;
-
-        Object imUnderline = attributes.get(TextAttribute.INPUT_METHOD_UNDERLINE);
-        Integer imUl = (Integer) imUnderline;
-
-        boolean swapBgFg =
-                TextAttribute.SWAP_COLORS_ON.equals(
-                        attributes.get(TextAttribute.SWAP_COLORS)
-                );
-
-        boolean strikeThrough =
-                TextAttribute.STRIKETHROUGH_ON.equals(
-                        attributes.get(TextAttribute.STRIKETHROUGH)
-                );
-
-        Paint fg = (Paint) attributes.get(TextAttribute.FOREGROUND);
-        Paint bg = (Paint) attributes.get(TextAttribute.BACKGROUND);
-
-        if (
-                !hasStandardUnderline &&
-                imUnderline == null &&
-                fg == null &&
-                bg == null &&
-                !swapBgFg &&
-                !strikeThrough
-        ) {
-            return null;
-        }
-        return new Decoration(imUl, swapBgFg, strikeThrough, bg, fg, hasStandardUnderline);
-    }
-
-    /**
-     * Fills the background before drawing if needed.
-     * 
-     * @param trs - text segment
-     * @param g2d - graphics to draw to
-     * @param xOffset - offset in X direction to the upper left corner of the
-     *        layout from the origin of the graphics
-     * @param yOffset - offset in Y direction to the upper left corner of the
-     *        layout from the origin of the graphics
-     */
-    static void prepareGraphics(
-            TextRunSegment trs, Graphics2D g2d,
-            float xOffset, float yOffset
-    ) {
-        Decoration d = trs.decoration;
-
-        if (d.fg == null && d.bg == null && d.swapBfFg == false) {
-            return; // Nothing to do
-        }
-
-        d.graphicsPaint = g2d.getPaint();
-
-        if (d.fg == null) {
-            d.fg = d.graphicsPaint;
-        }
-
-        if (d.swapBfFg) {
-            // Fill background area
-            g2d.setPaint(d.fg);
-            Rectangle2D bgArea = trs.getLogicalBounds();
-            Rectangle2D toFill =
-                    new Rectangle2D.Double(
-                            bgArea.getX() + xOffset,
-                            bgArea.getY() + yOffset,
-                            bgArea.getWidth(),
-                            bgArea.getHeight()
-                    );
-            g2d.fill(toFill);
-
-            // Set foreground color
-            g2d.setPaint(d.bg == null ? Color.WHITE : d.bg);
-        } else {
-            if (d.bg != null) { // Fill background area
-                g2d.setPaint(d.bg);
-                Rectangle2D bgArea = trs.getLogicalBounds();
-                Rectangle2D toFill =
-                        new Rectangle2D.Double(
-                                bgArea.getX() + xOffset,
-                                bgArea.getY() + yOffset,
-                                bgArea.getWidth(),
-                                bgArea.getHeight()
-                        );
-                g2d.fill(toFill);
-            }
-
-            // Set foreground color
-            g2d.setPaint(d.fg);
-        }
-    }
-
-    /**
-     * Restores the original state of the graphics if needed
-     * @param d - decoration
-     * @param g2d - graphics
-     */
-    static void restoreGraphics(Decoration d, Graphics2D g2d) {
-        if (d.fg == null && d.bg == null && d.swapBfFg == false) {
-            return; // Nothing to do
-        }
-
-        g2d.setPaint(d.graphicsPaint);
-    }
-
-    /**
-     * Renders the text decorations
-     * @param trs - text run segment
-     * @param g2d - graphics to render to
-     * @param xOffset - offset in X direction to the upper left corner
-     * of the layout from the origin of the graphics
-     * @param yOffset - offset in Y direction to the upper left corner
-     * of the layout from the origin of the graphics
-     */
-    static void drawTextDecorations(
-            TextRunSegment trs, Graphics2D g2d,
-            float xOffset, float yOffset
-    ) {
-        Decoration d = trs.decoration;
-
-        if (!d.ulOn && d.imUlStroke == null && !d.strikeThrough) {
-            return; // Nothing to do
-        }
-
-        float left = xOffset + (float) trs.getLogicalBounds().getMinX();
-        float right = xOffset + (float) trs.getLogicalBounds().getMaxX();
-
-        Stroke savedStroke = g2d.getStroke();
-
-        d.getStrokes(trs.metrics);
-
-        if (d.strikeThrough) {
-            float y = trs.y + yOffset + trs.metrics.strikethroughOffset;
-            g2d.setStroke(d.strikeThroughStroke);
-            g2d.draw(new Line2D.Float(left, y, right, y));
-        }
-
-        if (d.ulOn) {
-            float y = trs.y + yOffset + trs.metrics.underlineOffset;
-            g2d.setStroke(d.ulStroke);
-            g2d.draw(new Line2D.Float(left, y, right, y));
-        }
-
-        if (d.imUlStroke != null) {
-            float y = trs.y + yOffset + trs.metrics.underlineOffset;
-            g2d.setStroke(d.imUlStroke);
-            g2d.draw(new Line2D.Float(left, y, right, y));
-            if (d.imUlStroke2 != null) {
-                y++;
-                g2d.setStroke(d.imUlStroke2);
-                g2d.draw(new Line2D.Float(left, y, right, y));
-            }
-        }
-
-        g2d.setStroke(savedStroke);
-    }
-
-    /**
-     * Extends the visual bounds of the text run segment to
-     * include text decorations.
-     * @param trs - text segment
-     * @param segmentBounds - bounds of the undecorated text
-     * @param d - decoration
-     * @return extended bounds
-     */
-    static Rectangle2D extendVisualBounds(
-            TextRunSegment trs,
-            Rectangle2D segmentBounds,
-            Decoration d
-    ) {
-        if (d == null) {
-            return segmentBounds;
-        }
-        double minx = segmentBounds.getMinX();
-        double miny = segmentBounds.getMinY();
-        double maxx = segmentBounds.getMaxX();
-        double maxy = segmentBounds.getMaxY();
-
-        Rectangle2D lb = trs.getLogicalBounds();
-
-        if (d.swapBfFg || d.bg != null) {
-            minx = Math.min(lb.getMinX() - trs.x, minx);
-            miny = Math.min(lb.getMinY() - trs.y, miny);
-            maxx = Math.max(lb.getMaxX() - trs.x, maxx);
-            maxy = Math.max(lb.getMaxY() - trs.y, maxy);
-        }
-
-        if (d.ulOn || d.imUlStroke != null || d.strikeThrough) {
-            minx = Math.min(lb.getMinX() - trs.x, minx);
-            maxx = Math.max(lb.getMaxX() - trs.x, maxx);
-
-            d.getStrokes(trs.metrics);
-
-            if (d.ulStroke != null) {
-                maxy = Math.max(
-                        maxy,
-                        trs.metrics.underlineOffset +
-                        d.ulStroke.getLineWidth()
-                );
-            }
-
-            if (d.imUlStroke != null) {
-                maxy = Math.max(
-                        maxy,
-                        trs.metrics.underlineOffset +
-                        d.imUlStroke.getLineWidth() +
-                        (d.imUlStroke2 == null ? 0 : d.imUlStroke2.getLineWidth())
-                );
-            }
-        }
-
-        return new Rectangle2D.Double(minx, miny, maxx-minx, maxy-miny);
-    }
-
-    /**
-     * Extends the outline of the text run segment to
-     * include text decorations.
-     * @param trs - text segment
-     * @param segmentOutline - outline of the undecorated text
-     * @param d - decoration
-     * @return extended outline
-     */
-    static Shape extendOutline(
-            TextRunSegment trs,
-            Shape segmentOutline,
-            Decoration d
-    ) {
-        if (d == null || !d.ulOn && d.imUlStroke == null && !d.strikeThrough) {
-            return segmentOutline; // Nothing to do
-        }
-
-        Area res = new Area(segmentOutline);
-
-        float left = (float) trs.getLogicalBounds().getMinX() - trs.x;
-        float right = (float) trs.getLogicalBounds().getMaxX() - trs.x;
-
-        d.getStrokes(trs.metrics);
-
-        if (d.strikeThrough) {
-            float y = trs.metrics.strikethroughOffset;
-            res.add(new Area(d.strikeThroughStroke.createStrokedShape(
-                    new Line2D.Float(left, y, right, y)
-            )));
-        }
-
-        if (d.ulOn) {
-            float y = trs.metrics.underlineOffset;
-            res.add(new Area(d.ulStroke.createStrokedShape(
-                    new Line2D.Float(left, y, right, y)
-            )));
-        }
-
-        if (d.imUlStroke != null) {
-            float y = trs.metrics.underlineOffset;
-            res.add(new Area(d.imUlStroke.createStrokedShape(
-                    new Line2D.Float(left, y, right, y)
-            )));
-
-            if (d.imUlStroke2 != null) {
-                y++;
-                res.add(new Area(d.imUlStroke2.createStrokedShape(
-                        new Line2D.Float(left, y, right, y)
-                )));
-            }
-        }
-
-        return res;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextMetricsCalculator.java b/awt/org/apache/harmony/awt/gl/font/TextMetricsCalculator.java
deleted file mode 100644
index be5762a..0000000
--- a/awt/org/apache/harmony/awt/gl/font/TextMetricsCalculator.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- */
-
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.font.LineMetrics;
-import java.awt.font.GraphicAttribute;
-import java.awt.Font;
-import java.util.HashMap;
-import java.util.ArrayList;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * This class operates with an arbitrary text string which can include
- * any number of style, font and direction runs. It is responsible for computation
- * of the text metrics, such as ascent, descent, leading and advance. Actually,
- * each text run segment contains logic which allows it to compute its own metrics and
- * responsibility of this class is to combine metrics for all segments included in the text,
- * managed by the associated TextRunBreaker object.
- */
-public class TextMetricsCalculator {
-    TextRunBreaker breaker; // Associated run breaker
-
-    // Metrics
-    float ascent = 0;
-    float descent = 0;
-    float leading = 0;
-    float advance = 0;
-
-    private float baselineOffsets[];
-    int baselineIndex;
-
-    public TextMetricsCalculator(TextRunBreaker breaker) {
-        this.breaker = breaker;
-        checkBaselines();
-    }
-
-    /**
-     * Returns either values cached by checkBaselines method or reasonable
-     * values for the TOP and BOTTOM alignments.
-     * @param baselineIndex - baseline index
-     * @return baseline offset
-     */
-    float getBaselineOffset(int baselineIndex) {
-        if (baselineIndex >= 0) {
-            return baselineOffsets[baselineIndex];
-        } else if (baselineIndex == GraphicAttribute.BOTTOM_ALIGNMENT) {
-            return descent;
-        } else if (baselineIndex == GraphicAttribute.TOP_ALIGNMENT) {
-            return -ascent;
-        } else {
-            // awt.3F=Invalid baseline index
-            throw new IllegalArgumentException(Messages.getString("awt.3F")); //$NON-NLS-1$
-        }
-    }
-
-    public float[] getBaselineOffsets() {
-        float ret[] = new float[baselineOffsets.length];
-        System.arraycopy(baselineOffsets, 0, ret, 0, baselineOffsets.length);
-        return ret;
-    }
-
-    /**
-     * Take baseline offsets from the first font or graphic attribute
-     * and normalizes them, than caches the results.
-     */
-    public void checkBaselines() {
-        // Take baseline offsets of the first font and normalize them
-        HashMap<Integer, Font> fonts = breaker.fonts;
-
-        Object val = fonts.get(new Integer(0));
-
-        if (val instanceof Font) {
-            Font firstFont = (Font) val;
-            LineMetrics lm = firstFont.getLineMetrics(breaker.text, 0, 1, breaker.frc);
-            baselineOffsets = lm.getBaselineOffsets();
-            baselineIndex = lm.getBaselineIndex();
-        } else if (val instanceof GraphicAttribute) {
-            // Get first graphic attribute and use it
-            GraphicAttribute ga = (GraphicAttribute) val;
-
-            int align = ga.getAlignment();
-
-            if (
-                    align == GraphicAttribute.TOP_ALIGNMENT ||
-                    align == GraphicAttribute.BOTTOM_ALIGNMENT
-            ) {
-                baselineIndex = GraphicAttribute.ROMAN_BASELINE;
-            } else {
-                baselineIndex = align;
-            }
-
-            baselineOffsets = new float[3];
-            baselineOffsets[0] = 0;
-            baselineOffsets[1] = (ga.getDescent() - ga.getAscent()) / 2.f;
-            baselineOffsets[2] = -ga.getAscent();
-        } else { // Use defaults - Roman baseline and zero offsets
-            baselineIndex = GraphicAttribute.ROMAN_BASELINE;
-            baselineOffsets = new float[3];
-        }
-
-        // Normalize offsets if needed
-        if (baselineOffsets[baselineIndex] != 0) {
-            float baseOffset = baselineOffsets[baselineIndex];
-            for (int i = 0; i < baselineOffsets.length; i++) {
-                baselineOffsets[i] -= baseOffset;
-            }
-        }
-    }
-
-    /**
-     * Computes metrics for the text managed by the associated TextRunBreaker
-     */
-    void computeMetrics() {
-
-        ArrayList<TextRunSegment> segments = breaker.runSegments;
-
-        float maxHeight = 0;
-        float maxHeightLeading = 0;
-
-        for (int i = 0; i < segments.size(); i++) {
-            TextRunSegment segment = segments.get(i);
-            BasicMetrics metrics = segment.metrics;
-            int baseline = metrics.baseLineIndex;
-
-            if (baseline >= 0) {
-                float baselineOffset = baselineOffsets[metrics.baseLineIndex];
-                float fixedDescent = metrics.descent + baselineOffset;
-
-                ascent = Math.max(ascent, metrics.ascent - baselineOffset);
-                descent = Math.max(descent, fixedDescent);
-                leading = Math.max(leading, fixedDescent + metrics.leading);
-            } else { // Position is not fixed by the baseline, need sum of ascent and descent
-                float height = metrics.ascent + metrics.descent;
-
-                maxHeight = Math.max(maxHeight, height);
-                maxHeightLeading = Math.max(maxHeightLeading, height + metrics.leading);
-            }
-        }
-
-        // Need to increase sizes for graphics?
-        if (maxHeightLeading != 0) {
-            descent = Math.max(descent, maxHeight - ascent);
-            leading = Math.max(leading, maxHeightLeading - ascent);
-        }
-
-        // Normalize leading
-        leading -= descent;
-
-        BasicMetrics currMetrics;
-        float currAdvance = 0;
-
-        for (int i = 0; i < segments.size(); i++) {
-            TextRunSegment segment = segments.get(breaker.getSegmentFromVisualOrder(i));
-            currMetrics = segment.metrics;
-
-            segment.y = getBaselineOffset(currMetrics.baseLineIndex)
-                    + currMetrics.superScriptOffset;
-            segment.x = currAdvance;
-
-            currAdvance += segment.getAdvance();
-        }
-
-        advance = currAdvance;
-    }
-
-    /**
-     * Computes metrics and creates BasicMetrics object from them
-     * @return basic metrics
-     */
-    public BasicMetrics createMetrics() {
-        computeMetrics();
-        return new BasicMetrics(this);
-    }
-
-    /**
-     * Corrects advance after justification. Gets BasicMetrics object
-     * and updates advance stored into it.
-     * @param metrics - metrics with outdated advance which should be corrected 
-     */
-    public void correctAdvance(BasicMetrics metrics) {
-        ArrayList<TextRunSegment> segments = breaker.runSegments;
-        TextRunSegment segment = segments.get(breaker
-                .getSegmentFromVisualOrder(segments.size() - 1));
-
-        advance = segment.x + segment.getAdvance();
-        metrics.advance = advance;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextRunBreaker.java b/awt/org/apache/harmony/awt/gl/font/TextRunBreaker.java
deleted file mode 100644
index be606f7..0000000
--- a/awt/org/apache/harmony/awt/gl/font/TextRunBreaker.java
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- */
-
-package org.apache.harmony.awt.gl.font;
-
-
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Rectangle2D;
-import java.awt.im.InputMethodHighlight;
-import java.awt.font.*;
-import java.awt.*;
-import java.text.AttributedCharacterIterator;
-import java.text.Annotation;
-import java.text.AttributedCharacterIterator.Attribute;
-import java.util.*;
-
-import org.apache.harmony.awt.gl.font.TextDecorator.Decoration;
-import org.apache.harmony.awt.internal.nls.Messages;
-import org.apache.harmony.misc.HashCode;
-// TODO - bidi not implemented yet
-
-/**
- * This class is responsible for breaking the text into the run segments
- * with constant font, style, other text attributes and direction.
- * It also stores the created text run segments and covers functionality
- * related to the operations on the set of segments, like calculating metrics,
- * rendering, justification, hit testing, etc.
- */
-public class TextRunBreaker implements Cloneable {
-    AttributedCharacterIterator aci;
-    FontRenderContext frc;
-
-    char[] text;
-
-    byte[] levels;
-
-    HashMap<Integer, Font> fonts;
-    HashMap<Integer, Decoration> decorations;
-
-    // Related to default font substitution
-    int forcedFontRunStarts[];
-
-    ArrayList<TextRunSegment> runSegments = new ArrayList<TextRunSegment>();
-
-    // For fast retrieving of the segment containing
-    // character with known logical index
-    int logical2segment[];
-    int segment2visual[]; // Visual order of segments TODO - implement
-    int visual2segment[];
-    int logical2visual[];
-    int visual2logical[];
-
-    SegmentsInfo storedSegments;
-    private boolean haveAllSegments = false;
-    int segmentsStart, segmentsEnd;
-
-    float justification = 1.0f;
-
-    public TextRunBreaker(AttributedCharacterIterator aci, FontRenderContext frc) {
-        this.aci = aci;
-        this.frc = frc;
-
-        segmentsStart = aci.getBeginIndex();
-        segmentsEnd = aci.getEndIndex();
-
-        int len = segmentsEnd - segmentsStart;
-        text = new char[len];
-        aci.setIndex(segmentsEnd);
-        while (len-- != 0) { // Going in backward direction is faster? Simplier checks here?
-            text[len] = aci.previous();
-        }
-
-        createStyleRuns();
-    }
-
-    /**
-     * Visual order of text segments may differ from the logical order.
-     * This method calculates visual position of the segment from its logical position.
-     * @param segmentNum - logical position of the segment
-     * @return visual position of the segment
-     */
-    int getVisualFromSegmentOrder(int segmentNum) {
-        return (segment2visual == null) ? segmentNum : segment2visual[segmentNum];
-    }
-
-    /**
-     * Visual order of text segments may differ from the logical order.
-     * This method calculates logical position of the segment from its visual position.
-     * @param visual - visual position of the segment
-     * @return logical position of the segment
-     */
-    int getSegmentFromVisualOrder(int visual) {
-        return (visual2segment == null) ? visual : visual2segment[visual];
-    }
-
-    /**
-     * Visual order of the characters may differ from the logical order.
-     * This method calculates visual position of the character from its logical position.
-     * @param logical - logical position of the character
-     * @return visual position
-     */
-    int getVisualFromLogical(int logical) {
-        return (logical2visual == null) ? logical : logical2visual[logical];
-    }
-
-    /**
-     * Visual order of the characters may differ from the logical order.
-     * This method calculates logical position of the character from its visual position.
-     * @param visual - visual position
-     * @return logical position
-     */
-    int getLogicalFromVisual(int visual) {
-        return (visual2logical == null) ? visual : visual2logical[visual];
-    }
-
-    /**
-     * Calculates the end index of the level run, limited by the given text run.
-     * @param runStart - run start
-     * @param runEnd - run end
-     * @return end index of the level run
-     */
-    int getLevelRunLimit(int runStart, int runEnd) {
-        if (levels == null) {
-            return runEnd;
-        }
-        int endLevelRun = runStart + 1;
-        byte level = levels[runStart];
-
-        while (endLevelRun <= runEnd && levels[endLevelRun] == level) {
-            endLevelRun++;
-        }
-
-        return endLevelRun;
-    }
-
-    /**
-     * Adds InputMethodHighlight to the attributes
-     * @param attrs - text attributes
-     * @return patched text attributes
-     */
-    Map<? extends Attribute, ?> unpackAttributes(Map<? extends Attribute, ?> attrs) {
-        if (attrs.containsKey(TextAttribute.INPUT_METHOD_HIGHLIGHT)) {
-            Map<TextAttribute, ?> styles = null;
-
-            Object val = attrs.get(TextAttribute.INPUT_METHOD_HIGHLIGHT);
-
-            if (val instanceof Annotation) {
-                val = ((Annotation) val).getValue();
-            }
-
-            if (val instanceof InputMethodHighlight) {
-                InputMethodHighlight ihl = ((InputMethodHighlight) val);
-                styles = ihl.getStyle();
-
-                if (styles == null) {
-                    Toolkit tk = Toolkit.getDefaultToolkit();
-                    styles = tk.mapInputMethodHighlight(ihl);
-                }
-            }
-
-            if (styles != null) {
-                HashMap<Attribute, Object> newAttrs = new HashMap<Attribute, Object>();
-                newAttrs.putAll(attrs);
-                newAttrs.putAll(styles);
-                return newAttrs;
-            }
-        }
-
-        return attrs;
-    }
-
-    /**
-     * Breaks the text into separate style runs.
-     */
-    void createStyleRuns() {
-        // TODO - implement fast and simple case
-        fonts = new HashMap<Integer, Font>();
-        decorations = new HashMap<Integer, Decoration>();
-        ////
-
-        ArrayList<Integer> forcedFontRunStartsList = null;
-
-        Map<? extends Attribute, ?> attributes = null;
-
-        // Check justification attribute
-        Object val = aci.getAttribute(TextAttribute.JUSTIFICATION);
-        if (val != null) {
-            justification = ((Float) val).floatValue();
-        }
-
-        for (
-            int index = segmentsStart, nextRunStart = segmentsStart;
-            index < segmentsEnd;
-            index = nextRunStart, aci.setIndex(index)
-           )  {
-            nextRunStart = aci.getRunLimit();
-            attributes = unpackAttributes(aci.getAttributes());
-
-            TextDecorator.Decoration d = TextDecorator.getDecoration(attributes);
-            decorations.put(new Integer(index), d);
-
-            // Find appropriate font or place GraphicAttribute there
-
-            // 1. Try to pick up CHAR_REPLACEMENT (compatibility)
-            Font value = (Font)attributes.get(TextAttribute.CHAR_REPLACEMENT);
-
-            if (value == null) {
-                // 2. Try to Get FONT
-                value = (Font)attributes.get(TextAttribute.FONT);
-
-                if (value == null) {
-                    // 3. Try to create font from FAMILY
-                    if (attributes.get(TextAttribute.FAMILY) != null) {
-                        value = Font.getFont(attributes);
-                    }
-
-                    if (value == null) {
-                        // 4. No attributes found, using default.
-                        if (forcedFontRunStartsList == null) {
-                            forcedFontRunStartsList = new ArrayList<Integer>();
-                        }
-                        FontFinder.findFonts(
-                                text,
-                                index,
-                                nextRunStart,
-                                forcedFontRunStartsList,
-                                fonts
-                        );
-                        value = fonts.get(new Integer(index));
-                    }
-                }
-            }
-
-            fonts.put(new Integer(index), value);
-        }
-
-        // We have added some default fonts, so we have some extra runs in text
-        if (forcedFontRunStartsList != null) {
-            forcedFontRunStarts = new int[forcedFontRunStartsList.size()];
-            for (int i=0; i<forcedFontRunStartsList.size(); i++) {
-                forcedFontRunStarts[i] =
-                        forcedFontRunStartsList.get(i).intValue();
-            }
-        }
-    }
-
-    /**
-     * Starting from the current position looks for the end of the text run with
-     * constant text attributes.
-     * @param runStart - start position
-     * @param maxPos - position where to stop if no run limit found
-     * @return style run limit
-     */
-    int getStyleRunLimit(int runStart, int maxPos) {
-        try {
-            aci.setIndex(runStart);
-        } catch(IllegalArgumentException e) { // Index out of bounds
-            if (runStart < segmentsStart) {
-                aci.first();
-            } else {
-                aci.last();
-            }
-        }
-
-        // If we have some extra runs we need to check for their limits
-        if (forcedFontRunStarts != null) {
-            for (int element : forcedFontRunStarts) {
-                if (element > runStart) {
-                    maxPos = Math.min(element, maxPos);
-                    break;
-                }
-            }
-        }
-
-        return Math.min(aci.getRunLimit(), maxPos);
-    }
-
-    /**
-     * Creates segments for the text run with
-     * constant decoration, font and bidi level
-     * @param runStart - run start
-     * @param runEnd - run end
-     */
-    public void createSegments(int runStart, int runEnd) {
-        int endStyleRun, endLevelRun;
-
-        // TODO - update levels
-
-        int pos = runStart, levelPos;
-
-        aci.setIndex(pos);
-        final int firstRunStart = aci.getRunStart();
-        Object tdd = decorations.get(new Integer(firstRunStart));
-        Object fontOrGAttr = fonts.get(new Integer(firstRunStart));
-
-        logical2segment = new int[runEnd - runStart];
-
-        do {
-            endStyleRun = getStyleRunLimit(pos, runEnd);
-
-            // runStart can be non-zero, but all arrays will be indexed from 0
-            int ajustedPos = pos - runStart;
-            int ajustedEndStyleRun = endStyleRun - runStart;
-            levelPos = ajustedPos;
-            do {
-                endLevelRun = getLevelRunLimit(levelPos, ajustedEndStyleRun);
-
-                if (fontOrGAttr instanceof GraphicAttribute) {
-                    runSegments.add(
-                        new TextRunSegmentImpl.TextRunSegmentGraphic(
-                                (GraphicAttribute)fontOrGAttr,
-                                endLevelRun - levelPos,
-                                levelPos + runStart)
-                    );
-                    Arrays.fill(logical2segment, levelPos, endLevelRun, runSegments.size()-1);
-                } else {
-                    TextRunSegmentImpl.TextSegmentInfo i =
-                            new TextRunSegmentImpl.TextSegmentInfo(
-                                    levels == null ? 0 : levels[ajustedPos],
-                                    (Font) fontOrGAttr,
-                                    frc,
-                                    text,
-                                    levelPos + runStart,
-                                    endLevelRun + runStart
-                            );
-
-                    runSegments.add(
-                            new TextRunSegmentImpl.TextRunSegmentCommon(
-                                    i,
-                                    (TextDecorator.Decoration) tdd
-                            )
-                    );
-                    Arrays.fill(logical2segment, levelPos, endLevelRun, runSegments.size()-1);
-                }
-
-                levelPos = endLevelRun;
-            } while (levelPos < ajustedEndStyleRun);
-
-            // Prepare next iteration
-            pos = endStyleRun;
-            tdd = decorations.get(new Integer(pos));
-            fontOrGAttr = fonts.get(new Integer(pos));
-        } while (pos < runEnd);
-    }
-
-    /**
-     * Checks if text run segments are up to date and creates the new segments if not.
-     */
-    public void createAllSegments() {
-        if ( !haveAllSegments &&
-            (logical2segment == null ||
-             logical2segment.length != segmentsEnd - segmentsStart)
-        ) { // Check if we don't have all segments yet
-            resetSegments();
-            createSegments(segmentsStart, segmentsEnd);
-        }
-
-        haveAllSegments = true;
-    }
-
-    /**
-     * Calculates position where line should be broken without
-     * taking into account word boundaries.
-     * @param start - start index
-     * @param maxAdvance - maximum advance, width of the line
-     * @return position where to break
-     */
-    public int getLineBreakIndex(int start, float maxAdvance) {
-        int breakIndex;
-        TextRunSegment s = null;
-
-        for (
-                int segmentIndex = logical2segment[start];
-                segmentIndex < runSegments.size();
-                segmentIndex++
-           ) {
-            s = runSegments.get(segmentIndex);
-            breakIndex = s.getCharIndexFromAdvance(maxAdvance, start);
-
-            if (breakIndex < s.getEnd()) {
-                return breakIndex;
-            }
-            maxAdvance -= s.getAdvanceDelta(start, s.getEnd());
-            start = s.getEnd();
-        }
-
-        return s.getEnd();
-    }
-
-    /**
-     * Inserts character into the managed text.
-     * @param newParagraph - new character iterator
-     * @param insertPos - insertion position
-     */
-    public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) {
-        aci = newParagraph;
-
-        char insChar = aci.setIndex(insertPos);
-
-        Integer key = new Integer(insertPos);
-
-        insertPos -= aci.getBeginIndex();
-
-        char newText[] = new char[text.length + 1];
-        System.arraycopy(text, 0, newText, 0, insertPos);
-        newText[insertPos] = insChar;
-        System.arraycopy(text, insertPos, newText, insertPos+1, text.length - insertPos);
-        text = newText;
-
-        if (aci.getRunStart() == key.intValue() && aci.getRunLimit() == key.intValue() + 1) {
-            createStyleRuns(); // We have to create one new run, could be optimized
-        } else {
-            shiftStyleRuns(key, 1);
-        }
-
-        resetSegments();
-
-        segmentsEnd++;
-    }
-
-    /**
-     * Deletes character from the managed text.
-     * @param newParagraph - new character iterator
-     * @param deletePos - deletion position
-     */
-    public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) {
-        aci = newParagraph;
-
-        Integer key = new Integer(deletePos);
-
-        deletePos -= aci.getBeginIndex();
-
-        char newText[] = new char[text.length - 1];
-        System.arraycopy(text, 0, newText, 0, deletePos);
-        System.arraycopy(text, deletePos+1, newText, deletePos, newText.length - deletePos);
-        text = newText;
-
-        if (fonts.get(key) != null) {
-            fonts.remove(key);
-        }
-
-        shiftStyleRuns(key, -1);
-
-        resetSegments();
-
-        segmentsEnd--;
-    }
-
-    /**
-     * Shift all runs after specified position, needed to perfom insertion
-     * or deletion in the managed text
-     * @param pos - position where to start
-     * @param shift - shift, could be negative
-     */
-    private void shiftStyleRuns(Integer pos, final int shift) {
-        ArrayList<Integer> keys = new ArrayList<Integer>();
-
-        Integer key, oldkey;
-        for (Iterator<Integer> it = fonts.keySet().iterator(); it.hasNext(); ) {
-            oldkey = it.next();
-            if (oldkey.intValue() > pos.intValue()) {
-                keys.add(oldkey);
-            }
-        }
-
-        for (int i=0; i<keys.size(); i++) {
-            oldkey = keys.get(i);
-            key = new Integer(shift + oldkey.intValue());
-            fonts.put(key, fonts.remove(oldkey));
-            decorations.put(key, decorations.remove(oldkey));
-        }
-    }
-
-    /**
-     * Resets state of the class
-     */
-    private void resetSegments() {
-        runSegments = new ArrayList<TextRunSegment>();
-        logical2segment = null;
-        segment2visual = null;
-        visual2segment = null;
-        levels = null;
-        haveAllSegments = false;
-    }
-
-    private class SegmentsInfo {
-        ArrayList<TextRunSegment> runSegments;
-        int logical2segment[];
-        int segment2visual[];
-        int visual2segment[];
-        byte levels[];
-        int segmentsStart;
-        int segmentsEnd;
-    }
-
-    /**
-     * Saves the internal state of the class
-     * @param newSegStart - new start index in the text
-     * @param newSegEnd - new end index in the text
-     */
-    public void pushSegments(int newSegStart, int newSegEnd) {
-        storedSegments = new SegmentsInfo();
-        storedSegments.runSegments = this.runSegments;
-        storedSegments.logical2segment = this.logical2segment;
-        storedSegments.segment2visual = this.segment2visual;
-        storedSegments.visual2segment = this.visual2segment;
-        storedSegments.levels = this.levels;
-        storedSegments.segmentsStart = segmentsStart;
-        storedSegments.segmentsEnd = segmentsEnd;
-
-        resetSegments();
-
-        segmentsStart = newSegStart;
-        segmentsEnd = newSegEnd;
-    }
-
-    /**
-     * Restores the internal state of the class
-     */
-    public void popSegments() {
-        if (storedSegments == null) {
-            return;
-        }
-
-        this.runSegments = storedSegments.runSegments;
-        this.logical2segment = storedSegments.logical2segment;
-        this.segment2visual = storedSegments.segment2visual;
-        this.visual2segment = storedSegments.visual2segment;
-        this.levels = storedSegments.levels;
-        this.segmentsStart = storedSegments.segmentsStart;
-        this.segmentsEnd = storedSegments.segmentsEnd;
-        storedSegments = null;
-
-        if (runSegments.size() == 0 && logical2segment == null) {
-            haveAllSegments = false;
-        } else {
-            haveAllSegments = true;
-        }
-    }
-
-    @Override
-    public Object clone() {
-        try {
-            TextRunBreaker res = (TextRunBreaker) super.clone();
-            res.storedSegments = null;
-            ArrayList<TextRunSegment> newSegments = new ArrayList<TextRunSegment>(runSegments.size());
-            for (int i = 0; i < runSegments.size(); i++) {
-                TextRunSegment seg =  runSegments.get(i);
-                newSegments.add((TextRunSegment)seg.clone());
-            }
-            res.runSegments = newSegments;
-            return res;
-        } catch (CloneNotSupportedException e) {
-            // awt.3E=Clone not supported
-            throw new UnsupportedOperationException(Messages.getString("awt.3E")); //$NON-NLS-1$
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof TextRunBreaker)) {
-            return false;
-        }
-
-        TextRunBreaker br = (TextRunBreaker) obj;
-
-        if (br.getACI().equals(aci) && br.frc.equals(frc)) {
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return HashCode.combine(aci.hashCode(), frc.hashCode());
-    }
-
-    /**
-     * Renders the managed text
-     * @param g2d - graphics where to render
-     * @param xOffset - offset in X direction to the upper left corner
-     * of the layout from the origin of the graphics
-     * @param yOffset - offset in Y direction to the upper left corner
-     * of the layout from the origin of the graphics
-     */
-    public void drawSegments(Graphics2D g2d, float xOffset, float yOffset) {
-        for (int i=0; i<runSegments.size(); i++) {
-            runSegments.get(i).draw(g2d, xOffset, yOffset);
-        }
-    }
-
-    /**
-     * Creates the black box bounds shape
-     * @param firstEndpoint - start position
-     * @param secondEndpoint - end position
-     * @return black box bounds shape
-     */
-    public Shape getBlackBoxBounds(int firstEndpoint, int secondEndpoint) {
-        GeneralPath bounds = new GeneralPath();
-
-        TextRunSegment segment;
-
-        for (int idx = firstEndpoint; idx < secondEndpoint; idx=segment.getEnd()) {
-            segment = runSegments.get(logical2segment[idx]);
-            bounds.append(segment.getCharsBlackBoxBounds(idx, secondEndpoint), false);
-        }
-
-        return bounds;
-    }
-
-    /**
-     * Creates visual bounds shape
-     * @return visual bounds rectangle
-     */
-    public Rectangle2D getVisualBounds() {
-        Rectangle2D bounds = null;
-
-        for (int i=0; i<runSegments.size(); i++) {
-            TextRunSegment s = runSegments.get(i);
-            if (bounds != null) {
-                Rectangle2D.union(bounds, s.getVisualBounds(), bounds);
-            } else {
-                bounds = s.getVisualBounds();
-            }
-        }
-
-        return bounds;
-    }
-
-    /**
-     * Creates logical bounds shape
-     * @return logical bounds rectangle
-     */
-    public Rectangle2D getLogicalBounds() {
-        Rectangle2D bounds = null;
-
-        for (int i=0; i<runSegments.size(); i++) {
-            TextRunSegment s = runSegments.get(i);
-            if (bounds != null) {
-                Rectangle2D.union(bounds, s.getLogicalBounds(), bounds);
-            } else {
-                bounds = s.getLogicalBounds();
-            }
-        }
-
-        return bounds;
-    }
-
-    public int getCharCount() {
-        return segmentsEnd - segmentsStart;
-    }
-
-    public byte getLevel(int idx) {
-        if (levels == null) {
-            return 0;
-        }
-        return levels[idx];
-    }
-
-    public int getBaseLevel() {
-        return 0;
-    }
-
-    public boolean isLTR() {
-        return true;
-    }
-
-    public char getChar(int index) {
-        return text[index];
-    }
-
-    public AttributedCharacterIterator getACI() {
-        return aci;
-    }
-
-    /**
-     * Creates outline shape for the managed text
-     * @return outline
-     */
-    public GeneralPath getOutline() {
-        GeneralPath outline = new GeneralPath();
-
-        TextRunSegment segment;
-
-        for (int i = 0; i < runSegments.size(); i++) {
-            segment = runSegments.get(i);
-            outline.append(segment.getOutline(), false);
-        }
-
-        return outline;
-    }
-
-    /**
-     * Calculates text hit info from the screen coordinates.
-     * Current implementation totally ignores Y coordinate.
-     * If X coordinate is outside of the layout boundaries, this
-     * method returns leftmost or rightmost hit.
-     * @param x - x coordinate of the hit
-     * @param y - y coordinate of the hit
-     * @return hit info
-     */
-    public TextHitInfo hitTest(float x, float y) {
-        TextRunSegment segment;
-
-        double endOfPrevSeg = -1;
-        for (int i = 0; i < runSegments.size(); i++) {
-            segment = runSegments.get(i);
-            Rectangle2D bounds = segment.getVisualBounds();
-            if ((bounds.getMinX() <= x && bounds.getMaxX() >= x) || // We are in the segment
-               (endOfPrevSeg < x && bounds.getMinX() > x)) { // We are somewhere between the segments
-                return segment.hitTest(x,y);
-            }
-            endOfPrevSeg = bounds.getMaxX();
-        }
-
-        return isLTR() ? TextHitInfo.trailing(text.length) : TextHitInfo.leading(0);
-    }
-
-    public float getJustification() {
-        return justification;
-    }
-
-    /**
-     * Calculates position of the last non whitespace character
-     * in the managed text.
-     * @return position of the last non whitespace character
-     */
-    public int getLastNonWhitespace() {
-        int lastNonWhitespace = text.length;
-
-        while (lastNonWhitespace >= 0) {
-            lastNonWhitespace--;
-            if (!Character.isWhitespace(text[lastNonWhitespace])) {
-                break;
-            }
-        }
-
-        return lastNonWhitespace;
-    }
-
-    /**
-     * Performs justification of the managed text by changing segment positions
-     * and positions of the glyphs inside of the segments.
-     * @param gap - amount of space which should be compensated by justification
-     */
-    public void justify(float gap) {
-        // Ignore trailing logical whitespace
-        int firstIdx = segmentsStart;
-        int lastIdx = getLastNonWhitespace() + segmentsStart;
-        JustificationInfo jInfos[] = new JustificationInfo[5];
-        float gapLeft = gap;
-
-        int highestPriority = -1;
-        // GlyphJustificationInfo.PRIORITY_KASHIDA is 0
-        // GlyphJustificationInfo.PRIORITY_NONE is 3
-        for (int priority = 0; priority <= GlyphJustificationInfo.PRIORITY_NONE + 1; priority++) {
-            JustificationInfo jInfo = new JustificationInfo();
-            jInfo.lastIdx = lastIdx;
-            jInfo.firstIdx = firstIdx;
-            jInfo.grow = gap > 0;
-            jInfo.gapToFill = gapLeft;
-
-            if (priority <= GlyphJustificationInfo.PRIORITY_NONE) {
-                jInfo.priority = priority;
-            } else {
-                jInfo.priority = highestPriority; // Last pass
-            }
-
-            for (int i = 0; i < runSegments.size(); i++) {
-                TextRunSegment segment = runSegments.get(i);
-                if (segment.getStart() <= lastIdx) {
-                    segment.updateJustificationInfo(jInfo);
-                }
-            }
-
-            if (jInfo.priority == highestPriority) {
-                jInfo.absorb = true;
-                jInfo.absorbedWeight = jInfo.weight;
-            }
-
-            if (jInfo.weight != 0) {
-                if (highestPriority < 0) {
-                    highestPriority = priority;
-                }
-                jInfos[priority] = jInfo;
-            } else {
-                continue;
-            }
-
-            gapLeft -= jInfo.growLimit;
-
-            if (((gapLeft > 0) ^ jInfo.grow) || gapLeft == 0) {
-                gapLeft = 0;
-                jInfo.gapPerUnit = jInfo.gapToFill/jInfo.weight;
-                break;
-            }
-            jInfo.useLimits = true;
-
-            if (jInfo.absorbedWeight > 0) {
-                jInfo.absorb = true;
-                jInfo.absorbedGapPerUnit =
-                        (jInfo.gapToFill-jInfo.growLimit)/jInfo.absorbedWeight;
-                break;
-            }
-        }
-
-        float currJustificationOffset = 0;
-        for (int i = 0; i < runSegments.size(); i++) {
-            TextRunSegment segment =
-                    runSegments.get(getSegmentFromVisualOrder(i));
-            segment.x += currJustificationOffset;
-            currJustificationOffset += segment.doJustification(jInfos);
-        }
-
-        justification = -1; // Make further justification impossible
-    }
-
-    /**
-     * This class represents the information collected before the actual
-     * justification is started and needed to perform the justification.
-     * This information is closely related to the information stored in the
-     * GlyphJustificationInfo for the text represented by glyph vectors.
-     */
-    class JustificationInfo {
-        boolean grow;
-        boolean absorb = false;
-        boolean useLimits = false;
-        int priority = 0;
-        float weight = 0;
-        float absorbedWeight = 0;
-        float growLimit = 0;
-
-        int lastIdx;
-        int firstIdx;
-
-        float gapToFill;
-
-        float gapPerUnit = 0; // Precalculated value, gapToFill / weight
-        float absorbedGapPerUnit = 0; // Precalculated value, gapToFill / weight
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextRunSegment.java b/awt/org/apache/harmony/awt/gl/font/TextRunSegment.java
deleted file mode 100644
index 1cd2c05..0000000
--- a/awt/org/apache/harmony/awt/gl/font/TextRunSegment.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/*
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.Graphics2D;
-import java.awt.Shape;
-import java.awt.font.TextHitInfo;
-import java.awt.geom.Rectangle2D;
-
-/**
- * Abstract class which represents the segment of the text with constant attributes
- * running in one direction (i.e. constant level).
- */
-public abstract class TextRunSegment implements Cloneable {
-    float x; // Calculated x location of this segment on the screen
-    float y; // Calculated y location of this segment on the screen
-
-    BasicMetrics metrics; // Metrics of this text run segment
-    TextDecorator.Decoration decoration; // Underline, srikethrough, etc.
-    Rectangle2D logicalBounds = null; // Logical bounding box for the segment
-    Rectangle2D visualBounds = null; // Visual bounding box for the segment
-
-    /**
-     * Returns start index of the segment
-     * @return start index
-     */
-    abstract int getStart();
-
-    /**
-     * Returns end index of the segment
-     * @return end index
-     */
-    abstract int getEnd();
-
-    /**
-     * Returns the number of characters in the segment
-     * @return number of characters
-     */
-    abstract int getLength();
-
-    /**
-     * Renders this text run segment
-     * @param g2d - graphics to render to
-     * @param xOffset - X offset from the graphics origin to the
-     * origin of the text layout
-     * @param yOffset - Y offset from the graphics origin to the
-     * origin of the text layout
-     */
-    abstract void draw(Graphics2D g2d, float xOffset, float yOffset);
-
-    /**
-     * Creates black box bounds shape for the specified range
-     * @param start - range sart
-     * @param limit - range end
-     * @return black box bounds shape
-     */
-    abstract Shape getCharsBlackBoxBounds(int start, int limit);
-
-    /**
-     * Returns the outline shape
-     * @return outline
-     */
-    abstract Shape getOutline();
-
-    /**
-     * Returns visual bounds of this segment
-     * @return visual bounds
-     */
-    abstract Rectangle2D getVisualBounds();
-
-    /**
-     * Returns logical bounds of this segment
-     * @return logical bounds
-     */
-    abstract Rectangle2D getLogicalBounds();
-
-    /**
-     * Calculates advance of the segment
-     * @return advance
-     */
-    abstract float getAdvance();
-
-    /**
-     * Calculates advance delta between two characters
-     * @param start - 1st position
-     * @param end - 2nd position
-     * @return advance increment between specified positions
-     */
-    abstract float getAdvanceDelta(int start, int end);
-
-    /**
-     * Calculates index of the character which advance is equal to
-     * the given. If the given advance is greater then the segment
-     * advance it returns the position after the last character.
-     * @param advance - given advance
-     * @param start - character, from which to start measuring advance
-     * @return character index
-     */
-    abstract int getCharIndexFromAdvance(float advance, int start);
-
-    /**
-     * Checks if the character doesn't contribute to the text advance
-     * @param index - character index
-     * @return true if the character has zero advance
-     */
-    abstract boolean charHasZeroAdvance(int index);
-
-    /**
-     * Calculates position of the character on the screen
-     * @param index - character index
-     * @return X coordinate of the character position
-     */
-    abstract float getCharPosition(int index);
-
-    /**
-     * Returns the advance of the individual character
-     * @param index - character index
-     * @return character advance
-     */
-    abstract float getCharAdvance(int index);
-
-    /**
-     * Creates text hit info from the hit position
-     * @param x - X coordinate relative to the origin of the layout
-     * @param y - Y coordinate relative to the origin of the layout
-     * @return hit info
-     */
-    abstract TextHitInfo hitTest(float x, float y);
-
-    /**
-     * Collects justification information into JustificationInfo object
-     * @param jInfo - JustificationInfo object
-     */
-    abstract void updateJustificationInfo(TextRunBreaker.JustificationInfo jInfo);
-
-    /**
-     * Performs justification of the segment.
-     * Updates positions of individual characters.
-     * @param jInfos - justification information, gathered by the previous passes
-     * @return amount of growth or shrink of the segment
-     */    
-    abstract float doJustification(TextRunBreaker.JustificationInfo jInfos[]);
-
-    @Override
-    public abstract Object clone();
-}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java b/awt/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java
deleted file mode 100644
index 0ec2d05..0000000
--- a/awt/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java
+++ /dev/null
@@ -1,979 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- */
-
-package org.apache.harmony.awt.gl.font;
-
-import java.awt.*;
-import java.awt.font.*;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-// XXX - TODO - bidi not implemented yet
-//import java.text.Bidi;
-import java.util.Arrays;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * Date: Apr 25, 2005
- * Time: 4:33:18 PM
- *
- * This class contains the implementation of the behavior of the
- * text run segment with constant text attributes and direction.
- */
-public class TextRunSegmentImpl {
-
-    /**
-     * This class contains basic information required for creation
-     * of the glyph-based text run segment.
-     */
-    public static class TextSegmentInfo {
-        // XXX - TODO - bidi not implemented yet
-        //Bidi bidi;
-
-        Font font;
-        FontRenderContext frc;
-
-        char text[];
-
-        int start;
-        int end;
-        int length;
-
-        int flags = 0;
-
-        byte level = 0;
-
-        TextSegmentInfo(
-                byte level,
-                Font font, FontRenderContext frc,
-                char text[], int start, int end
-        ) {
-            this.font = font;
-            this.frc = frc;
-            this.text = text;
-            this.start = start;
-            this.end = end;
-            this.level = level;
-            length = end - start;
-        }
-    }
-
-    /**
-     * This class represents a simple text segment backed by the glyph vector
-     */
-    public static class TextRunSegmentCommon extends TextRunSegment {
-        TextSegmentInfo info;
-        private GlyphVector gv;
-        private float advanceIncrements[];
-        private int char2glyph[];
-        private GlyphJustificationInfo gjis[]; // Glyph justification info
-
-        TextRunSegmentCommon(TextSegmentInfo i, TextDecorator.Decoration d) {
-            // XXX - todo - check support bidi
-            i.flags &= ~0x09; // Clear bidi flags
-
-            if ((i.level & 0x1) != 0) {
-                i.flags |= Font.LAYOUT_RIGHT_TO_LEFT;
-            }
-
-            info = i;
-            this.decoration = d;
-
-            LineMetrics lm = i.font.getLineMetrics(i.text, i.start, i.end, i.frc);
-            this.metrics = new BasicMetrics(lm, i.font);
-
-            if (lm.getNumChars() != i.length) { // XXX todo - This should be handled
-                // awt.41=Font returned unsupported type of line metrics. This case is known, but not supported yet.
-                throw new UnsupportedOperationException(
-                        Messages.getString("awt.41")); //$NON-NLS-1$
-            }
-        }
-
-        @Override
-        public Object clone() {
-            return new TextRunSegmentCommon(info, decoration);
-        }
-
-        /**
-         * Creates glyph vector from the managed text if needed
-         * @return glyph vector
-         */
-        private GlyphVector getGlyphVector() {
-            if (gv==null) {
-                gv = info.font.layoutGlyphVector(
-                        info.frc,
-                        info.text,
-                        info.start,
-                        info.end - info.start, // NOTE: This parameter violates
-                                               // spec, it is count,
-                                               // not limit as spec states
-                        info.flags
-                );
-            }
-
-            return gv;
-        }
-
-        /**
-         * Renders this text run segment
-         * @param g2d - graphics to render to
-         * @param xOffset - X offset from the graphics origin to the
-         * origin of the text layout
-         * @param yOffset - Y offset from the graphics origin to the
-         * origin of the text layout
-         */
-        @Override
-        void draw(Graphics2D g2d, float xOffset, float yOffset) {
-            if (decoration == null) {
-                g2d.drawGlyphVector(getGlyphVector(), xOffset + x, yOffset + y);
-            } else {
-                TextDecorator.prepareGraphics(this, g2d, xOffset, yOffset);
-                g2d.drawGlyphVector(getGlyphVector(), xOffset + x, yOffset + y);
-                TextDecorator.drawTextDecorations(this, g2d, xOffset, yOffset);
-                TextDecorator.restoreGraphics(decoration, g2d);
-            }
-        }
-
-        /**
-         * Returns visual bounds of this segment
-         * @return visual bounds
-         */
-        @Override
-        Rectangle2D getVisualBounds() {
-            if (visualBounds == null) {
-                visualBounds =
-                        TextDecorator.extendVisualBounds(
-                                this,
-                                getGlyphVector().getVisualBounds(),
-                                decoration
-                        );
-
-                visualBounds.setRect(
-                        x + visualBounds.getX(),
-                        y + visualBounds.getY(),
-                        visualBounds.getWidth(),
-                        visualBounds.getHeight()
-                );
-            }
-
-            return (Rectangle2D) visualBounds.clone();
-        }
-
-        /**
-         * Returns logical bounds of this segment
-         * @return logical bounds
-         */
-        @Override
-        Rectangle2D getLogicalBounds() {
-            if (logicalBounds == null) {
-                logicalBounds = getGlyphVector().getLogicalBounds();
-
-                logicalBounds.setRect(
-                        x + logicalBounds.getX(),
-                        y + logicalBounds.getY(),
-                        logicalBounds.getWidth(),
-                        logicalBounds.getHeight()
-                );
-            }
-
-            return (Rectangle2D) logicalBounds.clone();
-        }
-
-        @Override
-        float getAdvance() {
-            return (float) getLogicalBounds().getWidth();
-        }
-
-        /**
-         * Attemts to map each character to the corresponding advance increment
-         */
-        void initAdvanceMapping() {
-            GlyphVector gv = getGlyphVector();
-            int charIndicies[] = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), null);
-            advanceIncrements = new float[info.length];
-
-            for (int i=0; i<charIndicies.length; i++) {
-                advanceIncrements[charIndicies[i]] = gv.getGlyphMetrics(i).getAdvance();
-            }
-        }
-
-        /**
-         * Calculates advance delta between two characters
-         * @param start - 1st position
-         * @param end - 2nd position
-         * @return advance increment between specified positions
-         */
-        @Override
-        float getAdvanceDelta(int start, int end) {
-            // Get coordinates in the segment context
-            start -= info.start;
-            end -= info.start;
-
-            if (advanceIncrements == null) {
-                initAdvanceMapping();
-            }
-
-            if (start < 0) {
-                start = 0;
-            }
-            if (end > info.length) {
-                end = info.length;
-            }
-
-            float sum = 0;
-            for (int i=start; i<end; i++) {
-                sum += advanceIncrements[i];
-            }
-
-            return sum;
-        }
-
-        /**
-         * Calculates index of the character which advance is equal to
-         * the given. If the given advance is greater then the segment
-         * advance it returns the position after the last character.
-         * @param advance - given advance
-         * @param start - character, from which to start measuring advance
-         * @return character index
-         */
-        @Override
-        int getCharIndexFromAdvance(float advance, int start) {
-            // XXX - todo - probably, possible to optimize
-            // Add check if the given advance is greater then
-            // the segment advance in the beginning. In this case
-            // we don't need to run through all increments
-            if (advanceIncrements == null) {
-                initAdvanceMapping();
-            }
-
-            start -= info.start;
-
-            if (start < 0) {
-                start = 0;
-            }
-
-            int i = start;
-            for (; i<info.length; i++) {
-                advance -= advanceIncrements[i];
-                if (advance < 0) {
-                    break;
-                }
-            }
-
-            return i + info.start;
-        }
-
-        @Override
-        int getStart() {
-            return info.start;
-        }
-
-        @Override
-        int getEnd() {
-            return info.end;
-        }
-
-        @Override
-        int getLength() {
-            return info.length;
-        }
-
-        /**
-         * Attemts to create mapping of the characters to glyphs in the glyph vector.
-         * @return array where for each character index stored corresponding glyph index
-         */
-        private int[] getChar2Glyph() {
-            if (char2glyph == null) {
-                GlyphVector gv = getGlyphVector();
-                char2glyph = new int[info.length];
-                Arrays.fill(char2glyph, -1);
-
-                // Fill glyph indicies for first characters corresponding to each glyph
-                int charIndicies[] = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), null);
-                for (int i=0; i<charIndicies.length; i++) {
-                    char2glyph[charIndicies[i]] = i;
-                }
-
-                // If several characters corresponds to one glyph, create mapping for them
-                // Suppose that these characters are going all together
-                int currIndex = 0;
-                for (int i=0; i<char2glyph.length; i++) {
-                    if (char2glyph[i] < 0) {
-                        char2glyph[i] = currIndex;
-                    } else {
-                        currIndex = char2glyph[i];
-                    }
-                }
-            }
-
-            return char2glyph;
-        }
-
-        /**
-         * Creates black box bounds shape for the specified range
-         * @param start - range sart
-         * @param limit - range end
-         * @return black box bounds shape
-         */
-        @Override
-        Shape getCharsBlackBoxBounds(int start, int limit) {
-            start -= info.start;
-            limit -= info.start;
-
-            if (limit > info.length) {
-                limit = info.length;
-            }
-
-            GeneralPath result = new GeneralPath();
-
-            int glyphIndex = 0;
-
-            for (int i=start; i<limit; i++) {
-                glyphIndex = getChar2Glyph()[i];
-                result.append(getGlyphVector().getGlyphVisualBounds(glyphIndex), false);
-            }
-
-            // Shift to the segment's coordinates
-            result.transform(AffineTransform.getTranslateInstance(x, y));
-
-            return result;
-        }
-
-        /**
-         * Calculates position of the character on the screen
-         * @param index - character index
-         * @return X coordinate of the character position
-         */
-        @Override
-        float getCharPosition(int index) {
-            index -= info.start;
-
-            if (index > info.length) {
-                index = info.length;
-            }
-
-            float result = 0;
-
-            int glyphIndex = getChar2Glyph()[index];
-            result = (float) getGlyphVector().getGlyphPosition(glyphIndex).getX();
-
-            // Shift to the segment's coordinates
-            result += x;
-
-            return result;
-        }
-
-        /**
-         * Returns the advance of the individual character
-         * @param index - character index
-         * @return character advance
-         */
-        @Override
-        float getCharAdvance(int index) {
-            if (advanceIncrements == null) {
-                initAdvanceMapping();
-            }
-
-            return advanceIncrements[index - this.getStart()];
-        }
-
-        /**
-         * Returns the outline shape
-         * @return outline
-         */
-        @Override
-        Shape getOutline() {
-            AffineTransform t = AffineTransform.getTranslateInstance(x, y);
-            return t.createTransformedShape(
-                    TextDecorator.extendOutline(
-                            this,
-                            getGlyphVector().getOutline(),
-                            decoration
-                    )
-            );
-        }
-
-        /**
-         * Checks if the character doesn't contribute to the text advance
-         * @param index - character index
-         * @return true if the character has zero advance
-         */
-        @Override
-        boolean charHasZeroAdvance(int index) {
-            if (advanceIncrements == null) {
-                initAdvanceMapping();
-            }
-
-            return advanceIncrements[index - this.getStart()] == 0;
-        }
-
-        /**
-         * Creates text hit info from the hit position
-         * @param hitX - X coordinate relative to the origin of the layout
-         * @param hitY - Y coordinate relative to the origin of the layout
-         * @return hit info
-         */
-        @Override
-        TextHitInfo hitTest(float hitX, float hitY) {
-            hitX -= x;
-
-            float glyphPositions[] =
-                    getGlyphVector().getGlyphPositions(0, info.length+1, null);
-
-            int glyphIdx;
-            boolean leading = false;
-            for (glyphIdx = 1; glyphIdx <= info.length; glyphIdx++) {
-                if (glyphPositions[(glyphIdx)*2] >= hitX) {
-                    float advance =
-                            glyphPositions[(glyphIdx)*2] - glyphPositions[(glyphIdx-1)*2];
-                    leading = glyphPositions[(glyphIdx-1)*2] + advance/2 > hitX ? true : false;
-                    glyphIdx--;
-                    break;
-                }
-            }
-
-            if (glyphIdx == info.length) {
-                glyphIdx--;
-            }
-
-            int charIdx = getGlyphVector().getGlyphCharIndex(glyphIdx);
-
-            return (leading) ^ ((info.level & 0x1) == 0x1)?
-                    TextHitInfo.leading(charIdx + info.start) :
-                    TextHitInfo.trailing(charIdx + info.start);
-        }
-
-        /**
-         * Collects GlyphJustificationInfo objects from the glyph vector
-         * @return array of all GlyphJustificationInfo objects
-         */
-        private GlyphJustificationInfo[] getGlyphJustificationInfos() {
-            if (gjis == null) {
-                GlyphVector gv = getGlyphVector();
-                int nGlyphs = gv.getNumGlyphs();
-                int charIndicies[] = gv.getGlyphCharIndices(0, nGlyphs, null);
-                gjis = new GlyphJustificationInfo[nGlyphs];
-
-                // Patch: temporary patch, getGlyphJustificationInfo is not implemented
-                float fontSize = info.font.getSize2D();
-                GlyphJustificationInfo defaultInfo =
-                        new GlyphJustificationInfo(
-                                0, // weight
-                                false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0, // grow
-                                false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0); // shrink
-                GlyphJustificationInfo spaceInfo = new GlyphJustificationInfo(
-                        fontSize, // weight
-                        true, GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, fontSize, // grow
-                        true, GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, fontSize); // shrink
-
-                ////////
-                // Temporary patch, getGlyphJustificationInfo is not implemented
-                for (int i = 0; i < nGlyphs; i++) {
-                    //gjis[i] = getGlyphVector().getGlyphJustificationInfo(i);
-
-                    char c = info.text[charIndicies[i] + info.start];
-                    if (Character.isWhitespace(c)) {
-                        gjis[i] = spaceInfo;
-                    } else {
-                        gjis[i] = defaultInfo;
-                    }
-                    // End patch
-                }
-            }
-
-            return gjis;
-        }
-
-        /**
-         * Collects justification information into JustificationInfo object
-         * @param jInfo - JustificationInfo object
-         */
-        @Override
-        void updateJustificationInfo(TextRunBreaker.JustificationInfo jInfo) {
-            int lastChar = Math.min(jInfo.lastIdx, info.end) - info.start;
-            boolean haveFirst = info.start <= jInfo.firstIdx;
-            boolean haveLast = info.end >= (jInfo.lastIdx + 1);
-
-            int prevGlyphIdx = -1;
-            int currGlyphIdx;
-
-            if (jInfo.grow) { // Check how much we can grow/shrink on current priority level
-                for (int i=0; i<lastChar; i++) {
-                    currGlyphIdx = getChar2Glyph()[i];
-
-                    if (currGlyphIdx == prevGlyphIdx) {
-                        // Several chars could be represented by one glyph,
-                        // suppose they are contiguous
-                        continue;
-                    }
-                    prevGlyphIdx = currGlyphIdx;
-
-                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[currGlyphIdx];
-                    if (gji.growPriority == jInfo.priority) {
-                        jInfo.weight += gji.weight * 2;
-                        jInfo.growLimit += gji.growLeftLimit;
-                        jInfo.growLimit += gji.growRightLimit;
-                        if (gji.growAbsorb) {
-                            jInfo.absorbedWeight += gji.weight * 2;
-                        }
-                    }
-                }
-            } else {
-                for (int i=0; i<lastChar; i++) {
-                    currGlyphIdx = getChar2Glyph()[i];
-                    if (currGlyphIdx == prevGlyphIdx) {
-                        continue;
-                    }
-                    prevGlyphIdx = currGlyphIdx;
-
-                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[currGlyphIdx];
-                    if (gji.shrinkPriority == jInfo.priority) {
-                        jInfo.weight += gji.weight * 2;
-                        jInfo.growLimit -= gji.shrinkLeftLimit;
-                        jInfo.growLimit -= gji.shrinkRightLimit;
-                        if (gji.shrinkAbsorb) {
-                            jInfo.absorbedWeight += gji.weight * 2;
-                        }
-                    }
-                }
-            }
-
-            if (haveFirst) {  // Don't add padding before first char
-                GlyphJustificationInfo gji = getGlyphJustificationInfos()[getChar2Glyph()[0]];
-                jInfo.weight -= gji.weight;
-                if (jInfo.grow) {
-                    jInfo.growLimit -= gji.growLeftLimit;
-                    if (gji.growAbsorb) {
-                        jInfo.absorbedWeight -= gji.weight;
-                    }
-                } else {
-                    jInfo.growLimit += gji.shrinkLeftLimit;
-                    if (gji.shrinkAbsorb) {
-                        jInfo.absorbedWeight -= gji.weight;
-                    }
-                }
-            }
-
-            if (haveLast) {   // Don't add padding after last char
-                GlyphJustificationInfo gji =
-                        getGlyphJustificationInfos()[getChar2Glyph()[lastChar]];
-                jInfo.weight -= gji.weight;
-                if (jInfo.grow) {
-                    jInfo.growLimit -= gji.growRightLimit;
-                    if (gji.growAbsorb) {
-                        jInfo.absorbedWeight -= gji.weight;
-                    }
-                } else {
-                    jInfo.growLimit += gji.shrinkRightLimit;
-                    if (gji.shrinkAbsorb) {
-                        jInfo.absorbedWeight -= gji.weight;
-                    }
-                }
-            }
-        }
-
-        /**
-         * Performs justification of the segment.
-         * Updates positions of individual characters.
-         * @param jInfos - justification information, gathered by the previous passes
-         * @return amount of growth or shrink of the segment
-         */
-        @Override
-        float doJustification(TextRunBreaker.JustificationInfo jInfos[]) {
-            int lastPriority =
-                    jInfos[jInfos.length-1] == null ?
-                    -1 : jInfos[jInfos.length-1].priority;
-
-            // Get the highest priority
-            int highestPriority = 0;
-            for (; highestPriority<jInfos.length; highestPriority++) {
-                if (jInfos[highestPriority] != null) {
-                    break;
-                }
-            }
-
-            if (highestPriority == jInfos.length) {
-                return 0;
-            }
-
-            TextRunBreaker.JustificationInfo firstInfo = jInfos[highestPriority];
-            TextRunBreaker.JustificationInfo lastInfo =
-                    lastPriority > 0 ? jInfos[lastPriority] : null;
-
-            boolean haveFirst = info.start <= firstInfo.firstIdx;
-            boolean haveLast = info.end >= (firstInfo.lastIdx + 1);
-
-            // Here we suppose that GLYPHS are ordered LEFT TO RIGHT
-            int firstGlyph = haveFirst ?
-                    getChar2Glyph()[firstInfo.firstIdx - info.start] :
-                    getChar2Glyph()[0];
-
-            int lastGlyph = haveLast ?
-                    getChar2Glyph()[firstInfo.lastIdx - info.start] :
-                    getChar2Glyph()[info.length - 1];
-            if (haveLast) {
-                lastGlyph--;
-            }
-
-            TextRunBreaker.JustificationInfo currInfo;
-            float glyphOffset = 0;
-            float positionIncrement = 0;
-            float sideIncrement = 0;
-
-            if (haveFirst) {  // Don't add padding before first char
-                GlyphJustificationInfo gji = getGlyphJustificationInfos()[firstGlyph];
-                currInfo = jInfos[gji.growPriority];
-                if (currInfo != null) {
-                    if (currInfo.useLimits) {
-                        if (currInfo.absorb) {
-                            glyphOffset += gji.weight * currInfo.absorbedGapPerUnit;
-                        } else if (
-                                lastInfo != null &&
-                                lastInfo.priority == currInfo.priority
-                        ) {
-                            glyphOffset += gji.weight * lastInfo.absorbedGapPerUnit;
-                        }
-                        glyphOffset +=
-                                firstInfo.grow ?
-                                gji.growRightLimit :
-                                -gji.shrinkRightLimit;
-                    } else {
-                        glyphOffset += gji.weight * currInfo.gapPerUnit;
-                    }
-                }
-
-                firstGlyph++;
-            }
-
-            if (firstInfo.grow) {
-                for (int i=firstGlyph; i<=lastGlyph; i++) {
-                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[i];
-                    currInfo = jInfos[gji.growPriority];
-                    if (currInfo == null) {
-                        // We still have to increment glyph position
-                        Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
-                        glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
-                        getGlyphVector().setGlyphPosition(i, glyphPos);
-
-                        continue;
-                    }
-
-                    if (currInfo.useLimits) {
-                        glyphOffset += gji.growLeftLimit;
-                        if (currInfo.absorb) {
-                            sideIncrement = gji.weight * currInfo.absorbedGapPerUnit;
-                            glyphOffset += sideIncrement;
-                            positionIncrement = glyphOffset;
-                            glyphOffset += sideIncrement;
-                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
-                            sideIncrement = gji.weight * lastInfo.absorbedGapPerUnit;
-                            glyphOffset += sideIncrement;
-                            positionIncrement = glyphOffset;
-                            glyphOffset += sideIncrement;
-                        } else {
-                            positionIncrement = glyphOffset;
-                        }
-                        glyphOffset += gji.growRightLimit;
-                    } else {
-                        sideIncrement = gji.weight * currInfo.gapPerUnit;
-                        glyphOffset += sideIncrement;
-                        positionIncrement = glyphOffset;
-                        glyphOffset += sideIncrement;
-                    }
-
-                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
-                    glyphPos.setLocation(glyphPos.getX() + positionIncrement, glyphPos.getY());
-                    getGlyphVector().setGlyphPosition(i, glyphPos);
-                }
-            } else {
-                for (int i=firstGlyph; i<=lastGlyph; i++) {
-                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[i];
-                    currInfo = jInfos[gji.shrinkPriority];
-                    if (currInfo == null) {
-                        // We still have to increment glyph position
-                        Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
-                        glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
-                        getGlyphVector().setGlyphPosition(i, glyphPos);
-
-                        continue;
-                    }
-
-                    if (currInfo.useLimits) {
-                        glyphOffset -= gji.shrinkLeftLimit;
-                        if (currInfo.absorb) {
-                            sideIncrement = gji.weight * currInfo.absorbedGapPerUnit;
-                            glyphOffset += sideIncrement;
-                            positionIncrement = glyphOffset;
-                            glyphOffset += sideIncrement;
-                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
-                            sideIncrement = gji.weight * lastInfo.absorbedGapPerUnit;
-                            glyphOffset += sideIncrement;
-                            positionIncrement = glyphOffset;
-                            glyphOffset += sideIncrement;
-                        } else {
-                            positionIncrement = glyphOffset;
-                        }
-                        glyphOffset -= gji.shrinkRightLimit;
-                    } else {
-                        sideIncrement =  gji.weight * currInfo.gapPerUnit;
-                        glyphOffset += sideIncrement;
-                        positionIncrement = glyphOffset;
-                        glyphOffset += sideIncrement;
-                    }
-
-                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
-                    glyphPos.setLocation(glyphPos.getX() + positionIncrement, glyphPos.getY());
-                    getGlyphVector().setGlyphPosition(i, glyphPos);
-                }
-            }
-
-
-            if (haveLast) {   // Don't add padding after last char
-                lastGlyph++;
-
-                GlyphJustificationInfo gji = getGlyphJustificationInfos()[lastGlyph];
-                currInfo = jInfos[gji.growPriority];
-
-                if (currInfo != null) {
-                    if (currInfo.useLimits) {
-                        glyphOffset += firstInfo.grow ? gji.growLeftLimit : -gji.shrinkLeftLimit;
-                        if (currInfo.absorb) {
-                            glyphOffset += gji.weight * currInfo.absorbedGapPerUnit;
-                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
-                            glyphOffset += gji.weight * lastInfo.absorbedGapPerUnit;
-                        }
-                    } else {
-                        glyphOffset += gji.weight * currInfo.gapPerUnit;
-                    }
-                }
-
-                // Ajust positions of all glyphs after last glyph
-                for (int i=lastGlyph; i<getGlyphVector().getNumGlyphs()+1; i++) {
-                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
-                    glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
-                    getGlyphVector().setGlyphPosition(i, glyphPos);
-                }
-            } else { // Update position after last glyph in glyph vector -
-                // to get correct advance for it
-                Point2D glyphPos = getGlyphVector().getGlyphPosition(lastGlyph+1);
-                glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
-                getGlyphVector().setGlyphPosition(lastGlyph+1, glyphPos);
-            }
-
-            gjis = null; // We don't need justification infos any more
-            // Also we have to reset cached bounds and metrics
-            this.visualBounds = null;
-            this.logicalBounds = null;
-
-            return glyphOffset; // How much our segment grown or shrunk
-        }
-    }
-
-    public static class TextRunSegmentGraphic extends TextRunSegment {
-        GraphicAttribute ga;
-        int start;
-        int length;
-        float fullAdvance;
-
-        TextRunSegmentGraphic(GraphicAttribute attr, int len, int start) {
-            this.start = start;
-            length = len;
-            ga = attr;
-            metrics = new BasicMetrics(ga);
-            fullAdvance = ga.getAdvance() * length;
-        }
-
-        @Override
-        public Object clone() {
-            return new TextRunSegmentGraphic(ga, length, start);
-        }
-
-        // Renders this text run segment
-        @Override
-        void draw(Graphics2D g2d, float xOffset, float yOffset) {
-            if (decoration != null) {
-                TextDecorator.prepareGraphics(this, g2d, xOffset, yOffset);
-            }
-
-            float xPos = x + xOffset;
-            float yPos = y + yOffset;
-
-            for (int i=0; i < length; i++) {
-                ga.draw(g2d, xPos, yPos);
-                xPos += ga.getAdvance();
-            }
-
-            if (decoration != null) {
-                TextDecorator.drawTextDecorations(this, g2d, xOffset, yOffset);
-                TextDecorator.restoreGraphics(decoration, g2d);
-            }
-        }
-
-        // Returns visual bounds of this segment
-        @Override
-        Rectangle2D getVisualBounds() {
-            if (visualBounds == null) {
-                Rectangle2D bounds = ga.getBounds();
-
-                // First and last chars can be out of logical bounds, so we calculate
-                // (bounds.getWidth() - ga.getAdvance()) which is exactly the difference
-                bounds.setRect(
-                        bounds.getMinX() + x,
-                        bounds.getMinY() + y,
-                        bounds.getWidth() - ga.getAdvance() + getAdvance(),
-                        bounds.getHeight()
-                );
-                visualBounds = TextDecorator.extendVisualBounds(this, bounds, decoration);
-            }
-
-            return (Rectangle2D) visualBounds.clone();
-        }
-
-        @Override
-        Rectangle2D getLogicalBounds() {
-            if (logicalBounds == null) {
-                logicalBounds =
-                        new Rectangle2D.Float(
-                                x, y - metrics.ascent,
-                                getAdvance(), metrics.ascent + metrics.descent
-                        );
-            }
-
-            return (Rectangle2D) logicalBounds.clone();
-        }
-
-        @Override
-        float getAdvance() {
-            return fullAdvance;
-        }
-
-        @Override
-        float getAdvanceDelta(int start, int end) {
-            return ga.getAdvance() * (end - start);
-        }
-
-        @Override
-        int getCharIndexFromAdvance(float advance, int start) {
-            start -= this.start;
-
-            if (start < 0) {
-                start = 0;
-            }
-
-            int charOffset = (int) (advance/ga.getAdvance());
-
-            if (charOffset + start > length) {
-                return length + this.start;
-            }
-            return charOffset + start + this.start;
-        }
-
-        @Override
-        int getStart() {
-            return start;
-        }
-
-        @Override
-        int getEnd() {
-            return start + length;
-        }
-
-        @Override
-        int getLength() {
-            return length;
-        }
-
-        @Override
-        Shape getCharsBlackBoxBounds(int start, int limit) {
-            start -= this.start;
-            limit -= this.start;
-
-            if (limit > length) {
-                limit = length;
-            }
-
-            Rectangle2D charBounds = ga.getBounds();
-            charBounds.setRect(
-                    charBounds.getX() + ga.getAdvance() * start + x,
-                    charBounds.getY() + y,
-                    charBounds.getWidth() + ga.getAdvance() * (limit - start),
-                    charBounds.getHeight()
-            );
-
-            return charBounds;
-        }
-
-        @Override
-        float getCharPosition(int index) {
-            index -= start;
-            if (index > length) {
-                index = length;
-            }
-
-            return ga.getAdvance() * index + x;
-        }
-
-        @Override
-        float getCharAdvance(int index) {
-            return ga.getAdvance();
-        }
-
-        @Override
-        Shape getOutline() {
-            AffineTransform t = AffineTransform.getTranslateInstance(x, y);
-            return t.createTransformedShape(
-                    TextDecorator.extendOutline(this, getVisualBounds(), decoration)
-            );
-        }
-
-        @Override
-        boolean charHasZeroAdvance(int index) {
-            return false;
-        }
-
-        @Override
-        TextHitInfo hitTest(float hitX, float hitY) {
-            hitX -= x;
-
-            float tmp = hitX / ga.getAdvance();
-            int hitIndex = Math.round(tmp);
-
-            if (tmp > hitIndex) {
-                return TextHitInfo.leading(hitIndex + this.start);
-            }
-            return TextHitInfo.trailing(hitIndex + this.start);
-        }
-
-        @Override
-        void updateJustificationInfo(TextRunBreaker.JustificationInfo jInfo) {
-            // Do nothing
-        }
-
-        @Override
-        float doJustification(TextRunBreaker.JustificationInfo jInfos[]) {
-            // Do nothing
-            return 0;
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/BufferedImageGraphics2D.java b/awt/org/apache/harmony/awt/gl/image/BufferedImageGraphics2D.java
deleted file mode 100644
index f1d64fb..0000000
--- a/awt/org/apache/harmony/awt/gl/image/BufferedImageGraphics2D.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Alexey A. Petrenko
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.image;
-
-import java.awt.Graphics;
-import java.awt.GraphicsConfiguration;
-import java.awt.Rectangle;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.WritableRaster;
-
-import org.apache.harmony.awt.gl.CommonGraphics2D;
-import org.apache.harmony.awt.gl.Surface;
-import org.apache.harmony.awt.gl.render.JavaBlitter;
-import org.apache.harmony.awt.gl.render.NativeImageBlitter;
-
-/**
- * BufferedImageGraphics2D is implementation of CommonGraphics2D for
- * drawing on buffered images. 
- */
-public class BufferedImageGraphics2D extends CommonGraphics2D {
-    private BufferedImage bi = null;
-    private Rectangle bounds = null;
-
-    public BufferedImageGraphics2D(BufferedImage bi) {
-        super();
-        this.bi = bi;
-        this.bounds = new Rectangle(0, 0, bi.getWidth(), bi.getHeight());
-        clip(bounds);
-        dstSurf = Surface.getImageSurface(bi);
-        if(dstSurf.isNativeDrawable()){
-            blitter = NativeImageBlitter.getInstance();
-        }else{
-            blitter = JavaBlitter.getInstance();
-        }
-    }
-
-    @Override
-    public void copyArea(int x, int y, int width, int height, int dx, int dy) {
-    }
-
-    @Override
-    public Graphics create() {
-        BufferedImageGraphics2D res = new BufferedImageGraphics2D(bi);
-        copyInternalFields(res);
-        return res;
-    }
-
-    @Override
-    public GraphicsConfiguration getDeviceConfiguration() {
-        return null;
-    }
-
-    public ColorModel getColorModel() {
-        return bi.getColorModel();
-    }
-
-    public WritableRaster getWritableRaster() {
-        return bi.getRaster();
-    }
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/BufferedImageSource.java b/awt/org/apache/harmony/awt/gl/image/BufferedImageSource.java
deleted file mode 100644
index 0fe25a2..0000000
--- a/awt/org/apache/harmony/awt/gl/image/BufferedImageSource.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-
-package org.apache.harmony.awt.gl.image;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.DataBufferInt;
-import java.awt.image.DirectColorModel;
-import java.awt.image.ImageConsumer;
-import java.awt.image.ImageProducer;
-import java.awt.image.IndexColorModel;
-import java.awt.image.WritableRaster;
-import java.util.Hashtable;
-
-public class BufferedImageSource implements ImageProducer {
-
-    private Hashtable<?, ?> properties;
-    private ColorModel cm;
-    private WritableRaster raster;
-    private int width;
-    private int height;
-
-    private ImageConsumer ic;
-
-    public BufferedImageSource(BufferedImage image, Hashtable<?, ?> properties){
-        if(properties == null) {
-            this.properties = new Hashtable<Object, Object>();
-        } else {
-            this.properties = properties;
-        }
-
-        width = image.getWidth();
-        height = image.getHeight();
-        cm = image.getColorModel();
-        raster = image.getRaster();
-    }
-
-    public BufferedImageSource(BufferedImage image){
-        this(image, null);
-    }
-
-    public boolean isConsumer(ImageConsumer ic) {
-        return (this.ic == ic);
-    }
-
-    public void startProduction(ImageConsumer ic) {
-        addConsumer(ic);
-    }
-
-    public void requestTopDownLeftRightResend(ImageConsumer ic) {
-    }
-
-    public void removeConsumer(ImageConsumer ic) {
-        if (this.ic == ic) {
-            this.ic = null;
-        }
-    }
-
-    public void addConsumer(ImageConsumer ic) {
-        this.ic = ic;
-        startProduction();
-    }
-
-    private void startProduction(){
-        try {
-            ic.setDimensions(width, height);
-            ic.setProperties(properties);
-            ic.setColorModel(cm);
-            ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
-                    ImageConsumer.COMPLETESCANLINES |
-                    ImageConsumer.SINGLEFRAME |
-                    ImageConsumer.SINGLEPASS);
-            if(cm instanceof IndexColorModel &&
-                    raster.getTransferType() == DataBuffer.TYPE_BYTE ||
-                    cm instanceof ComponentColorModel &&
-                    raster.getTransferType() == DataBuffer.TYPE_BYTE &&
-                    raster.getNumDataElements() == 1){
-                DataBufferByte dbb = (DataBufferByte) raster.getDataBuffer();
-                byte data[] = dbb.getData();
-                int off = dbb.getOffset();
-                ic.setPixels(0, 0, width, height, cm, data, off, width);
-            }else if(cm instanceof DirectColorModel &&
-                    raster.getTransferType() == DataBuffer.TYPE_INT){
-                DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
-                int data[] = dbi.getData();
-                int off = dbi.getOffset();
-                ic.setPixels(0, 0, width, height, cm, data, off, width);
-            }else if(cm instanceof DirectColorModel &&
-                    raster.getTransferType() == DataBuffer.TYPE_BYTE){
-                DataBufferByte dbb = (DataBufferByte) raster.getDataBuffer();
-                byte data[] = dbb.getData();
-                int off = dbb.getOffset();
-                ic.setPixels(0, 0, width, height, cm, data, off, width);
-            }else{
-                ColorModel rgbCM = ColorModel.getRGBdefault();
-                int pixels[] = new int[width];
-                Object pix = null;
-                for(int y = 0; y < height; y++){
-                    for(int x = 0 ; x < width; x++){
-                        pix = raster.getDataElements(x, y, pix);
-                        pixels[x] = cm.getRGB(pix);
-                    }
-                    ic.setPixels(0, y, width, 1, rgbCM, pixels, 0, width);
-                }
-            }
-            ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
-        }catch (NullPointerException e){
-            if (ic != null) {
-                ic.imageComplete(ImageConsumer.IMAGEERROR);
-            }
-        }
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/ByteArrayDecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/ByteArrayDecodingImageSource.java
deleted file mode 100644
index cc6d7cf..0000000
--- a/awt/org/apache/harmony/awt/gl/image/ByteArrayDecodingImageSource.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-/*
- * Created on 10.02.2005
- *
- */
-package org.apache.harmony.awt.gl.image;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-
-public class ByteArrayDecodingImageSource extends DecodingImageSource {
-
-    byte imagedata[];
-    int imageoffset;
-    int imagelength;
-
-    public ByteArrayDecodingImageSource(byte imagedata[], int imageoffset,
-            int imagelength){
-        this.imagedata = imagedata;
-        this.imageoffset = imageoffset;
-        this.imagelength = imagelength;
-    }
-
-    public ByteArrayDecodingImageSource(byte imagedata[]){
-        this(imagedata, 0, imagedata.length);
-    }
-
-    @Override
-    protected boolean checkConnection() {
-        return true;
-    }
-
-    @Override
-    protected InputStream getInputStream() {
-        // BEGIN android-modified
-        // TODO: Why does a ByteArrayInputStream need to be buffered at all?
-        return new BufferedInputStream(new ByteArrayInputStream(imagedata,
-                        imageoffset, imagelength), 1024);
-        // END android-modified
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/DataBufferListener.java b/awt/org/apache/harmony/awt/gl/image/DataBufferListener.java
deleted file mode 100644
index 8793050..0000000
--- a/awt/org/apache/harmony/awt/gl/image/DataBufferListener.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- * Created on 13.03.2006
- *
- */
-package org.apache.harmony.awt.gl.image;
-
-public interface DataBufferListener {
-    
-    void dataChanged();
-    void dataTaken();
-    void dataReleased();
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/DecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/DecodingImageSource.java
deleted file mode 100644
index 958d691..0000000
--- a/awt/org/apache/harmony/awt/gl/image/DecodingImageSource.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-/*
- * Created on 18.01.2005
- */
-package org.apache.harmony.awt.gl.image;
-
-import java.awt.image.ImageConsumer;
-import java.awt.image.ImageProducer;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * This is an abstract class that encapsulates a main part of ImageProducer functionality
- * for the images being decoded by the native decoders, like PNG, JPEG and GIF.
- * It helps to integrate image decoders into producer/consumer model. It provides
- * functionality for working with several decoder instances and several image consumers
- * simultaneously.
- */
-public abstract class DecodingImageSource implements ImageProducer {
-    List<ImageConsumer> consumers = new ArrayList<ImageConsumer>(5);
-    List<ImageDecoder> decoders = new ArrayList<ImageDecoder>(5);
-    boolean loading;
-
-    ImageDecoder decoder;
-
-    protected abstract boolean checkConnection();
-
-    protected abstract InputStream getInputStream();
-
-    public synchronized void addConsumer(ImageConsumer ic) {
-        if (!checkConnection()) { // No permission for this consumer
-            ic.imageComplete(ImageConsumer.IMAGEERROR);
-            return;
-        }
-
-        ImageConsumer cons = findConsumer(consumers, ic);
-
-        if (cons == null) { // Try to look in the decoders
-            ImageDecoder d = null;
-
-            // Check for all existing decoders
-            for (Iterator<ImageDecoder> i = decoders.iterator(); i.hasNext();) {
-                d = i.next();
-                cons = findConsumer(d.consumers, ic);
-                if (cons != null) {
-                    break;
-                }
-            }
-        }
-
-        if (cons == null) { // Not found, add this consumer
-            consumers.add(ic);
-        }
-    }
-
-    /**
-     * This method stops sending data to the given consumer
-     * @param ic - consumer
-     */
-    private void abortConsumer(ImageConsumer ic) {
-        ic.imageComplete(ImageConsumer.IMAGEERROR);
-        consumers.remove(ic);
-    }
-
-    /**
-     * This method stops sending data to the list of consumers.
-     * @param consumersList - list of consumers
-     */
-    private void abortAllConsumers(List<ImageConsumer> consumersList) {
-        for (ImageConsumer imageConsumer : consumersList) {
-            abortConsumer(imageConsumer);
-        }
-    }
-
-    public synchronized void removeConsumer(ImageConsumer ic) {
-        ImageDecoder d = null;
-
-        // Remove in all existing decoders
-        for (Iterator<ImageDecoder> i = decoders.iterator(); i.hasNext();) {
-            d = i.next();
-            removeConsumer(d.consumers, ic);
-            if (d.consumers.size() <= 0) {
-                d.terminate();
-            }
-        }
-
-        // Remove in the current queue of consumers
-        removeConsumer(consumers, ic);
-    }
-
-    /**
-     * Static implementation of removeConsumer method
-     * @param consumersList - list of consumers
-     * @param ic - consumer to be removed
-     */
-    private static void removeConsumer(List<ImageConsumer> consumersList, ImageConsumer ic) {
-        ImageConsumer cons = null;
-
-        for (Iterator<ImageConsumer> i = consumersList.iterator(); i.hasNext();) {
-            cons = i.next();
-            if (cons.equals(ic)) {
-                i.remove();
-            }
-        }
-    }
-
-    public void requestTopDownLeftRightResend(ImageConsumer consumer) {
-        // Do nothing
-    }
-
-    public synchronized void startProduction(ImageConsumer ic) {
-        if (ic != null) {
-            addConsumer(ic);
-        }
-
-        if (!loading && consumers.size() > 0) {
-            ImageLoader.addImageSource(this);
-            loading = true;
-        }
-    }
-
-    public synchronized boolean isConsumer(ImageConsumer ic) {
-        ImageDecoder d = null;
-
-        // Check for all existing decoders
-        for (Iterator<ImageDecoder> i = decoders.iterator(); i.hasNext();) {
-            d = i.next();
-            if (findConsumer(d.consumers, ic) != null) {
-                return true;
-            }
-        }
-
-        // Check current queue of consumers
-        return findConsumer(consumers, ic) != null;
-    }
-
-    /**
-     * Checks if the consumer is in the list and returns it it is there
-     * @param consumersList - list of consumers
-     * @param ic - consumer
-     * @return consumer if found, null otherwise
-     */
-    private static ImageConsumer findConsumer(List<ImageConsumer> consumersList, ImageConsumer ic) {
-        ImageConsumer res = null;
-
-        for (Iterator<ImageConsumer> i = consumersList.iterator(); i.hasNext();) {
-            res = i.next();
-            if (res.equals(ic)) {
-                return res;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Use this method to finish decoding or lock the list of consumers
-     * for a particular decoder
-     * @param d - decoder
-     */
-    synchronized void lockDecoder(ImageDecoder d) {
-        if (d == decoder) {
-            decoder = null;
-            startProduction(null);
-        }
-    }
-
-    /**
-     * Tries to find an appropriate decoder for the input stream and adds it
-     * to the list of decoders
-     * @return created decoder
-     */
-    private ImageDecoder createDecoder() {
-        InputStream is = getInputStream();
-
-        ImageDecoder decoder;
-
-        if (is == null) {
-            decoder = null;
-        } else {
-            decoder = ImageDecoder.createDecoder(this, is);
-        }
-
-        if (decoder != null) {
-            synchronized (this) {
-                decoders.add(decoder);
-                this.decoder = decoder;
-                loading = false;
-                consumers = new ArrayList<ImageConsumer>(5); // Reset queue
-            }
-
-            return decoder;
-        }
-        // We were not able to find appropriate decoder
-        List<ImageConsumer> cs;
-        synchronized (this) {
-            cs = consumers;
-            consumers = new ArrayList<ImageConsumer>(5);
-            loading = false;
-        }
-        abortAllConsumers(cs);
-
-        return null;
-    }
-
-    /**
-     * Stop the given decoder and remove it from the list
-     * @param dr - decoder
-     */
-    private synchronized void removeDecoder(ImageDecoder dr) {
-        lockDecoder(dr);
-        decoders.remove(dr);
-    }
-
-    /**
-     * This method serves as an entry point.
-     * It starts the decoder and loads the image data.
-     */
-    public void load() {
-        synchronized (this) {
-            if (consumers.size() == 0) {
-                loading = false;
-                return;
-            }
-        }
-
-        ImageDecoder d = createDecoder();
-        if (d != null) {
-            try {
-                decoder.decodeImage();
-            } catch (IOException e) {
-                e.printStackTrace();
-            } finally {
-                removeDecoder(d);
-                abortAllConsumers(d.consumers);
-            }
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/FileDecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/FileDecodingImageSource.java
deleted file mode 100644
index 54d4664..0000000
--- a/awt/org/apache/harmony/awt/gl/image/FileDecodingImageSource.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-/*
- * Created on 20.01.2005
- */
-package org.apache.harmony.awt.gl.image;
-
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-
-public class FileDecodingImageSource extends DecodingImageSource {
-  String filename;
-
-  public FileDecodingImageSource(String file) {
-    SecurityManager security = System.getSecurityManager();
-    if (security != null) {
-        security.checkRead(file);
-    }
-
-    filename = file;
-  }
-
-  @Override
-protected boolean checkConnection() {
-      SecurityManager security = System.getSecurityManager();
-      if (security != null) {
-          try {
-            security.checkRead(filename);
-          } catch (SecurityException e) {
-              return false;
-          }
-      }
-
-      return true;
-  }
-
-  @Override
-protected InputStream getInputStream() {
-    try {
-      // BEGIN android-modified
-      return new BufferedInputStream(new FileInputStream(filename), 8192);
-      // END android-modified
-    } catch (FileNotFoundException e) {
-      return null;
-    }
-  }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/GifDecoder.java b/awt/org/apache/harmony/awt/gl/image/GifDecoder.java
deleted file mode 100644
index 7ecb15b..0000000
--- a/awt/org/apache/harmony/awt/gl/image/GifDecoder.java
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-/*
-* Created on 27.01.2005
-*/
-package org.apache.harmony.awt.gl.image;
-
-import java.awt.image.ColorModel;
-import java.awt.image.ImageConsumer;
-import java.awt.image.IndexColorModel;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.List;
-
-public class GifDecoder extends ImageDecoder {
-    // initializes proper field IDs
-    private static native void initIDs();
-
-    static {
-        System.loadLibrary("gl"); //$NON-NLS-1$
-        initIDs();
-    }
-
-    // ImageConsumer hints: common
-    private static final int baseHints =
-            ImageConsumer.SINGLEPASS | ImageConsumer.COMPLETESCANLINES |
-            ImageConsumer.SINGLEFRAME;
-    // ImageConsumer hints: interlaced
-    private static final int interlacedHints =
-            baseHints | ImageConsumer.RANDOMPIXELORDER;
-
-    // Impossible color value - no translucent pixels allowed
-    static final int IMPOSSIBLE_VALUE = 0x0FFFFFFF;
-
-    // I/O buffer
-    private static final int BUFFER_SIZE = 1024;
-    private byte buffer[] = new byte[BUFFER_SIZE];
-
-    GifDataStream gifDataStream = new GifDataStream();
-    GifGraphicBlock currBlock;
-
-    // Pointer to native structure which store decoding state
-    // between subsequent decoding/IO-suspension cycles
-    private long hNativeDecoder; // NULL initially
-
-    // Number of bytes eaten by the native decoder
-    private int bytesConsumed;
-
-    private boolean consumersPrepared;
-    private Hashtable<String, String> properties = new Hashtable<String, String>();
-
-    // Could be set up by java code or native method when
-    // transparent pixel index changes or local color table encountered
-    private boolean forceRGB;
-
-    private byte screenBuffer[];
-    private int screenRGBBuffer[];
-
-    public GifDecoder(DecodingImageSource src, InputStream is) {
-        super(src, is);
-    }
-
-    private static native int[] toRGB(byte imageData[], byte colormap[], int transparentColor);
-
-    private static native void releaseNativeDecoder(long hDecoder);
-
-    private native int decode(
-            byte input[],
-            int bytesInBuffer,
-            long hDecoder,
-            GifDataStream dataStream,
-            GifGraphicBlock currBlock
-            );
-
-    private int[] getScreenRGBBuffer() {
-        if (screenRGBBuffer == null) {
-            if (screenBuffer != null) {
-                int transparentColor =
-                        gifDataStream.logicalScreen.globalColorTable.cm.getTransparentPixel();
-                transparentColor = transparentColor > 0 ? transparentColor : IMPOSSIBLE_VALUE;
-                screenRGBBuffer =
-                        toRGB(
-                                screenBuffer,
-                                gifDataStream.logicalScreen.globalColorTable.colors,
-                                transparentColor
-                        );
-            } else {
-                int size = gifDataStream.logicalScreen.logicalScreenHeight *
-                        gifDataStream.logicalScreen.logicalScreenWidth;
-                screenRGBBuffer = new int[size];
-            }
-        }
-
-        return screenRGBBuffer;
-    }
-
-    private void prepareConsumers() {
-        GifLogicalScreen gls = gifDataStream.logicalScreen;
-        setDimensions(gls.logicalScreenWidth,
-                gls.logicalScreenHeight);
-        setProperties(properties);
-
-        currBlock = gifDataStream.graphicBlocks.get(0);
-        if (forceRGB) {
-            setColorModel(ColorModel.getRGBdefault());
-        } else {
-            setColorModel(gls.globalColorTable.getColorModel(currBlock.transparentColor));
-        }
-
-        // Fill screen buffer with the background or transparent color
-        if (forceRGB) {
-            int fillColor = 0xFF000000;
-            if (gls.backgroundColor != IMPOSSIBLE_VALUE) {
-                fillColor = gls.backgroundColor;
-            }
-
-            Arrays.fill(getScreenRGBBuffer(), fillColor);
-        } else {
-            int fillColor = 0;
-
-            if (gls.backgroundColor != IMPOSSIBLE_VALUE) {
-                fillColor = gls.backgroundColor;
-            } else {
-                fillColor = gls.globalColorTable.cm.getTransparentPixel();
-            }
-
-            screenBuffer = new byte[gls.logicalScreenHeight*gls.logicalScreenWidth];
-            Arrays.fill(screenBuffer, (byte) fillColor);
-        }
-
-        setHints(interlacedHints); // XXX - always random pixel order
-    }
-
-    @Override
-    public void decodeImage() throws IOException {
-        try {
-            int bytesRead = 0;
-            int needBytes, offset, bytesInBuffer = 0;
-            boolean eosReached = false;
-            GifGraphicBlock blockToDispose = null;
-
-            // Create new graphic block
-            if (currBlock == null) {
-                currBlock = new GifGraphicBlock();
-                gifDataStream.graphicBlocks.add(currBlock);
-            }
-
-            // Read from the input stream
-            for (;;) {
-                needBytes = BUFFER_SIZE - bytesInBuffer;
-                offset = bytesInBuffer;
-
-                bytesRead = inputStream.read(buffer, offset, needBytes);
-
-                if (bytesRead < 0) {
-                    eosReached = true;
-                    bytesRead = 0;
-                } // Don't break, maybe something left in buffer
-
-                // Keep track on how much bytes left in buffer
-                bytesInBuffer += bytesRead;
-
-                // Here we pass number of new bytes read from the input stream (bytesRead)
-                // since native decoder uses java buffer and doesn't have its own
-                // buffer. So it adds this number to the number of bytes left
-                // in buffer from the previous call.
-                int numLines = decode(
-                        buffer,
-                        bytesRead,
-                        hNativeDecoder,
-                        gifDataStream,
-                        currBlock);
-
-                // Keep track on how much bytes left in buffer
-                bytesInBuffer -= bytesConsumed;
-
-                if (
-                        !consumersPrepared &&
-                        gifDataStream.logicalScreen.completed &&
-                        gifDataStream.logicalScreen.globalColorTable.completed &&
-                        (currBlock.imageData != null || // Have transparent pixel filled
-                        currBlock.rgbImageData != null)
-                ) {
-                    prepareConsumers();
-                    consumersPrepared = true;
-                }
-
-                if (bytesConsumed < 0) {
-                    break; // Error exit
-                }
-
-                if (currBlock != null) {
-                    if (numLines != 0) {
-                        // Dispose previous image only before showing next
-                        if (blockToDispose != null) {
-                            blockToDispose.dispose();
-                            blockToDispose = null;
-                        }
-
-                        currBlock.sendNewData(this, numLines);
-                    }
-
-                    if (currBlock.completed && hNativeDecoder != 0) {
-                        blockToDispose = currBlock; // Dispose only before showing new pixels
-                        currBlock = new GifGraphicBlock();
-                        gifDataStream.graphicBlocks.add(currBlock);
-                    }
-                }
-
-                if (hNativeDecoder == 0) {
-                    break;
-                }
-
-                if (eosReached && numLines == 0) { // Maybe image is truncated...
-                    releaseNativeDecoder(hNativeDecoder);
-                    break;
-                }
-            }
-        } finally {
-            closeStream();
-        }
-
-        // Here all animation goes
-        // Repeat image loopCount-1 times or infinitely if loopCount = 0
-        if (gifDataStream.loopCount != 1) {
-            if (currBlock.completed == false) {
-                gifDataStream.graphicBlocks.remove(currBlock);
-            }
-
-            int numFrames = gifDataStream.graphicBlocks.size();
-            // At first last block will be disposed
-            GifGraphicBlock gb =
-                    gifDataStream.graphicBlocks.get(numFrames-1);
-
-            ImageLoader.beginAnimation();
-
-            while (gifDataStream.loopCount != 1) {
-                if (gifDataStream.loopCount != 0) {
-                    gifDataStream.loopCount--;
-                }
-
-                // Show all frames
-                for (int i=0; i<numFrames; i++) {
-                    gb.dispose();
-                    gb = gifDataStream.graphicBlocks.get(i);
-
-                    // Show one frame
-                    if (forceRGB) {
-                        setPixels(
-                                gb.imageLeft,
-                                gb.imageTop,
-                                gb.imageWidth,
-                                gb.imageHeight,
-                                ColorModel.getRGBdefault(),
-                                gb.getRgbImageData(),
-                                0,
-                                gb.imageWidth
-                        );
-                    } else {
-                        setPixels(
-                                gb.imageLeft,
-                                gb.imageTop,
-                                gb.imageWidth,
-                                gb.imageHeight,
-                                null,
-                                gb.imageData,
-                                0,
-                                gb.imageWidth
-                        );
-                    }
-                }
-            }
-            ImageLoader.endAnimation();
-        }
-
-        imageComplete(ImageConsumer.STATICIMAGEDONE);
-    }
-
-    void setComment(String newComment) {
-        Object currComment = properties.get("comment"); //$NON-NLS-1$
-
-        if (currComment == null) {
-            properties.put("comment", newComment); //$NON-NLS-1$
-        } else {
-            properties.put("comment", (String) currComment + "\n" + newComment); //$NON-NLS-1$ //$NON-NLS-2$
-        }
-
-        setProperties(properties);
-    }
-
-    class GifDataStream {
-        //  Indicates that reading of the whole data stream accomplished
-        boolean completed = false;
-
-        // Added to support Netscape 2.0 application
-        // extension block.
-        int loopCount = 1;
-
-        GifLogicalScreen logicalScreen = new GifLogicalScreen();
-        List<GifGraphicBlock> graphicBlocks = new ArrayList<GifGraphicBlock>(10); // Of GifGraphicBlocks
-
-        // Comments from the image
-        String comments[];
-    }
-
-    class GifLogicalScreen {
-        //  Indicates that reading of this block accomplished
-        boolean completed = false;
-
-        int logicalScreenWidth;
-        int logicalScreenHeight;
-
-        int backgroundColor = IMPOSSIBLE_VALUE;
-
-        GifColorTable globalColorTable = new GifColorTable();
-    }
-
-    class GifGraphicBlock {
-        //  Indicates that reading of this block accomplished
-        boolean completed = false;
-
-        final static int DISPOSAL_NONE = 0;
-        final static int DISPOSAL_NODISPOSAL = 1;
-        final static int DISPOSAL_BACKGROUND = 2;
-        final static int DISPOSAL_RESTORE = 3;
-
-        int disposalMethod;
-        int delayTime; // Multiplied by 10 already
-        int transparentColor = IMPOSSIBLE_VALUE;
-
-        int imageLeft;
-        int imageTop;
-        int imageWidth;
-        int imageHeight;
-
-        // Auxilliary variables to minimize computations
-        int imageRight;
-        int imageBottom;
-
-        boolean interlace;
-
-        // Don't need local color table - if it is specified
-        // image data are converted to RGB in the native code
-
-        byte imageData[] = null;
-        int rgbImageData[] = null;
-
-        private int currY = 0; // Current output scanline
-
-        int[] getRgbImageData() {
-            if (rgbImageData == null) {
-                rgbImageData =
-                        toRGB(
-                                imageData,
-                                gifDataStream.logicalScreen.globalColorTable.colors,
-                                transparentColor
-                        );
-                if (transparentColor != IMPOSSIBLE_VALUE) {
-                    transparentColor =
-                            gifDataStream.logicalScreen.globalColorTable.cm.getRGB(transparentColor);
-                    transparentColor &= 0x00FFFFFF;
-                }
-            }
-            return rgbImageData;
-        }
-
-        private void replaceTransparentPixels(int numLines) {
-            List<GifGraphicBlock> graphicBlocks = gifDataStream.graphicBlocks;
-            int prevBlockIndex = graphicBlocks.indexOf(this) - 1;
-
-            if (prevBlockIndex >= 0) {
-                int maxY = currY + numLines + imageTop;
-                int offset = currY * imageWidth;
-
-                // Update right and bottom coordinates
-                imageRight = imageLeft + imageWidth;
-                imageBottom = imageTop + imageHeight;
-
-                int globalWidth = gifDataStream.logicalScreen.logicalScreenWidth;
-                int pixelValue, imageOffset;
-                int rgbData[] = forceRGB ? getRgbImageData() : null;
-
-                for (int y = currY + imageTop; y < maxY; y++) {
-                    imageOffset = globalWidth * y + imageLeft;
-                    for (int x = imageLeft; x < imageRight; x++) {
-                        pixelValue = forceRGB ?
-                                rgbData[offset] :
-                                imageData[offset] & 0xFF;
-                        if (pixelValue == transparentColor) {
-                            if (forceRGB) {
-                                pixelValue = getScreenRGBBuffer() [imageOffset];
-                                rgbData[offset] = pixelValue;
-                            } else {
-                                pixelValue = screenBuffer [imageOffset];
-                                imageData[offset] = (byte) pixelValue;
-                            }
-                        }
-                        offset++;
-                        imageOffset++;
-                    } // for
-                } // for
-
-            } // if (prevBlockIndex >= 0)
-        }
-
-        public void sendNewData(GifDecoder decoder, int numLines) {
-            // Get values for transparent pixels
-            // from the perevious frames
-            if (transparentColor != IMPOSSIBLE_VALUE) {
-                replaceTransparentPixels(numLines);
-            }
-
-            if (forceRGB) {
-                decoder.setPixels(
-                        imageLeft,
-                        imageTop + currY,
-                        imageWidth,
-                        numLines,
-                        ColorModel.getRGBdefault(),
-                        getRgbImageData(),
-                        currY*imageWidth,
-                        imageWidth
-                );
-            } else {
-                decoder.setPixels(
-                        imageLeft,
-                        imageTop + currY,
-                        imageWidth,
-                        numLines,
-                        null,
-                        imageData,
-                        currY*imageWidth,
-                        imageWidth
-                );
-            }
-
-            currY += numLines;
-        }
-
-        public void dispose() {
-            imageComplete(ImageConsumer.SINGLEFRAMEDONE);
-
-            // Show current frame until delayInterval will not elapse
-            if (delayTime > 0) {
-                try {
-                    Thread.sleep(delayTime);
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
-                }
-            } else {
-                Thread.yield(); // Allow consumers to consume data
-            }
-
-            // Don't dispose if image is outside of the visible area
-            if (imageLeft > gifDataStream.logicalScreen.logicalScreenWidth ||
-                    imageTop > gifDataStream.logicalScreen.logicalScreenHeight) {
-                disposalMethod = DISPOSAL_NONE;
-            }
-
-            switch(disposalMethod) {
-                case DISPOSAL_BACKGROUND: {
-                    if (forceRGB) {
-                        getRgbImageData(); // Ensure that transparentColor is RGB, not index
-
-                        int data[] = new int[imageWidth*imageHeight];
-
-                        // Compatibility: Fill with transparent color if we have one
-                        if (transparentColor != IMPOSSIBLE_VALUE) {
-                            Arrays.fill(
-                                    data,
-                                    transparentColor
-                            );
-                        } else {
-                            Arrays.fill(
-                                    data,
-                                    gifDataStream.logicalScreen.backgroundColor
-                            );
-                        }
-
-                        setPixels(
-                                imageLeft,
-                                imageTop,
-                                imageWidth,
-                                imageHeight,
-                                ColorModel.getRGBdefault(),
-                                data,
-                                0,
-                                imageWidth
-                        );
-
-                        sendToScreenBuffer(data);
-                    } else {
-                        byte data[] = new byte[imageWidth*imageHeight];
-
-                        // Compatibility: Fill with transparent color if we have one
-                        if (transparentColor != IMPOSSIBLE_VALUE) {
-                            Arrays.fill(
-                                    data,
-                                    (byte) transparentColor
-                            );
-                        } else {
-                            Arrays.fill(
-                                    data,
-                                    (byte) gifDataStream.logicalScreen.backgroundColor
-                            );
-                        }
-
-                        setPixels(
-                                imageLeft,
-                                imageTop,
-                                imageWidth,
-                                imageHeight,
-                                null,
-                                data,
-                                0,
-                                imageWidth
-                        );
-
-                        sendToScreenBuffer(data);
-                    }
-                    break;
-                }
-                case DISPOSAL_RESTORE: {
-                    screenBufferToScreen();
-                    break;
-                }
-                case DISPOSAL_NONE:
-                case DISPOSAL_NODISPOSAL:
-                default: {
-                    // Copy transmitted data to the screen buffer
-                    Object data = forceRGB ? (Object) getRgbImageData() : imageData;
-                    sendToScreenBuffer(data);
-                    break;
-                }
-            }
-        }
-
-        private void sendToScreenBuffer(Object data) {
-            int dataInt[];
-            byte dataByte[];
-
-            int width = gifDataStream.logicalScreen.logicalScreenWidth;
-
-
-            if (forceRGB) {
-                dataInt = (int[]) data;
-
-                if (imageWidth == width) {
-                    System.arraycopy(dataInt,
-                            0,
-                            getScreenRGBBuffer(),
-                            imageLeft + imageTop*width,
-                            dataInt.length
-                    );
-                } else { // Each scanline
-                    copyScanlines(dataInt, getScreenRGBBuffer(), width);
-                }
-            } else {
-                dataByte = (byte[]) data;
-
-                if (imageWidth == width) {
-                    System.arraycopy(dataByte,
-                            0,
-                            screenBuffer,
-                            imageLeft + imageTop*width,
-                            dataByte.length
-                    );
-                } else { // Each scanline
-                    copyScanlines(dataByte, screenBuffer, width);
-                }
-            }
-        } // sendToScreenBuffer
-
-        private void copyScanlines(Object src, Object dst, int width) {
-            for (int i=0; i<imageHeight; i++) {
-                System.arraycopy(src,
-                        i*imageWidth,
-                        dst,
-                        imageLeft + i*width + imageTop*width,
-                        imageWidth
-                );
-            } // for
-        }
-
-        private void screenBufferToScreen() {
-            int width = gifDataStream.logicalScreen.logicalScreenWidth;
-
-            Object dst = forceRGB ?
-                    (Object) new int[imageWidth*imageHeight] :
-                    new byte[imageWidth*imageHeight];
-
-            Object src = forceRGB ?
-                    getScreenRGBBuffer() :
-                    (Object) screenBuffer;
-
-            int offset = 0;
-            Object toSend;
-
-            if (width == imageWidth) {
-                offset = imageWidth * imageTop;
-                toSend = src;
-            } else {
-                for (int i=0; i<imageHeight; i++) {
-                    System.arraycopy(src,
-                            imageLeft + i*width + imageTop*width,
-                            dst,
-                            i*imageWidth,
-                            imageWidth
-                    );
-                } // for
-                toSend = dst;
-            }
-
-            if (forceRGB) {
-                setPixels(
-                        imageLeft,
-                        imageTop,
-                        imageWidth,
-                        imageHeight,
-                        ColorModel.getRGBdefault(),
-                        (int [])toSend,
-                        offset,
-                        imageWidth
-                );
-            } else {
-                setPixels(
-                        imageLeft,
-                        imageTop,
-                        imageWidth,
-                        imageHeight,
-                        null,
-                        (byte [])toSend,
-                        offset,
-                        imageWidth
-                );
-            }
-        }
-    }
-
-    class GifColorTable {
-        //  Indicates that reading of this block accomplished
-        boolean completed = false;
-
-        IndexColorModel cm = null;
-        int size = 0; // Actual number of colors in the color table
-        byte colors[] = new byte[256*3];
-
-        IndexColorModel getColorModel(int transparentColor) {
-            if (cm != null) {
-                if (transparentColor != cm.getTransparentPixel()) {
-                    return cm = null; // Force default ARGB color model
-                }
-                return cm;
-            } else
-                if (completed && size > 0) {
-                    if (transparentColor == IMPOSSIBLE_VALUE) {
-                        return cm =
-                                new IndexColorModel(8, size, colors, 0, false);
-                    }
-
-                    if (transparentColor > size) {
-                        size = transparentColor + 1;
-                    }
-                    return cm =
-                            new IndexColorModel(8, size, colors, 0, false, transparentColor);
-                }
-
-            return cm = null; // Force default ARGB color model
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/ImageDecoder.java b/awt/org/apache/harmony/awt/gl/image/ImageDecoder.java
deleted file mode 100644
index d16128e..0000000
--- a/awt/org/apache/harmony/awt/gl/image/ImageDecoder.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-/*
- * Created on 18.01.2005
- */
-package org.apache.harmony.awt.gl.image;
-
-import com.android.internal.awt.AndroidImageDecoder;
-
-import java.awt.image.ColorModel;
-import java.awt.image.ImageConsumer;
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ConcurrentModificationException;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-
-
-/**
- * This class contains common functionality for all image decoders.
- */
-public abstract class ImageDecoder {
-    
-    /** Image types */
-    public static final int GENERIC_DECODER = 0;
-    public static final int JPG_DECODER = 1;
-    public static final int GIF_DECODER = 2;
-    public static final int PNG_DECODER = 3;
-    
-    private static final int MAX_BYTES_IN_SIGNATURE = 8;
-
-    protected List<ImageConsumer> consumers;
-    protected InputStream inputStream;
-    protected DecodingImageSource src;
-
-    protected boolean terminated;
-
-    /**
-     * Chooses appropriate image decoder by looking into input stream and checking
-     * the image signature.
-     * @param src - image producer, required for passing data to it from the
-     * created decoder via callbacks
-     * @param is - stream
-     * @return decoder
-     */
-    static ImageDecoder createDecoder(DecodingImageSource src, InputStream is) {
-        InputStream markable;
-
-        if (!is.markSupported()) {
-            // BEGIN android-modified
-            markable = new BufferedInputStream(is, 8192);
-            // END android-modified
-        } else {
-            markable = is;
-        }
-            
-        // Read the signature from the stream and then reset it back
-        try {
-            markable.mark(MAX_BYTES_IN_SIGNATURE);
-
-            byte[] signature = new byte[MAX_BYTES_IN_SIGNATURE];
-            markable.read(signature, 0, MAX_BYTES_IN_SIGNATURE);
-            markable.reset();
-
-            if ((signature[0] & 0xFF) == 0xFF &&
-                    (signature[1] & 0xFF) == 0xD8 &&
-                    (signature[2] & 0xFF) == 0xFF) { // JPEG
-                return loadDecoder(PNG_DECODER, src, is);
-            } else if ((signature[0] & 0xFF) == 0x47 && // G
-                    (signature[1] & 0xFF) == 0x49 && // I
-                    (signature[2] & 0xFF) == 0x46) { // F
-                return loadDecoder(GIF_DECODER, src, is);
-            } else if ((signature[0] & 0xFF) == 137 && // PNG signature: 137 80 78 71 13 10 26 10
-                    (signature[1] & 0xFF) == 80 &&
-                    (signature[2] & 0xFF) == 78 &&
-                    (signature[3] & 0xFF) == 71 &&
-                    (signature[4] & 0xFF) == 13 &&
-                    (signature[5] & 0xFF) == 10 &&
-                    (signature[6] & 0xFF) == 26 &&
-                    (signature[7] & 0xFF) == 10) {
-                return loadDecoder(JPG_DECODER, src, is);
-            }
-
-            return loadDecoder(GENERIC_DECODER, src, is);
-            
-        } catch (IOException e) { // Silently
-        }
-
-        return null;
-    }
-    
-    /*
-     * In the future, we might return different decoders for differen image types.
-     * But for now, we always return the generic one.
-     * Also: we could add a factory to load image decoder.
-     */
-    private static ImageDecoder loadDecoder(int type, DecodingImageSource src, 
-            InputStream is) {
-        return new AndroidImageDecoder(src, is);
-    }
-
-    protected ImageDecoder(DecodingImageSource _src, InputStream is) {
-        src = _src;
-        consumers = src.consumers;
-        inputStream = is;
-    }
-
-    public abstract void decodeImage() throws IOException;
-
-    public synchronized void closeStream() {
-        if (inputStream != null) {
-            try {
-                inputStream.close();
-            } catch (IOException e) {
-            }
-        }
-    }
-
-    /**
-     * Stops the decoding by interrupting the current decoding thread.
-     * Used when all consumers are removed and there's no more need to
-     * run the decoder.
-     */
-    public void terminate() {
-        src.lockDecoder(this);
-        closeStream();
-
-        AccessController.doPrivileged(
-                new PrivilegedAction<Void>() {
-                    public Void run() {
-                        Thread.currentThread().interrupt();
-                        return null;
-                    }
-                }
-        );
-
-        terminated = true;
-    }
-
-    protected void setDimensions(int w, int h) {
-        if (terminated) {
-            return;
-        }
-
-        for (ImageConsumer ic : consumers) {
-            ic.setDimensions(w, h);
-        }
-    }
-
-    protected void setProperties(Hashtable<?, ?> props) {
-        if (terminated) {
-            return;
-        }
-
-        for (ImageConsumer ic : consumers) {
-            ic.setProperties(props);
-        }
-    }
-
-    protected void setColorModel(ColorModel cm) {
-        if (terminated) {
-            return;
-        }
-
-        for (ImageConsumer ic : consumers) {
-            ic.setColorModel(cm);
-        }
-    }
-
-    protected void setHints(int hints) {
-        if (terminated) {
-            return;
-        }
-
-        for (ImageConsumer ic : consumers) {
-            ic.setHints(hints);
-        }
-    }
-
-    protected void setPixels(
-            int x, int y,
-            int w, int h,
-            ColorModel model,
-            byte pix[],
-            int off, int scansize
-            ) {
-        if (terminated) {
-            return;
-        }
-
-        src.lockDecoder(this);
-
-        for (ImageConsumer ic : consumers) {
-            ic.setPixels(x, y, w, h, model, pix, off, scansize);
-        }
-    }
-
-    protected void setPixels(
-            int x, int y,
-            int w, int h,
-            ColorModel model,
-            int pix[],
-            int off, int scansize
-            ) {
-        if (terminated) {
-            return;
-        }
-
-        src.lockDecoder(this);
-
-        for (ImageConsumer ic : consumers) {
-            ic.setPixels(x, y, w, h, model, pix, off, scansize);
-        }
-    }
-
-    protected void imageComplete(int status) {
-        if (terminated) {
-            return;
-        }
-
-        src.lockDecoder(this);
-
-        ImageConsumer ic = null;
-
-        for (Iterator<ImageConsumer> i = consumers.iterator(); i.hasNext();) {
-            try {
-                ic = i.next();
-            } catch (ConcurrentModificationException e) {
-                i = consumers.iterator();
-                continue;
-            }
-            ic.imageComplete(status);
-        }
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/ImageLoader.java b/awt/org/apache/harmony/awt/gl/image/ImageLoader.java
deleted file mode 100644
index 5c7d180..0000000
--- a/awt/org/apache/harmony/awt/gl/image/ImageLoader.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-/*
- * Created on 18.01.2005
- */
-package org.apache.harmony.awt.gl.image;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * This class provides functionality for simultaneous loading of
- * several images and running animation.
- */
-public class ImageLoader extends Thread {
-    // Contains ImageLoader objects
-    // and queue of image sources waiting to be loaded
-    static class ImageLoadersStorage {
-        private static final int MAX_THREADS = 5;
-        private static final int TIMEOUT = 4000;
-        static ImageLoadersStorage instance;
-
-        List<DecodingImageSource> queue = new LinkedList<DecodingImageSource>();
-        List<Thread> loaders = new ArrayList<Thread>(MAX_THREADS);
-
-        private int freeLoaders;
-
-        private ImageLoadersStorage() {}
-
-        static ImageLoadersStorage getStorage() {
-            if (instance == null) {
-                instance = new ImageLoadersStorage();
-            }
-
-            return instance;
-        }
-    }
-
-    ImageLoader() {
-        super();
-        setDaemon(true);
-    }
-
-    /**
-     * This method creates a new thread which is able to load an image
-     * or run animation (if the number of existing loader threads does not
-     * exceed the limit).
-     */
-    private static void createLoader() {
-        final ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
-
-        synchronized(storage.loaders) {
-            if (storage.loaders.size() < ImageLoadersStorage.MAX_THREADS) {
-                AccessController.doPrivileged(
-                        new PrivilegedAction<Void>() {
-                            public Void run() {
-                                ImageLoader loader = new ImageLoader();
-                                storage.loaders.add(loader);
-                                loader.start();
-                                return null;
-                            }
-                        });
-            }
-        }
-    }
-
-    /**
-     * Adds a new image source to the queue and starts a new loader
-     * thread if required
-     * @param imgSrc - image source
-     */
-    public static void addImageSource(DecodingImageSource imgSrc) {
-        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
-        synchronized(storage.queue) {
-            if (!storage.queue.contains(imgSrc)) {
-                storage.queue.add(imgSrc);
-            }
-            if (storage.freeLoaders == 0) {
-                createLoader();
-            }
-
-            storage.queue.notify();
-        }
-    }
-
-    /**
-     * Waits for a new ImageSource until timout expires.
-     * Loader thread will terminate after returning from this method
-     * if timeout expired and image source was not picked up from the queue.
-     * @return image source picked up from the queue or null if timeout expired
-     */
-    private static DecodingImageSource getWaitingImageSource() {
-        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
-
-        synchronized(storage.queue) {
-            DecodingImageSource isrc = null;
-
-            if (storage.queue.size() == 0) {
-                try {
-                    storage.freeLoaders++;
-                    storage.queue.wait(ImageLoadersStorage.TIMEOUT);
-                } catch (InterruptedException e) {
-                    return null;
-                } finally {
-                    storage.freeLoaders--;
-                }
-            }
-
-            if (storage.queue.size() > 0) {
-                isrc = storage.queue.get(0);
-                storage.queue.remove(0);
-            }
-
-            return isrc;
-        }
-    }
-
-    /**
-     * Entry point of the loader thread. Picks up image sources and
-     * runs decoders for them while there are available image sources in the queue.
-     * If there are no and timeout expires it terminates.
-     */
-    @Override
-    public void run() {
-        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
-
-        try {
-            while (storage.loaders.contains(this)) {
-                Thread.interrupted(); // Reset the interrupted flag
-                DecodingImageSource isrc = getWaitingImageSource();
-                if (isrc != null) {
-                    try {
-                        isrc.load();
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                } else {
-                    break; // Don't wait if timeout expired - terminate loader
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            synchronized(storage.loaders) {
-                storage.loaders.remove(Thread.currentThread());
-            }
-        }
-    }
-
-    /**
-     * Removes current thread from loaders (so we are able
-     * to create more loaders) and decreases its priority.
-     */
-    static void beginAnimation() {
-        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
-        Thread currThread = Thread.currentThread();
-
-        synchronized(storage) {
-            storage.loaders.remove(currThread);
-
-            if (storage.freeLoaders < storage.queue.size()) {
-                createLoader();
-            }
-        }
-
-        currThread.setPriority(Thread.MIN_PRIORITY);
-    }
-
-    /**
-     * Sends the current thread to wait for the new images to load
-     * if there are free placeholders for loaders
-     */
-    static void endAnimation() {
-        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
-        Thread currThread = Thread.currentThread();
-
-        synchronized(storage) {
-            if (storage.loaders.size() < ImageLoadersStorage.MAX_THREADS &&
-                    !storage.loaders.contains(currThread)
-            ) {
-                storage.loaders.add(currThread);
-            }
-        }
-
-        currThread.setPriority(Thread.NORM_PRIORITY);
-    }
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/JpegDecoder.java b/awt/org/apache/harmony/awt/gl/image/JpegDecoder.java
deleted file mode 100644
index 2e64427..0000000
--- a/awt/org/apache/harmony/awt/gl/image/JpegDecoder.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
-*  Licensed to the Apache Software Foundation (ASF) under one or more
-*  contributor license agreements.  See the NOTICE file distributed with
-*  this work for additional information regarding copyright ownership.
-*  The ASF licenses this file to You under the Apache License, Version 2.0
-*  (the "License"); you may not use this file except in compliance with
-*  the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-*  Unless required by applicable law or agreed to in writing, software
-*  distributed under the License is distributed on an "AS IS" BASIS,
-*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-*  See the License for the specific language governing permissions and
-*  limitations under the License.
-*/
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.image;
-
-import java.awt.image.*;
-import java.awt.color.ColorSpace;
-import java.awt.*;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Hashtable;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-public class JpegDecoder extends ImageDecoder {
-    // Only 2 output colorspaces expected. Others are converted into
-    // these ones.
-    // 1. Grayscale
-    public static final int JCS_GRAYSCALE = 1;
-    // 2. RGB
-    public static final int JCS_RGB = 2;
-
-    // Flags for the consumer, progressive JPEG
-    private static final int hintflagsProgressive =
-            ImageConsumer.SINGLEFRAME | // JPEG is a static image
-            ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
-            ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
-    // Flags for the consumer, singlepass JPEG
-    private static final int hintflagsSingle =
-            ImageConsumer.SINGLEPASS |
-            hintflagsProgressive;
-
-    // Buffer for the stream
-    private static final int BUFFER_SIZE = 1024;
-    private byte buffer[] = new byte[BUFFER_SIZE];
-
-    // 3 possible color models only
-    private static ColorModel cmRGB;
-    private static ColorModel cmGray;
-
-    // initializes proper field IDs
-    private static native void initIDs();
-
-    // Pointer to native structure which store decoding state
-    // between subsequent decoding/IO-suspension cycles
-    private long hNativeDecoder = 0; // NULL initially
-
-    private boolean headerDone = false;
-
-    // Next 4 members are filled by the native method (decompress).
-    // We can simply check if imageWidth is still negative to find
-    // out if they are already filled.
-    private int imageWidth = -1;
-    private int imageHeight = -1;
-    private boolean progressive = false;
-    private int jpegColorSpace = 0;
-
-    // Stores number of bytes consumed by the native decoder
-    private int bytesConsumed = 0;
-    // Stores current scanline returned by the decoder
-    private int currScanline = 0;
-
-    private ColorModel cm = null;
-
-    static {
-        System.loadLibrary("jpegdecoder"); //$NON-NLS-1$
-
-        cmGray = new ComponentColorModel(
-                ColorSpace.getInstance(ColorSpace.CS_GRAY),
-                false, false,
-                Transparency.OPAQUE, DataBuffer.TYPE_BYTE
-        );
-
-        // Create RGB color model
-        cmRGB = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);
-
-        initIDs();
-    }
-
-    public JpegDecoder(DecodingImageSource src, InputStream is) {
-        super(src, is);
-    }
-
-    /*
-    public JpegDecoder(InputStream iStream, ImageConsumer iConsumer) {
-    inputStream = iStream;
-    consumer = iConsumer;
-    }
-    */
-
-    /**
-     * @return - not NULL if call is successful
-     */
-    private native Object decode(
-            byte[] input,
-            int bytesInBuffer,
-            long hDecoder);
-
-    private static native void releaseNativeDecoder(long hDecoder);
-
-    @Override
-    public void decodeImage() throws IOException {
-        try {
-            int bytesRead = 0, dataLength = 0;
-            boolean eosReached = false;
-            int needBytes, offset, bytesInBuffer = 0;
-            byte byteOut[] = null;
-            int intOut[] = null;
-            // Read from the input stream
-            for (;;) {
-                needBytes = BUFFER_SIZE - bytesInBuffer;
-                offset = bytesInBuffer;
-
-                bytesRead = inputStream.read(buffer, offset, needBytes);
-
-                if (bytesRead < 0) {
-                    bytesRead = 0;//break;
-                    eosReached = true;
-                } // Don't break, maybe something left in buffer
-
-                // Keep track on how much bytes left in buffer
-                bytesInBuffer += bytesRead;
-
-                // Here we pass overall number of bytes left in the java buffer
-                // (bytesInBuffer) since jpeg decoder has its own buffer and consumes
-                // as many bytes as it can. If there are any unconsumed bytes
-                // it didn't add them to its buffer...
-                Object arr = decode(
-                        buffer,
-                        bytesInBuffer,
-                        hNativeDecoder);
-
-                // Keep track on how much bytes left in buffer
-                bytesInBuffer -= bytesConsumed;
-
-                if (!headerDone && imageWidth != -1) {
-                    returnHeader();
-                    headerDone = true;
-                }
-
-                if (bytesConsumed < 0) {
-                    break; // Error exit
-                }
-
-                if (arr instanceof byte[]) {
-                    byteOut = (byte[]) arr;
-                    dataLength = byteOut.length;
-                    returnData(byteOut, currScanline);
-                } else if (arr instanceof int[]) {
-                    intOut = (int[]) arr;
-                    dataLength = intOut.length;
-                    returnData(intOut, currScanline);
-                } else {
-                    dataLength = 0;
-                }
-
-                if (hNativeDecoder == 0) {
-                    break;
-                }
-
-                if (dataLength == 0 && eosReached) {
-                    releaseNativeDecoder(hNativeDecoder);
-                    break; // Probably image is truncated
-                }
-            }
-            imageComplete(ImageConsumer.STATICIMAGEDONE);
-        } catch (IOException e) {
-            throw e;
-        } finally {
-            closeStream();
-        }
-    }
-
-    public void returnHeader() {
-        setDimensions(imageWidth, imageHeight);
-
-        switch (jpegColorSpace) {
-            case JCS_GRAYSCALE: cm = cmGray; break;
-            case JCS_RGB: cm = cmRGB; break;
-            default: 
-                // awt.3D=Unknown colorspace
-                throw new IllegalArgumentException(Messages.getString("awt.3D")); //$NON-NLS-1$
-        }
-        setColorModel(cm);
-
-        setHints(progressive ? hintflagsProgressive : hintflagsSingle);
-
-        setProperties(new Hashtable<Object, Object>()); // Empty
-    }
-
-    // Send the data to the consumer
-    public void returnData(int data[], int currScanLine) {
-        // Send 1 or more scanlines to the consumer.
-        int numScanlines = data.length / imageWidth;
-        if (numScanlines > 0) {
-            setPixels(
-                    0, currScanLine - numScanlines,
-                    imageWidth, numScanlines,
-                    cm, data, 0, imageWidth
-            );
-        }
-    }
-
-    public void returnData(byte data[], int currScanLine) {
-        int numScanlines = data.length / imageWidth;
-        if (numScanlines > 0) {
-            setPixels(
-                    0, currScanLine - numScanlines,
-                    imageWidth, numScanlines,
-                    cm, data, 0, imageWidth
-            );
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/OffscreenImage.java b/awt/org/apache/harmony/awt/gl/image/OffscreenImage.java
deleted file mode 100644
index 3445f8e..0000000
--- a/awt/org/apache/harmony/awt/gl/image/OffscreenImage.java
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-/*
- * Created on 22.12.2004
- *
- */
-package org.apache.harmony.awt.gl.image;
-
-import java.awt.Graphics;
-import java.awt.Image;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.DataBufferInt;
-import java.awt.image.DirectColorModel;
-import java.awt.image.ImageConsumer;
-import java.awt.image.ImageObserver;
-import java.awt.image.ImageProducer;
-import java.awt.image.IndexColorModel;
-import java.awt.image.WritableRaster;
-import java.util.Hashtable;
-import java.util.Vector;
-
-import org.apache.harmony.awt.gl.ImageSurface;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-
-/**
- * This class represent implementation of abstract Image class
- */
-public class OffscreenImage extends Image implements ImageConsumer {
-
-    static final ColorModel rgbCM = ColorModel.getRGBdefault();
-    ImageProducer src;
-    BufferedImage image;
-    ColorModel cm;
-    WritableRaster raster;
-    boolean isIntRGB;
-    Hashtable<?, ?> properties;
-    Vector<ImageObserver> observers;
-    int width;
-    int height;
-    int imageState;
-    int hints;
-    private boolean producing;
-    private ImageSurface imageSurf;
-
-    public OffscreenImage(ImageProducer ip){
-        imageState = 0;
-        src = ip;
-        width = -1;
-        height = -1;
-        observers = new Vector<ImageObserver>();
-        producing = false;
-    }
-
-    @Override
-    public Object getProperty(String name, ImageObserver observer) {
-        if(name == null) {
-            // awt.38=Property name is not defined
-            throw new NullPointerException(Messages.getString("awt.38")); //$NON-NLS-1$
-        }
-        if(properties == null){
-            addObserver(observer);
-            startProduction();
-            if(properties == null) {
-                return null;
-            }
-        }
-        Object prop = properties.get(name);
-        if(prop == null) {
-            prop = UndefinedProperty;
-        }
-        return prop;
-    }
-
-    @Override
-    public ImageProducer getSource() {
-        return src;
-    }
-
-    @Override
-    public int getWidth(ImageObserver observer) {
-        if((imageState & ImageObserver.WIDTH) == 0){
-            addObserver(observer);
-            startProduction();
-            if((imageState & ImageObserver.WIDTH) == 0) {
-                return -1;
-            }
-        }
-        return width;
-    }
-
-    @Override
-    public int getHeight(ImageObserver observer) {
-        if((imageState & ImageObserver.HEIGHT) == 0){
-            addObserver(observer);
-            startProduction();
-            if((imageState & ImageObserver.HEIGHT) == 0) {
-                return -1;
-            }
-        }
-        return height;
-    }
-
-    @Override
-    public Graphics getGraphics() {
-        // awt.39=This method is not implemented for image obtained from ImageProducer
-        throw new UnsupportedOperationException(Messages.getString("awt.39")); //$NON-NLS-1$
-    }
-
-    @Override
-    public void flush() {
-        stopProduction();
-        imageUpdate(this, ImageObserver.ABORT, -1, -1, -1, -1);
-        imageState &= ~ImageObserver.ERROR;
-        imageState = 0;
-        image = null;
-        cm = null;
-        raster = null;
-        hints = 0;
-        width = -1;
-        height = -1;
-    }
-
-    public void setProperties(Hashtable<?, ?> properties) {
-        this.properties = properties;
-        imageUpdate(this, ImageObserver.PROPERTIES, 0, 0, width, height);
-    }
-
-    public void setColorModel(ColorModel cm) {
-        this.cm = cm;
-    }
-
-    /*
-     * We suppose what in case loading JPEG image then image has DirectColorModel
-     * and for infill image Raster will use setPixels method with int array.
-     *
-     * In case loading GIF image, for raster infill, is used setPixels method with
-     * byte array and Color Model is IndexColorModel. But Color Model may
-     * be changed during this process. Then is called setPixels method with
-     * int array and image force to default color model - int ARGB. The rest
-     * pixels are sending in DirectColorModel.
-     */
-    public void setPixels(int x, int y, int w, int h, ColorModel model,
-            int[] pixels, int off, int scansize) {
-        if(raster == null){
-            if(cm == null){
-                if(model == null) {
-                    // awt.3A=Color Model is null
-                    throw new NullPointerException(Messages.getString("awt.3A")); //$NON-NLS-1$
-                }
-                cm = model;
-            }
-            createRaster();
-        }
-
-        if(model == null) {
-            model = cm;
-        }
-        if(cm != model){
-            forceToIntARGB();
-        }
-
-        if(cm == model && model.getTransferType() == DataBuffer.TYPE_INT &&
-                raster.getNumDataElements() == 1){
-
-            DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
-            int data[] = dbi.getData();
-            int scanline = raster.getWidth();
-            int rof = dbi.getOffset() + y * scanline + x;
-            for(int lineOff = off, line = y; line < y + h;
-                line++, lineOff += scansize, rof += scanline){
-
-                System.arraycopy(pixels, lineOff, data, rof, w);
-            }
-
-        }else if(isIntRGB){
-            int buff[] = new int[w];
-            DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
-            int data[] = dbi.getData();
-            int scanline = raster.getWidth();
-            int rof = dbi.getOffset() + y * scanline + x;
-            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize,
-                rof += scanline) {
-
-                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
-                    buff[idx] = model.getRGB(pixels[sOff + idx]);
-                }
-                System.arraycopy(buff, 0, data, rof, w);
-            }
-        }else{
-            Object buf = null;
-            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize) {
-                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
-                    int rgb = model.getRGB(pixels[sOff + idx]);
-                    buf = cm.getDataElements(rgb, buf);
-                    raster.setDataElements(sx, sy, buf);
-                }
-            }
-        }
-
-        if (imageSurf != null) {
-            imageSurf.invalidate();
-        }
-
-        imageUpdate(this, ImageObserver.SOMEBITS, 0, 0, width, height);
-    }
-
-    public void setPixels(int x, int y, int w, int h, ColorModel model,
-            byte[] pixels, int off, int scansize) {
-
-        if(raster == null){
-            if(cm == null){
-                if(model == null) {
-                    // awt.3A=Color Model is null
-                    throw new NullPointerException(Messages.getString("awt.3A")); //$NON-NLS-1$
-                }
-                cm = model;
-            }
-            createRaster();
-        }
-        if(model == null) {
-            model = cm;
-        }
-        if(model != cm){
-            forceToIntARGB();
-        }
-
-        if(isIntRGB){
-            int buff[] = new int[w];
-            IndexColorModel icm = (IndexColorModel) model;
-            int colorMap[] = new int[icm.getMapSize()];
-            icm.getRGBs(colorMap);
-            DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
-            int data[] = dbi.getData();
-            int scanline = raster.getWidth();
-            int rof = dbi.getOffset() + y * scanline + x;
-            if(model instanceof IndexColorModel){
-
-                for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize,
-                    rof += scanline) {
-                    for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
-                        buff[idx] = colorMap[pixels[sOff + idx] & 0xff];
-                    }
-                    System.arraycopy(buff, 0, data, rof, w);
-                }
-            }else{
-
-                for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize,
-                    rof += scanline) {
-                    for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
-                        buff[idx] = model.getRGB(pixels[sOff + idx] & 0xff);
-                    }
-                    System.arraycopy(buff, 0, data, rof, w);
-                }
-            }
-        }else if(model == cm && model.getTransferType() == DataBuffer.TYPE_BYTE &&
-                raster.getNumDataElements() == 1){
-
-            DataBufferByte dbb = (DataBufferByte)raster.getDataBuffer();
-            byte data[] = dbb.getData();
-            int scanline = raster.getWidth();
-            int rof = dbb.getOffset() + y * scanline + x;
-            for(int lineOff = off, line = y; line < y + h;
-                line++, lineOff += scansize, rof += scanline){
-                System.arraycopy(pixels, lineOff, data, rof, w);
-            }
-        // BEGIN android-added (taken from newer Harmony)
-        }else if(model == cm && model.getTransferType() == DataBuffer.TYPE_BYTE &&
-                cm instanceof ComponentColorModel){
-
-            int nc = cm.getNumComponents();
-            byte stride[] = new byte[scansize];
-            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize) {
-                System.arraycopy(pixels, sOff, stride, 0, scansize);
-                
-                raster.setDataElements(x, sy, w, 1, stride);
-            }
-        // END android-added
-        }else {
-            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize) {
-                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
-                    int rgb = model.getRGB(pixels[sOff + idx] & 0xff);
-                    raster.setDataElements(sx, sy, cm.getDataElements(rgb, null));
-                }
-            }
-        }
-
-        if (imageSurf != null) {
-            imageSurf.invalidate();
-        }
-
-        imageUpdate(this, ImageObserver.SOMEBITS, 0, 0, width, height);
-    }
-
-    public void setDimensions(int width, int height) {
-        if(width <= 0 || height <= 0){
-            imageComplete(ImageObserver.ERROR);
-            return;
-        }
-
-        this.width = width;
-        this.height = height;
-        imageUpdate(this, (ImageObserver.HEIGHT | ImageObserver.WIDTH),
-                0, 0, width, height);
-    }
-
-    public void setHints(int hints) {
-        this.hints = hints;
-    }
-
-    public void imageComplete(int state) {
-        int flag;
-        switch(state){
-        case IMAGEABORTED:
-            flag = ImageObserver.ABORT;
-            break;
-        case IMAGEERROR:
-            flag = ImageObserver.ERROR | ImageObserver.ABORT;
-            break;
-        case SINGLEFRAMEDONE:
-            flag = ImageObserver.FRAMEBITS;
-            break;
-        case STATICIMAGEDONE:
-            flag = ImageObserver.ALLBITS;
-            break;
-        default:
-            // awt.3B=Incorrect ImageConsumer completion status
-            throw new IllegalArgumentException(Messages.getString("awt.3B")); //$NON-NLS-1$
-        }
-        imageUpdate(this, flag, 0, 0, width, height);
-
-        if((flag & (ImageObserver.ERROR | ImageObserver.ABORT |
-                ImageObserver.ALLBITS)) != 0 ) {
-            stopProduction();
-            observers.removeAllElements();
-        }
-    }
-
-    public /*synchronized*/ BufferedImage getBufferedImage(){
-        if(image == null){
-            ColorModel model = getColorModel();
-            WritableRaster wr = getRaster();
-            if(model != null && wr != null) {
-                image = new BufferedImage(model, wr, model.isAlphaPremultiplied(), null);
-            }
-        }
-        return image;
-    }
-
-    public /*synchronized*/ int checkImage(ImageObserver observer){
-        addObserver(observer);
-        return imageState;
-    }
-
-    public /*synchronized*/ boolean prepareImage(ImageObserver observer){
-        if((imageState & ImageObserver.ERROR) != 0){
-            if(observer != null){
-                observer.imageUpdate(this, ImageObserver.ERROR |
-                        ImageObserver.ABORT, -1, -1, -1, -1);
-            }
-            return false;
-        }
-        if((imageState & ImageObserver.ALLBITS) != 0) {
-            return true;
-        }
-        addObserver(observer);
-        startProduction();
-        return ((imageState & ImageObserver.ALLBITS) != 0);
-    }
-
-    public /*synchronized*/ ColorModel getColorModel(){
-        if(cm == null) {
-            startProduction();
-        }
-        return cm;
-    }
-
-    public /*synchronized*/ WritableRaster getRaster(){
-        if(raster == null) {
-            startProduction();
-        }
-        return raster;
-    }
-
-    public int getState(){
-        return imageState;
-    }
-
-    private /*synchronized*/ void addObserver(ImageObserver observer){
-        if(observer != null){
-          if(observers.contains(observer)) {
-            return;
-        }
-          if((imageState & ImageObserver.ERROR) != 0){
-              observer.imageUpdate(this, ImageObserver.ERROR |
-                      ImageObserver.ABORT, -1, -1, -1, -1);
-              return;
-          }
-          if((imageState & ImageObserver.ALLBITS) != 0){
-              observer.imageUpdate(this, imageState, 0, 0, width, height);
-              return;
-          }
-          observers.addElement(observer);
-        }
-    }
-
-    private synchronized void startProduction(){
-        if(!producing){
-            imageState &= ~ImageObserver.ABORT;
-            producing = true;
-            src.startProduction(this);
-        }
-    }
-
-    private synchronized void stopProduction(){
-        producing = false;
-        src.removeConsumer(this);
-    }
-
-    private void createRaster(){
-        try{
-            raster = cm.createCompatibleWritableRaster(width, height);
-            isIntRGB = false;
-            if(cm instanceof DirectColorModel){
-                DirectColorModel dcm = (DirectColorModel) cm;
-                if(dcm.getTransferType() == DataBuffer.TYPE_INT &&
-                        dcm.getRedMask() == 0xff0000 &&
-                        dcm.getGreenMask() == 0xff00 &&
-                        dcm.getBlueMask() == 0xff){
-                    isIntRGB = true;
-                }
-            }
-        }catch(Exception e){
-            cm = ColorModel.getRGBdefault();
-            raster = cm.createCompatibleWritableRaster(width, height);
-            isIntRGB = true;
-        }
-    }
-
-    private /*synchronized*/ void imageUpdate(Image img, int infoflags, int x, int y,
-            int width, int height){
-
-        imageState |= infoflags;
-        for (ImageObserver observer : observers) {
-            observer.imageUpdate(this, infoflags, x, y, width, height);
-        }
-
-//            notifyAll();
-    }
-
-    private void forceToIntARGB(){
-
-        int w = raster.getWidth();
-        int h = raster.getHeight();
-
-        WritableRaster destRaster = rgbCM.createCompatibleWritableRaster(w, h);
-
-        Object obj = null;
-        int pixels[] = new int[w];
-
-        if(cm instanceof IndexColorModel){
-            IndexColorModel icm = (IndexColorModel) cm;
-            int colorMap[] = new int[icm.getMapSize()];
-            icm.getRGBs(colorMap);
-
-            for (int y = 0; y < h; y++) {
-                obj = raster.getDataElements(0, y, w, 1, obj);
-                byte ba[] = (byte[]) obj;
-                for (int x = 0; x < ba.length; x++) {
-                    pixels[x] = colorMap[ba[x] & 0xff];
-                }
-                destRaster.setDataElements(0, y, w, 1, pixels);
-            }
-
-        }else{
-            for(int y = 0; y < h; y++){
-                for(int x = 0; x < w; x++){
-                    obj = raster.getDataElements(x, y, obj);
-                    pixels[x] = cm.getRGB(obj);
-                }
-                destRaster.setDataElements(0, y, w, 1, pixels);
-            }
-        }
-
-        synchronized(this){
-            if(imageSurf != null){
-                imageSurf.dispose();
-                imageSurf = null;
-            }
-            if(image != null){
-                image.flush();
-                image = null;
-            }
-            cm = rgbCM;
-            raster = destRaster;
-            isIntRGB = true;
-        }
-    }
-
-    public ImageSurface getImageSurface() {
-        if (imageSurf == null) {
-            ColorModel model = getColorModel();
-            WritableRaster wr = getRaster();
-            if(model != null && wr != null) {
-                imageSurf = new ImageSurface(model, wr);
-            }
-        }
-        return imageSurf;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/OrdinaryWritableRaster.java b/awt/org/apache/harmony/awt/gl/image/OrdinaryWritableRaster.java
deleted file mode 100644
index 1748e1b..0000000
--- a/awt/org/apache/harmony/awt/gl/image/OrdinaryWritableRaster.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-/*
- * Created on 30.09.2004
- *
- */
-package org.apache.harmony.awt.gl.image;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-import java.awt.image.SampleModel;
-import java.awt.image.WritableRaster;
-
-public class OrdinaryWritableRaster extends WritableRaster {
-
-    public OrdinaryWritableRaster(SampleModel sampleModel,
-            DataBuffer dataBuffer, Rectangle aRegion,
-            Point sampleModelTranslate, WritableRaster parent) {
-        super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
-    }
-
-    public OrdinaryWritableRaster(SampleModel sampleModel,
-            DataBuffer dataBuffer, Point origin) {
-        super(sampleModel, dataBuffer, origin);
-    }
-
-    public OrdinaryWritableRaster(SampleModel sampleModel, Point origin) {
-        super(sampleModel, origin);
-    }
-
-    @Override
-    public void setDataElements(int x, int y, Object inData) {
-        super.setDataElements(x, y, inData);
-    }
-
-    @Override
-    public void setDataElements(int x, int y, int w, int h, Object inData) {
-        super.setDataElements(x, y, w, h, inData);
-    }
-
-    @Override
-    public WritableRaster createWritableChild(int parentX, int parentY, int w,
-            int h, int childMinX, int childMinY, int[] bandList) {
-        return super.createWritableChild(parentX, parentY, w, h, childMinX,
-                childMinY, bandList);
-    }
-
-    @Override
-    public WritableRaster createWritableTranslatedChild(int childMinX,
-            int childMinY) {
-        return super.createWritableTranslatedChild(childMinX, childMinY);
-    }
-
-    @Override
-    public WritableRaster getWritableParent() {
-        return super.getWritableParent();
-    }
-
-    @Override
-    public void setRect(Raster srcRaster) {
-        super.setRect(srcRaster);
-    }
-
-    @Override
-    public void setRect(int dx, int dy, Raster srcRaster) {
-        super.setRect(dx, dy, srcRaster);
-    }
-
-    @Override
-    public void setDataElements(int x, int y, Raster inRaster) {
-        super.setDataElements(x, y, inRaster);
-    }
-
-    @Override
-    public void setPixel(int x, int y, int[] iArray) {
-        super.setPixel(x, y, iArray);
-    }
-
-    @Override
-    public void setPixel(int x, int y, float[] fArray) {
-        super.setPixel(x, y, fArray);
-    }
-
-    @Override
-    public void setPixel(int x, int y, double[] dArray) {
-        super.setPixel(x, y, dArray);
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, int[] iArray) {
-        super.setPixels(x, y, w, h, iArray);
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, float[] fArray) {
-        super.setPixels(x, y, w, h, fArray);
-    }
-
-    @Override
-    public void setPixels(int x, int y, int w, int h, double[] dArray) {
-        super.setPixels(x, y, w, h, dArray);
-    }
-
-    @Override
-    public void setSamples(int x, int y, int w, int h, int b, int[] iArray) {
-        super.setSamples(x, y, w, h, b, iArray);
-    }
-
-    @Override
-    public void setSamples(int x, int y, int w, int h, int b, float[] fArray) {
-        super.setSamples(x, y, w, h, b, fArray);
-    }
-
-    @Override
-    public void setSamples(int x, int y, int w, int h, int b, double[] dArray) {
-        super.setSamples(x, y, w, h, b, dArray);
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, int s) {
-        super.setSample(x, y, b, s);
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, float s) {
-        super.setSample(x, y, b, s);
-    }
-
-    @Override
-    public void setSample(int x, int y, int b, double s) {
-        super.setSample(x, y, b, s);
-    }
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/PngDecoder.java b/awt/org/apache/harmony/awt/gl/image/PngDecoder.java
deleted file mode 100644
index 7e85600..0000000
--- a/awt/org/apache/harmony/awt/gl/image/PngDecoder.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- *
- * @date: Jul 22, 2005
- */
-
-package org.apache.harmony.awt.gl.image;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Hashtable;
-import java.awt.color.ColorSpace;
-import java.awt.image.*;
-import java.awt.*;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-public class PngDecoder extends ImageDecoder {
-    // initializes proper field IDs
-    private static native void initIDs();
-
-    static {
-        System.loadLibrary("gl"); //$NON-NLS-1$
-        initIDs();
-    }
-
-    private static final int hintflags =
-            ImageConsumer.SINGLEFRAME | // PNG is a static image
-            ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
-            ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
-
-    // Each pixel is a grayscale sample.
-    private static final int PNG_COLOR_TYPE_GRAY = 0;
-    // Each pixel is an R,G,B triple.
-    private static final int PNG_COLOR_TYPE_RGB = 2;
-    // Each pixel is a palette index, a PLTE chunk must appear.
-    private static final int PNG_COLOR_TYPE_PLTE = 3;
-    // Each pixel is a grayscale sample, followed by an alpha sample.
-    private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
-    // Each pixel is an R,G,B triple, followed by an alpha sample.
-    private static final int PNG_COLOR_TYPE_RGBA = 6;
-
-    private static final int INPUT_BUFFER_SIZE = 4096;
-    private byte buffer[] = new byte[INPUT_BUFFER_SIZE];
-
-    // Buffers for decoded image data
-    byte byteOut[];
-    int intOut[];
-
-    // Native pointer to png decoder data
-    private long hNativeDecoder;
-
-    int imageWidth, imageHeight;
-    int colorType;
-    int bitDepth;
-    byte cmap[];
-
-    boolean transferInts; // Is transfer type int?.. or byte?
-    int dataElementsPerPixel = 1;
-
-    ColorModel cm;
-
-    int updateFromScanline; // First scanline to update
-    int numScanlines; // Number of scanlines to update
-
-    private native long decode(byte[] input, int bytesInBuffer, long hDecoder);
-
-    private static native void releaseNativeDecoder(long hDecoder);
-
-    public PngDecoder(DecodingImageSource src, InputStream is) {
-        super(src, is);
-    }
-
-    @Override
-    public void decodeImage() throws IOException {
-        try {
-            int bytesRead = 0;
-            int needBytes, offset, bytesInBuffer = 0;
-            // Read from the input stream
-            for (;;) {
-                needBytes = INPUT_BUFFER_SIZE - bytesInBuffer;
-                offset = bytesInBuffer;
-
-                bytesRead = inputStream.read(buffer, offset, needBytes);
-
-                if (bytesRead < 0) { // Break, nothing to read from buffer, image truncated?
-                    releaseNativeDecoder(hNativeDecoder);
-                    break;
-                }
-
-                // Keep track on how much bytes left in buffer
-                bytesInBuffer += bytesRead;
-                hNativeDecoder = decode(buffer, bytesInBuffer, hNativeDecoder);
-                // PNG decoder always consumes all bytes at once
-                bytesInBuffer = 0;
-
-                // if (bytesConsumed < 0)
-                //break; // Error exit
-
-                returnData();
-
-                // OK, we decoded all the picture in the right way...
-                if (hNativeDecoder == 0) {
-                    break;
-                }
-            }
-
-            imageComplete(ImageConsumer.STATICIMAGEDONE);
-        } catch (IOException e) {
-            throw e;
-        } catch (RuntimeException e) {
-            imageComplete(ImageConsumer.IMAGEERROR);
-            throw e;
-        } finally {
-            closeStream();
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private void returnHeader() { // Called from native code
-        setDimensions(imageWidth, imageHeight);
-
-        switch (colorType) {
-            case PNG_COLOR_TYPE_GRAY: {
-                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
-                    // awt.3C=Unknown PNG color type
-                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-                }
-
-                // Create gray color model
-                int numEntries = 1 << bitDepth;
-                int scaleFactor = 255 / (numEntries-1);
-                byte comps[] = new byte[numEntries];
-                for (int i = 0; i < numEntries; i++) {
-                    comps[i] = (byte) (i * scaleFactor);
-                }
-                cm = new IndexColorModel(/*bitDepth*/8, numEntries, comps, comps, comps);
-
-                transferInts = false;
-                break;
-            }
-
-            case PNG_COLOR_TYPE_RGB: {
-                if (bitDepth != 8) {
-                    // awt.3C=Unknown PNG color type
-                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-                }
-
-                cm = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);
-
-                transferInts = true;
-                break;
-            }
-
-            case PNG_COLOR_TYPE_PLTE: {
-                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
-                    // awt.3C=Unknown PNG color type
-                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-                }
-
-                cm = new IndexColorModel(/*bitDepth*/8, cmap.length / 3, cmap, 0, false);
-
-                transferInts = false;
-                break;
-            }
-
-            case PNG_COLOR_TYPE_GRAY_ALPHA: {
-                if (bitDepth != 8) {
-                    // awt.3C=Unknown PNG color type
-                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-                }
-
-                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
-                        true, false,
-                        Transparency.TRANSLUCENT,
-                        DataBuffer.TYPE_BYTE);
-
-                transferInts = false;
-                dataElementsPerPixel = 2;
-                break;
-            }
-
-            case PNG_COLOR_TYPE_RGBA: {
-                if (bitDepth != 8) {
-                    // awt.3C=Unknown PNG color type
-                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-                }
-
-                cm = ColorModel.getRGBdefault();
-
-                transferInts = true;
-                break;
-            }
-            default:
-                // awt.3C=Unknown PNG color type
-                throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
-        }
-
-        // Create output buffer
-        if (transferInts) {
-            intOut = new int[imageWidth * imageHeight];
-        } else {
-            byteOut = new byte[imageWidth * imageHeight * dataElementsPerPixel];
-        }
-
-        setColorModel(cm);
-
-        setHints(hintflags);
-        setProperties(new Hashtable<Object, Object>()); // Empty
-    }
-
-    // Send the data to the consumer
-    private void returnData() {
-        // Send 1 or more scanlines to the consumer.
-        if (numScanlines > 0) {
-            // Native decoder could have returned
-            // some data from the next pass, handle it here
-            int pass1, pass2;
-            if (updateFromScanline + numScanlines > imageHeight) {
-                pass1 = imageHeight - updateFromScanline;
-                pass2 = updateFromScanline + numScanlines - imageHeight;
-            } else {
-                pass1 = numScanlines;
-                pass2 = 0;
-            }
-
-            transfer(updateFromScanline, pass1);
-            if (pass2 != 0) {
-                transfer(0, pass2);
-            }
-        }
-    }
-
-    private void transfer(int updateFromScanline, int numScanlines) {
-        if (transferInts) {
-            setPixels(
-                    0, updateFromScanline,
-                    imageWidth, numScanlines,
-                    cm, intOut,
-                    updateFromScanline * imageWidth,
-                    imageWidth
-            );
-        } else {
-            setPixels(
-                    0, updateFromScanline,
-                    imageWidth, numScanlines,
-                    cm, byteOut,
-                    updateFromScanline * imageWidth * dataElementsPerPixel,
-                    imageWidth * dataElementsPerPixel
-            );
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/PngDecoderJava.java b/awt/org/apache/harmony/awt/gl/image/PngDecoderJava.java
deleted file mode 100644
index bfb2b51..0000000
--- a/awt/org/apache/harmony/awt/gl/image/PngDecoderJava.java
+++ /dev/null
@@ -1,298 +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 org.apache.harmony.awt.gl.image;
-
-// A simple PNG decoder source code in Java.
-import java.awt.Graphics;
-import java.awt.Insets;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.IndexColorModel;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.zip.CRC32;
-import java.util.zip.InflaterInputStream;
-
-//import javax.swing.JFrame;
-
-public class PngDecoderJava {
- 
-/*
-  public static void main(String[] args) throws Exception {
-    String name = "logo.png";
-    if (args.length > 0)
-      name = args[0];
-    InputStream in = PngDecoderJava.class.getResourceAsStream(name);
-    final BufferedImage image = PngDecoderJava.decode(in);
-    in.close();
-
-    JFrame f = new JFrame() {
-      public void paint(Graphics g) {
-        Insets insets = getInsets();
-        g.drawImage(image, insets.left, insets.top, null);
-      }
-    };
-    f.setVisible(true);
-    Insets insets = f.getInsets();
-    f.setSize(image.getWidth() + insets.left + insets.right, image
-        .getHeight()
-        + insets.top + insets.bottom);
-  }
-  */
-
-  public static BufferedImage decode(InputStream in) throws IOException {
-    DataInputStream dataIn = new DataInputStream(in);
-    readSignature(dataIn);
-    PNGData chunks = readChunks(dataIn);
-
-    long widthLong = chunks.getWidth();
-    long heightLong = chunks.getHeight();
-    if (widthLong > Integer.MAX_VALUE || heightLong > Integer.MAX_VALUE)
-      throw new IOException("That image is too wide or tall.");
-    int width = (int) widthLong;
-    int height = (int) heightLong;
-
-    ColorModel cm = chunks.getColorModel();
-    WritableRaster raster = chunks.getRaster();
-
-    BufferedImage image = new BufferedImage(cm, raster, false, null);
-
-    return image;
-  }
-
-  protected static void readSignature(DataInputStream in) throws IOException {
-    long signature = in.readLong();
-    if (signature != 0x89504e470d0a1a0aL)
-      throw new IOException("PNG signature not found!");
-  }
-
-  protected static PNGData readChunks(DataInputStream in) throws IOException {
-    PNGData chunks = new PNGData();
-
-    boolean trucking = true;
-    while (trucking) {
-      try {
-        // Read the length.
-        int length = in.readInt();
-        if (length < 0)
-          throw new IOException("Sorry, that file is too long.");
-        // Read the type.
-        byte[] typeBytes = new byte[4];
-        in.readFully(typeBytes);
-        // Read the data.
-        byte[] data = new byte[length];
-        in.readFully(data);
-        // Read the CRC.
-        long crc = in.readInt() & 0x00000000ffffffffL; // Make it
-        // unsigned.
-        if (verifyCRC(typeBytes, data, crc) == false)
-          throw new IOException("That file appears to be corrupted.");
-
-        PNGChunk chunk = new PNGChunk(typeBytes, data);
-        chunks.add(chunk);
-      } catch (EOFException eofe) {
-        trucking = false;
-      }
-    }
-    return chunks;
-  }
-
-  protected static boolean verifyCRC(byte[] typeBytes, byte[] data, long crc) {
-    CRC32 crc32 = new CRC32();
-    crc32.update(typeBytes);
-    crc32.update(data);
-    long calculated = crc32.getValue();
-    return (calculated == crc);
-  }
-}
-
-class PNGData {
-  private int mNumberOfChunks;
-
-  private PNGChunk[] mChunks;
-
-  public PNGData() {
-    mNumberOfChunks = 0;
-    mChunks = new PNGChunk[10];
-  }
-
-  public void add(PNGChunk chunk) {
-    mChunks[mNumberOfChunks++] = chunk;
-    if (mNumberOfChunks >= mChunks.length) {
-      PNGChunk[] largerArray = new PNGChunk[mChunks.length + 10];
-      System.arraycopy(mChunks, 0, largerArray, 0, mChunks.length);
-      mChunks = largerArray;
-    }
-  }
-
-  public long getWidth() {
-    return getChunk("IHDR").getUnsignedInt(0);
-  }
-
-  public long getHeight() {    return getChunk("IHDR").getUnsignedInt(4);
-  }
-
-  public short getBitsPerPixel() {
-    return getChunk("IHDR").getUnsignedByte(8);
-  }
-
-  public short getColorType() {
-    return getChunk("IHDR").getUnsignedByte(9);
-  }
-
-  public short getCompression() {
-    return getChunk("IHDR").getUnsignedByte(10);
-  }
-
-  public short getFilter() {
-    return getChunk("IHDR").getUnsignedByte(11);
-  }
-
-  public short getInterlace() {
-    return getChunk("IHDR").getUnsignedByte(12);
-  }
-
-  public ColorModel getColorModel() {
-    short colorType = getColorType();
-    int bitsPerPixel = getBitsPerPixel();
-
-    if (colorType == 3) {
-      byte[] paletteData = getChunk("PLTE").getData();
-      int paletteLength = paletteData.length / 3;
-      return new IndexColorModel(bitsPerPixel, paletteLength,
-          paletteData, 0, false);
-    }
-    System.out.println("Unsupported color type: " + colorType);
-    return null;
-  }
-
-  public WritableRaster getRaster() {
-    int width = (int) getWidth();
-    int height = (int) getHeight();
-    int bitsPerPixel = getBitsPerPixel();
-    short colorType = getColorType();
-
-    if (colorType == 3) {
-      byte[] imageData = getImageData();
-      //Orig: DataBuffer db = new DataBufferByte(imageData, imageData.length);
-      int len = Math.max(imageData.length, (width - 1) * (height -1));
-      DataBuffer db = new DataBufferByte(imageData, len);
-      WritableRaster raster = Raster.createPackedRaster(db, width,
-          height, bitsPerPixel, null);
-      return raster;
-    } else
-      System.out.println("Unsupported color type!");
-    return null;
-  }
-
-  public byte[] getImageData() {
-    try {
-      ByteArrayOutputStream out = new ByteArrayOutputStream();
-      // Write all the IDAT data into the array.
-      for (int i = 0; i < mNumberOfChunks; i++) {
-        PNGChunk chunk = mChunks[i];
-        if (chunk.getTypeString().equals("IDAT")) {
-          out.write(chunk.getData());
-        }
-      }
-      out.flush();
-      // Now deflate the data.
-      InflaterInputStream in = new InflaterInputStream(
-          new ByteArrayInputStream(out.toByteArray()));
-      ByteArrayOutputStream inflatedOut = new ByteArrayOutputStream();
-      int readLength;
-      byte[] block = new byte[8192];
-      while ((readLength = in.read(block)) != -1)
-        inflatedOut.write(block, 0, readLength);
-      inflatedOut.flush();
-      byte[] imageData = inflatedOut.toByteArray();
-      // Compute the real length.
-      int width = (int) getWidth();
-      int height = (int) getHeight();
-      int bitsPerPixel = getBitsPerPixel();
-      int length = width * height * bitsPerPixel / 8;
-
-      byte[] prunedData = new byte[length];
-
-      // We can only deal with non-interlaced images.
-      if (getInterlace() == 0) {
-        int index = 0;
-        for (int i = 0; i < length; i++) {
-          if ((i * 8 / bitsPerPixel) % width == 0) {
-            index++; // Skip the filter byte.
-          }
-          prunedData[i] = imageData[index++];
-        }
-      } else
-        System.out.println("Couldn't undo interlacing.");
-
-      return prunedData;
-    } catch (IOException ioe) {
-    }
-    return null;
-  }
-
-  public PNGChunk getChunk(String type) {
-    for (int i = 0; i < mNumberOfChunks; i++)
-      if (mChunks[i].getTypeString().equals(type))
-        return mChunks[i];
-    return null;
-  }
-}
-
-class PNGChunk {
-  private byte[] mType;
-
-  private byte[] mData;
-
-  public PNGChunk(byte[] type, byte[] data) {
-    mType = type;
-    mData = data;
-  }
-
-  public String getTypeString() {
-    try {
-      return new String(mType, "UTF8");
-    } catch (UnsupportedEncodingException uee) {
-      return "";
-    }
-  }
-
-  public byte[] getData() {
-    return mData;
-  }
-
-  public long getUnsignedInt(int offset) {
-    long value = 0;
-    for (int i = 0; i < 4; i++)
-      value += (mData[offset + i] & 0xff) << ((3 - i) * 8);
-    return value;
-  }
-
-  public short getUnsignedByte(int offset) {
-    return (short) (mData[offset] & 0x00ff);
-  }
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java
deleted file mode 100644
index a1899d6..0000000
--- a/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- */
-/*
- * Created on 10.02.2005
- *
- */
-package org.apache.harmony.awt.gl.image;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.security.Permission;
-
-public class URLDecodingImageSource extends DecodingImageSource {
-
-    URL url;
-
-    public URLDecodingImageSource(URL url){
-        SecurityManager security = System.getSecurityManager();
-        if (security != null) {
-            security.checkConnect(url.getHost(), url.getPort());
-            try {
-                Permission p = url.openConnection().getPermission();
-                security.checkPermission(p);
-            } catch (IOException e) {
-            }
-        }
-        this.url = url;
-    }
-
-    @Override
-    protected boolean checkConnection() {
-        SecurityManager security = System.getSecurityManager();
-        if (security != null) {
-            try {
-                security.checkConnect(url.getHost(), url.getPort());
-                return true;
-            } catch (SecurityException e) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    protected InputStream getInputStream() {
-        try{
-            URLConnection uc = url.openConnection();
-            // BEGIN android-modified
-            return new BufferedInputStream(uc.getInputStream(), 8192);
-            // END android-modified
-        }catch(IOException e){
-            return null;
-        }
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/render/Blitter.java b/awt/org/apache/harmony/awt/gl/render/Blitter.java
deleted file mode 100644
index 3b8012e..0000000
--- a/awt/org/apache/harmony/awt/gl/render/Blitter.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- * Created on 14.11.2005
- *
- */
-package org.apache.harmony.awt.gl.render;
-
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.geom.AffineTransform;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.gl.Surface;
-
-/**
- * The interface for objects which can drawing Images on other Images which have 
- * Graphics or on the display.  
- */
-public interface Blitter {
-
-    public abstract void blit(int srcX, int srcY, Surface srcSurf,
-            int dstX, int dstY, Surface dstSurf, int width, int height,
-            AffineTransform sysxform, AffineTransform xform,
-            Composite comp, Color bgcolor,
-            MultiRectArea clip);
-
-    public abstract void blit(int srcX, int srcY, Surface srcSurf,
-            int dstX, int dstY, Surface dstSurf, int width, int height,
-            AffineTransform sysxform, Composite comp, Color bgcolor,
-            MultiRectArea clip);
-
-    public abstract void blit(int srcX, int srcY, Surface srcSurf,
-            int dstX, int dstY, Surface dstSurf, int width, int height,
-            Composite comp, Color bgcolor, MultiRectArea clip);
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaArcRasterizer.java b/awt/org/apache/harmony/awt/gl/render/JavaArcRasterizer.java
deleted file mode 100644
index b643b41..0000000
--- a/awt/org/apache/harmony/awt/gl/render/JavaArcRasterizer.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.render;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-
-public class JavaArcRasterizer {
-
-    /**
-     * Adds particular arc segment to mra 
-     */
-    static void addX0LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
-        int x1 = 0;
-        for(int i = 0; i < line.length; i++) {
-            int x2 = line[i];
-            int y = cy + (b - i);
-            if (x1 <= finish && x2 >= start) {
-                mra.addRect(cx + Math.max(x1, start), y, cx + Math.min(x2, finish), y);
-            }
-            x1 = x2 + 1;
-        }
-    }
-
-    static void addX1LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
-        int x1 = 0;
-        for(int i = 0; i < line.length; i++) {
-            int x2 = line[i];
-            int y = cy - (b - i);
-            if (x1 <= finish && x2 >= start) {
-                mra.addRect(cx + Math.max(x1, start), y, cx + Math.min(x2, finish), y);
-            }
-            x1 = x2 + 1;
-        }
-    }
-
-    static void addX2LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
-        int x1 = 0;
-        for(int i = 0; i < line.length; i++) {
-            int x2 = line[i];
-            int y = cy - (b - i);
-            if (x1 <= finish && x2 >= start) {
-                mra.addRect(cx - Math.min(x2, finish), y, cx - Math.max(x1, start), y);
-            }
-            x1 = x2 + 1;
-        }
-    }
-
-    static void addX3LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
-        int x1 = 0;
-        for(int i = 0; i < line.length; i++) {
-            int x2 = line[i];
-            int y = cy + (b - i);
-            if (x1 <= finish && x2 >= start) {
-                mra.addRect(cx - Math.min(x2, finish), y, cx - Math.max(x1, start), y);
-            }
-            x1 = x2 + 1;
-        }
-    }
-
-    static void addY0LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
-        int y1 = 0;
-        for(int i = 0; i < line.length; i++) {
-            int x = cx + (b - i);
-            int y2 = line[i];
-            if (y1 <= finish && y2 >= start) {
-                mra.addRect(x, cy + Math.max(y1, start), x, cy + Math.min(y2, finish));
-            }
-            y1 = y2 + 1;
-        }
-    }
-
-    static void addY1LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
-        int y1 = 0;
-        for(int i = 0; i < line.length; i++) {
-            int x = cx - (b - i);
-            int y2 = line[i];
-            if (y1 <= finish && y2 >= start) {
-                mra.addRect(x, cy + Math.max(y1, start), x, cy + Math.min(y2, finish));
-            }
-            y1 = y2 + 1;
-        }
-    }
-
-    static void addY2LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
-        int y1 = 0;
-        for(int i = 0; i < line.length; i++) {
-            int x = cx - (b - i);
-            int y2 = line[i];
-            if (y1 <= finish && y2 >= start) {
-                mra.addRect(x, cy - Math.min(y2, finish), x, cy - Math.max(y1, start));
-            }
-            y1 = y2 + 1;
-        }
-    }
-
-    static void addY3LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
-        int y1 = 0;
-        for(int i = 0; i < line.length; i++) {
-            int x = cx + (b - i);
-            int y2 = line[i];
-            if (y1 <= finish && y2 >= start) {
-                mra.addRect(x, cy - Math.min(y2, finish), x, cy - Math.max(y1, start));
-            }
-            y1 = y2 + 1;
-        }
-    }
-
-    static void addX0Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
-        int prev = 0;
-        for(int i = 0; i < line.length; i++) {
-            mra.addRect(cx + prev, cy + (b - i), cx + line[i], cy + (b - i));
-            prev = line[i] + 1;
-        }
-    }
-
-    static void addX1Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
-        int prev = 0;
-        for(int i = 0; i < line.length; i++) {
-            mra.addRect(cx + prev, cy - (b - i), cx + line[i], cy - (b - i));
-            prev = line[i] + 1;
-        }
-    }
-
-    static void addX2Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
-        int prev = 0;
-        for(int i = 0; i < line.length; i++) {
-            mra.addRect(cx - line[i], cy - (b - i), cx - prev, cy - (b - i));
-            prev = line[i] + 1;
-        }
-    }
-
-    static void addX3Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
-        int prev = 0;
-        for(int i = 0; i < line.length; i++) {
-            mra.addRect(cx - line[i], cy + (b - i), cx - prev, cy + (b - i));
-            prev = line[i] + 1;
-        }
-    }
-
-    static void addY0Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
-        int prev = 0;
-        for(int i = 0; i < line.length; i++) {
-            mra.addRect(cx + (a - i), cy + prev, cx + (a - i), cy + line[i]);
-            prev = line[i] + 1;
-        }
-    }
-
-    static void addY1Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
-        int prev = 0;
-        for(int i = 0; i < line.length; i++) {
-            mra.addRect(cx - (a - i), cy + prev, cx - (a - i), cy + line[i]);
-            prev = line[i] + 1;
-        }
-    }
-
-    static void addY2Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
-        int prev = 0;
-        for(int i = 0; i < line.length; i++) {
-            mra.addRect(cx - (a - i), cy - line[i], cx - (a - i), cy - prev);
-            prev = line[i] + 1;
-        }
-    }
-
-    static void addY3Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
-        int prev = 0;
-        for(int i = 0; i < line.length; i++) {
-            mra.addRect(cx + (a - i), cy - line[i], cx + (a - i), cy - prev);
-            prev = line[i] + 1;
-        }
-    }
-
-    /**
-     * Returns normalized angle (from 0 to 360 degrees)
-     */
-    static double getNormAngle(double angle) {
-        angle -= Math.floor(angle / 360) * 360;
-        if (angle < 0) {
-            angle += 360;
-        }
-        return angle;
-    }
-
-    /**
-     * Creates arc lookup table
-     */
-    static int[] createLine(int a, int b, int xcount, int ycount) {
-        int[] buf = new int[b - ycount + 1];
-        int d = a * a + 2 * b * b - 2 * a * a * b;
-        int x = 0;
-        int y = b;
-        while (y >= ycount) {
-            if (d < 0) {
-                d = d + b * b * (4 * x + 6);
-            } else {
-                buf[b - y] = x;
-                d = d + b * b * (4 * x + 6) + 4 * a * a * (1 - y);
-                y--;
-            }
-            x++;
-        }
-        return buf;
-    }
-
-    /**
-     * Adds head/tail arc segment to MultiRectArea
-     */
-    static void addSeg(MultiRectArea mra, int cx1, int cy1, int cx2, int cy2, int a, int b, int[] xline, int[] yline, int[] bounds) {
-        switch(bounds[0]) {
-        case 0:
-            addY3LineSeg(mra, yline, cx2, cy1, a, bounds[1], bounds[2]);
-            break;
-        case 1:
-            addX1LineSeg(mra, xline, cx2, cy1, b, bounds[1], bounds[2]);
-            break;
-        case 2:
-            addX2LineSeg(mra, xline, cx1, cy1, b, bounds[1], bounds[2]);
-            break;
-        case 3:
-            addY2LineSeg(mra, yline, cx1, cy1, a, bounds[1], bounds[2]);
-            break;
-        case 4:
-            addY1LineSeg(mra, yline, cx1, cy2, a, bounds[1], bounds[2]);
-            break;
-        case 5:
-            addX3LineSeg(mra, xline, cx1, cy2, b, bounds[1], bounds[2]);
-            break;
-        case 6:
-            addX0LineSeg(mra, xline, cx2, cy2, b, bounds[1], bounds[2]);
-            break;
-        case 7:
-            addY0LineSeg(mra, yline, cx2, cy2, a, bounds[1], bounds[2]);
-            break;
-        }
-    }
-
-    /**
-     * Returns bounds for non quadratic arc head
-     */
-    static int[] getSegment1(double angle, int ax, int ay, int xcount, int ycount) {
-        int[] bounds = new int[3];
-        switch((int)(angle / 90)) {
-        case 0:
-            if (xcount <  ax) {
-                bounds[0] = 0; // Y3
-                bounds[1] = -ay;
-                bounds[2] = ycount;
-            } else {
-                bounds[0] = 1; // X1
-                bounds[1] = 0;
-                bounds[2] = ax;
-            }
-            break;
-        case 1:
-            if (xcount > -ax) {
-                bounds[0] = 2; // X2
-                bounds[1] = -ax;
-                bounds[2] = xcount;
-            } else {
-                bounds[0] = 3; // Y2
-                bounds[1] = 0;
-                bounds[2] = -ay;
-            }
-            break;
-        case 2:
-            if (xcount < -ax) {
-                bounds[0] = 4; // Y1
-                bounds[1] = ay;
-                bounds[2] = ycount;
-            } else {
-                bounds[0] = 5; // X3
-                bounds[1] = 0;
-                bounds[2] = -ax;
-            }
-            break;
-        case 3:
-            if (xcount >  ax) {
-                bounds[0] = 6; // X0
-                bounds[1] = ax;
-                bounds[2] = xcount;
-            } else {
-                bounds[0] = 7; // Y0
-                bounds[1] = 0;
-                bounds[2] = ay;
-            }
-            break;
-        }
-        return bounds;
-    }
-
-    /**
-     * Returns bounds for non quadratic arc tail
-     */
-    static int[] getSegment2(double angle, int ax, int ay, int xcount, int ycount) {
-        int[] bounds = new int[3];
-        switch((int)(angle / 90)) {
-        case 0:
-            if (xcount <  ax) {
-                bounds[0] = 0; // Y3
-                bounds[1] = 0;
-                bounds[2] = -ay;
-            } else {
-                bounds[0] = 1; // X1
-                bounds[1] = ax;
-                bounds[2] = xcount;
-            }
-            break;
-        case 1:
-            if (xcount > -ax) {
-                bounds[0] = 2; // X2
-                bounds[1] = 0;
-                bounds[2] = -ax;
-            } else {
-                bounds[0] = 3; // Y2
-                bounds[1] = -ay;
-                bounds[2] = ycount;
-            }
-            break;
-        case 2:
-            if (xcount < -ax) {
-                bounds[0] = 4; // Y1
-                bounds[1] = 0;
-                bounds[2] = ay;
-            } else {
-                bounds[0] = 5; // X3
-                bounds[1] = -ax;
-                bounds[2] = xcount;
-            }
-            break;
-        case 3:
-            if (xcount >  ax) {
-                bounds[0] = 6; // X0
-                bounds[1] = 0;
-                bounds[2] = ax;
-            } else {
-                bounds[0] = 7; // Y0
-                bounds[1] = ay;
-                bounds[2] = ycount;
-            }
-            break;
-        }
-        return bounds;
-    }
-
-    /**
-     * Rasterizes arc using clippind and dashing style
-     * @param x1 - the x coordinate of the left-upper corner of the arc bounds
-     * @param y1 - the y coordinate of the left-upper corner of the arc bounds
-     * @param width - the width of the arc bounds
-     * @param height - the height of the arc bounds
-     * @param angleStart - the start angle of the arc in degrees
-     * @param angleExtent - the angle extent in degrees
-     * @param clip - the MultiRectArea object of clipping area
-     * @return a MultiRectArea of rasterizer arc
-     */
-    public static MultiRectArea rasterize(int x, int y, int width, int height, double angleStart, double angleExtent, MultiRectArea clip) {
-
-        MultiRectArea mra = new MultiRectArea(false);
-
-        int cx1, cx2, cy1, cy2;
-        cx1 = cx2 = x + width / 2;
-        cy1 = cy2 = y + height / 2;
-
-        if (width % 2 == 0) {
-            cx2--;
-        }
-
-        if (height % 2 == 0) {
-            cy2--;
-        }
-
-        int a = width / 2;
-        int b = height / 2;
-        double c = Math.sqrt(a * a + b * b);
-
-        int xcount, ycount;
-        if (a < b) {
-            xcount = (int)Math.ceil(a * a / c);
-            ycount = (int)Math.floor(b * b / c);
-        } else {
-            xcount = (int)Math.floor(a * a / c);
-            ycount = (int)Math.ceil(b * b / c);
-        }
-
-        int[] xline = createLine(a, b, xcount, ycount);
-        int[] yline = createLine(b, a, ycount, xcount);
-
-        // Correct lines
-        int i = xline.length;
-        while(xline[--i] > xcount) {
-            xline[i] = xcount;
-        }
-
-        i = yline.length;
-        while(yline[--i] > ycount) {
-            yline[i] = ycount;
-        }
-
-        if (Math.abs(angleExtent) >= 360) {
-            // Rasterize CIRCLE
-            addX0Line(mra, xline, cx2, cy2, b);
-            addX1Line(mra, xline, cx2, cy1, b);
-            addX2Line(mra, xline, cx1, cy1, b);
-            addX3Line(mra, xline, cx1, cy2, b);
-            addY0Line(mra, yline, cx2, cy2, a);
-            addY1Line(mra, yline, cx1, cy2, a);
-            addY2Line(mra, yline, cx1, cy1, a);
-            addY3Line(mra, yline, cx2, cy1, a);
-        } else {
-            // Rasterize ARC
-            angleStart = getNormAngle(angleStart);
-            double angleFinish = getNormAngle(angleStart + angleExtent);
-
-            if (angleExtent < 0) {
-                double tmp = angleStart;
-                angleStart = angleFinish;
-                angleFinish = tmp;
-            }
-
-            double radStart = -Math.toRadians(angleStart);
-            double radFinish = -Math.toRadians(angleFinish);
-            int ax1 = (int)(a * Math.cos(radStart));
-            int ay1 = (int)(b * Math.sin(radStart));
-            int ax2 = (int)(a * Math.cos(radFinish));
-            int ay2 = (int)(b * Math.sin(radFinish));
-
-            int[] seg1 = getSegment1(angleStart, ax1, ay1, xcount, ycount);
-            int[] seg2 = getSegment2(angleFinish, ax2, ay2, xcount, ycount);
-
-            // Start and Finish located in the same quater
-            if (angleStart < angleFinish && seg1[0] == seg2[0]) {
-                if (seg1[0] % 2 == 0) {
-                    seg1[2] = seg2[2];
-                } else {
-                    seg1[1] = seg2[1];
-                }
-                addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg1);
-                return mra;
-            }
-
-            addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg1);
-            addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg2);
-
-            int startSeg = (seg1[0] + 1) % 8;
-            int finishSeg = seg2[0];
-
-            while (startSeg != finishSeg) {
-                switch(startSeg) {
-                case 0:
-                    addY3Line(mra, yline, cx2, cy1, a);
-                    break;
-                case 1:
-                    addX1Line(mra, xline, cx2, cy1, b);
-                    break;
-                case 2:
-                    addX2Line(mra, xline, cx1, cy1, b);
-                    break;
-                case 3:
-                    addY2Line(mra, yline, cx1, cy1, a);
-                    break;
-                case 4:
-                    addY1Line(mra, yline, cx1, cy2, a);
-                    break;
-                case 5:
-                    addX3Line(mra, xline, cx1, cy2, b);
-                    break;
-                case 6:
-                    addX0Line(mra, xline, cx2, cy2, b);
-                    break;
-                case 7:
-                    addY0Line(mra, yline, cx2, cy2, a);
-                    break;
-                }
-                startSeg = (startSeg + 1) % 8;
-            }
-        }
-
-        if (clip != null) {
-            mra.intersect(clip);
-        }
-
-        return mra;
-    }
-
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaBlitter.java b/awt/org/apache/harmony/awt/gl/render/JavaBlitter.java
deleted file mode 100644
index 67e0a59..0000000
--- a/awt/org/apache/harmony/awt/gl/render/JavaBlitter.java
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- * Created on 18.11.2005
- *
- */
-package org.apache.harmony.awt.gl.render;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.CompositeContext;
-import java.awt.Rectangle;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.ColorModel;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.gl.Surface;
-import org.apache.harmony.awt.gl.XORComposite;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * Java implenetation of the Blitter interface. Using when we can't 
- * draw images natively.
- */
-public class JavaBlitter implements Blitter {
-
-    /**
-     * Instead of multiplication and division we are using values from
-     * Lookup tables.
-     */
-    static byte mulLUT[][]; // Lookup table for multiplication
-    static byte divLUT[][]; // Lookup table for division
-
-    static{
-        mulLUT = new byte[256][256];
-        for(int i = 0; i < 256; i++){
-            for(int j = 0; j < 256; j++){
-                mulLUT[i][j] = (byte)((float)(i * j)/255 + 0.5f);
-            }
-        }
-        divLUT = new byte[256][256];
-        for(int i = 1; i < 256; i++){
-            for(int j = 0; j < i; j++){
-                divLUT[i][j] = (byte)(((float)j / 255) / ((float)i/ 255) * 255 + 0.5f);
-            }
-            for(int j = i; j < 256; j++){
-                divLUT[i][j] = (byte)255;
-            }
-        }
-    }
-
-    final static int AlphaCompositeMode = 1;
-    final static int XORMode = 2;
-
-    final static JavaBlitter inst = new JavaBlitter();
-
-    public static JavaBlitter getInstance(){
-        return inst;
-    }
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, AffineTransform sysxform,
-            AffineTransform xform, Composite comp, Color bgcolor,
-            MultiRectArea clip) {
-
-        if(xform == null){
-            blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
-                    sysxform, comp, bgcolor, clip);
-        }else{
-            double scaleX = xform.getScaleX();
-            double scaleY = xform.getScaleY();
-            double scaledX = dstX / scaleX;
-            double scaledY = dstY / scaleY;
-            AffineTransform at = new AffineTransform();
-            at.setToTranslation(scaledX, scaledY);
-            xform.concatenate(at);
-            sysxform.concatenate(xform);
-            blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
-                    sysxform, comp, bgcolor, clip);
-        }
-
-    }
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, AffineTransform sysxform,
-            Composite comp, Color bgcolor, MultiRectArea clip) {
-
-        if(sysxform == null) {
-            sysxform = new AffineTransform();
-        }
-        int type = sysxform.getType();
-        switch(type){
-            case AffineTransform.TYPE_TRANSLATION:
-                dstX += sysxform.getTranslateX();
-                dstY += sysxform.getTranslateY();
-            case AffineTransform.TYPE_IDENTITY:
-                 blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
-                        width, height, comp, bgcolor, clip);
-                break;
-            default:
-                int srcW = srcSurf.getWidth();
-                int srcH = srcSurf.getHeight();
-
-                int w = srcX + width < srcW ? width : srcW - srcX;
-                int h = srcY + height < srcH ? height : srcH - srcY;
-
-                ColorModel srcCM = srcSurf.getColorModel();
-                Raster srcR = srcSurf.getRaster().createChild(srcX, srcY,
-                        w, h, 0, 0, null);
-
-                ColorModel dstCM = dstSurf.getColorModel();
-                WritableRaster dstR = dstSurf.getRaster();
-
-                transformedBlit(srcCM, srcR, 0, 0, dstCM, dstR, dstX, dstY, w, h,
-                        sysxform, comp, bgcolor, clip);
-
-        }
-    }
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, Composite comp,
-            Color bgcolor, MultiRectArea clip) {
-
-        javaBlt(srcX, srcY, srcSurf.getWidth(), srcSurf.getHeight(),
-                srcSurf.getColorModel(), srcSurf.getRaster(), dstX, dstY,
-                dstSurf.getWidth(), dstSurf.getHeight(),
-                dstSurf.getColorModel(), dstSurf.getRaster(),
-                width, height, comp, bgcolor, clip);
-
-    }
-    public void javaBlt(int srcX, int srcY, int srcW, int srcH,
-            ColorModel srcCM, Raster srcRast, int dstX, int dstY,
-            int dstW, int dstH, ColorModel dstCM, WritableRaster dstRast,
-            int width, int height, Composite comp, Color bgcolor,
-            MultiRectArea clip){
-
-        int srcX2 = srcW - 1;
-        int srcY2 = srcH - 1;
-        int dstX2 = dstW - 1;
-        int dstY2 = dstH - 1;
-
-        if(srcX < 0){
-            width += srcX;
-            srcX = 0;
-        }
-        if(srcY < 0){
-            height += srcY;
-            srcY = 0;
-        }
-
-        if(dstX < 0){
-            width += dstX;
-            srcX -= dstX;
-            dstX = 0;
-        }
-        if(dstY < 0){
-            height += dstY;
-            srcY -= dstY;
-            dstY = 0;
-        }
-
-        if(srcX > srcX2 || srcY > srcY2) {
-            return;
-        }
-        if(dstX > dstX2 || dstY > dstY2) {
-            return;
-        }
-
-        if(srcX + width > srcX2) {
-            width = srcX2 - srcX + 1;
-        }
-        if(srcY + height > srcY2) {
-            height = srcY2 - srcY + 1;
-        }
-        if(dstX + width > dstX2) {
-            width = dstX2 - dstX + 1;
-        }
-        if(dstY + height > dstY2) {
-            height = dstY2 - dstY + 1;
-        }
-
-        if(width <= 0 || height <= 0) {
-            return;
-        }
-
-        int clipRects[];
-        if(clip != null) {
-            clipRects = clip.rect;
-        } else {
-            clipRects = new int[]{5, 0, 0, dstW - 1, dstH - 1};
-        }
-
-        boolean isAlphaComp = false;
-        int rule = 0;
-        float alpha = 0;
-        boolean isXORComp = false;
-        Color xorcolor = null;
-        CompositeContext cont = null;
-
-        if(comp instanceof AlphaComposite){
-            isAlphaComp = true;
-            AlphaComposite ac = (AlphaComposite) comp;
-            rule = ac.getRule();
-            alpha = ac.getAlpha();
-        }else if(comp instanceof XORComposite){
-            isXORComp = true;
-            XORComposite xcomp = (XORComposite) comp;
-            xorcolor = xcomp.getXORColor();
-        }else{
-            cont = comp.createContext(srcCM, dstCM, null);
-        }
-
-        for(int i = 1; i < clipRects[0]; i += 4){
-            int _sx = srcX;
-            int _sy = srcY;
-
-            int _dx = dstX;
-            int _dy = dstY;
-
-            int _w = width;
-            int _h = height;
-
-            int cx = clipRects[i];          // Clipping left top X
-            int cy = clipRects[i + 1];      // Clipping left top Y
-            int cx2 = clipRects[i + 2];     // Clipping right bottom X
-            int cy2 = clipRects[i + 3];     // Clipping right bottom Y
-
-            if(_dx > cx2 || _dy > cy2 || dstX2 < cx || dstY2 < cy) {
-                continue;
-            }
-
-            if(cx > _dx){
-                int shx = cx - _dx;
-                _w -= shx;
-                _dx = cx;
-                _sx += shx;
-            }
-
-            if(cy > _dy){
-                int shy = cy - _dy;
-                _h -= shy;
-                _dy = cy;
-                _sy += shy;
-            }
-
-            if(_dx + _w > cx2 + 1){
-                _w = cx2 - _dx + 1;
-            }
-
-            if(_dy + _h > cy2 + 1){
-                _h = cy2 - _dy + 1;
-            }
-
-            if(_sx > srcX2 || _sy > srcY2) {
-                continue;
-            }
-
-            if(isAlphaComp){
-                alphaCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
-                        dstCM, dstRast, _w, _h, rule, alpha, bgcolor);
-            }else if(isXORComp){
-                xorCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
-                        dstCM, dstRast, _w, _h, xorcolor);
-            }else{
-                Raster sr = srcRast.createChild(_sx, _sy, _w, _h, 0, 0, null);
-                WritableRaster dr = dstRast.createWritableChild(_dx, _dy,
-                        _w, _h, 0, 0, null);
-                cont.compose(sr, dr, dr);
-            }
-        }
-    }
-
-    void alphaCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
-            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
-            int width, int height, int rule, float alpha, Color bgcolor){
-
-        Object srcPixel, dstPixel;
-        int srcConstAllpha = (int)(alpha * 255 + 0.5f);
-        int srcRGB, dstRGB = 0;
-
-        if(bgcolor != null){
-            dstRGB = bgcolor.getRGB();
-        }
-
-        for(int sy = srcY, dy = dstY, srcYMax = srcY + height; sy < srcYMax; sy++, dy++){
-            for(int sx = srcX, dx = dstX, srcXMax = srcX + width; sx < srcXMax; sx++, dx++){
-                srcPixel = srcRast.getDataElements(sx, sy, null);
-                srcRGB = srcCM.getRGB(srcPixel);
-                if(bgcolor == null){
-                    dstPixel = dstRast.getDataElements(dx, dy, null);
-                    dstRGB = dstCM.getRGB(dstPixel);
-                }
-
-                dstRGB = compose(srcRGB, srcCM.isAlphaPremultiplied(),
-                        dstRGB, dstCM.hasAlpha(), dstCM.isAlphaPremultiplied(),
-                        rule, srcConstAllpha);
-
-                dstPixel = dstCM.getDataElements(dstRGB, null);
-                dstRast.setDataElements(dx,dy,dstPixel);
-            }
-        }
-    }
-
-    void xorCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
-            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
-            int width, int height, Color xorcolor){
-
-        Object srcPixel, dstPixel;
-        int xorRGB = xorcolor.getRGB();
-        int srcRGB, dstRGB;
-
-        for(int sy = srcY, dy = dstY, srcYMax = srcY + height; sy < srcYMax; sy++, dy++){
-            for(int sx = srcX, dx = dstX, srcXMax = srcX + width; sx < srcXMax; sx++, dx++){
-                srcPixel = srcRast.getDataElements(sx, sy, null);
-                dstPixel = dstRast.getDataElements(dx, dy, null);
-
-                srcRGB = srcCM.getRGB(srcPixel);
-                dstRGB = dstCM.getRGB(dstPixel);
-                dstRGB = srcRGB ^ xorRGB ^ dstRGB;
-
-                dstRGB = 0xff000000 | dstRGB;
-                dstPixel = dstCM.getDataElements(dstRGB, dstPixel);
-                dstRast.setDataElements(dx,dy,dstPixel);
-
-            }
-        }
-
-    }
-
-    private void transformedBlit(ColorModel srcCM, Raster srcR, int srcX, int srcY,
-            ColorModel dstCM, WritableRaster dstR, int dstX, int dstY,
-            int width, int height, AffineTransform at, Composite comp,
-            Color bgcolor,MultiRectArea clip) {
-
-        Rectangle srcBounds = new Rectangle(width, height);
-        Rectangle dstBlitBounds = new Rectangle(dstX, dstY, srcR.getWidth(), srcR.getHeight());
-
-        Rectangle transSrcBounds = getBounds2D(at, srcBounds).getBounds();
-        Rectangle transDstBlitBounds = getBounds2D(at, dstBlitBounds).getBounds();
-
-        int translateX = transDstBlitBounds.x - transSrcBounds.x;
-        int translateY = transDstBlitBounds.y - transSrcBounds.y;
-
-        AffineTransform inv = null;
-        try {
-             inv = at.createInverse();
-        } catch (NoninvertibleTransformException e) {
-            return;
-        }
-
-        double[] m = new double[6];
-        inv.getMatrix(m);
-
-        int clipRects[];
-        if(clip != null) {
-            clipRects = clip.rect;
-        } else {
-            clipRects = new int[]{5, 0, 0, dstR.getWidth(), dstR.getHeight()};
-        }
-
-        int compType = 0;
-        int srcConstAlpha = 0;
-        int rule = 0;
-        int bgRGB = bgcolor == null ? 0 : bgcolor.getRGB();
-        int srcRGB = 0, dstRGB = 0;
-        Object srcVal = null, dstVal = null;
-        if(comp instanceof AlphaComposite){
-            compType = AlphaCompositeMode;
-            AlphaComposite ac = (AlphaComposite) comp;
-            rule = ac.getRule();
-            srcConstAlpha = (int)(ac.getAlpha() * 255 + 0.5f);
-        }else if(comp instanceof XORComposite){
-            compType = XORMode;
-            XORComposite xor = (XORComposite) comp;
-            bgRGB = xor.getXORColor().getRGB();
-        }
-
-        for(int i = 1; i < clipRects[0]; i += 4){
-            Rectangle dstBounds = new Rectangle(clipRects[i], clipRects[i + 1], 0, 0);
-            dstBounds.add(clipRects[i + 2] + 1, clipRects[i + 1]);
-            dstBounds.add(clipRects[i + 2] + 1, clipRects[i + 3] + 1);
-            dstBounds.add(clipRects[i], clipRects[i + 3] + 1);
-
-            Rectangle bounds = dstBounds.intersection(transDstBlitBounds);
-
-            int minSrcX = srcBounds.x;
-            int minSrcY = srcBounds.y;
-            int maxSrcX = minSrcX + srcBounds.width;
-            int maxSrcY = minSrcY + srcBounds.height;
-
-            int minX = bounds.x;
-            int minY = bounds.y;
-            int maxX = minX + bounds.width;
-            int maxY = minY + bounds.height;
-
-            int hx = (int)((m[0] * 256) + 0.5);
-            int hy = (int)((m[1] * 256) + 0.5);
-            int vx = (int)((m[2] * 256) + 0.5);
-            int vy = (int)((m[3] * 256) + 0.5);
-            int sx = (int)((m[4] + m[0] * (bounds.x - translateX) + m[2] * (bounds.y - translateY)) * 256 + 0.5);
-            int sy = (int)((m[5] + m[1] * (bounds.x - translateX) + m[3] * (bounds.y - translateY)) * 256 + 0.5);
-
-            vx -= hx * bounds.width;
-            vy -= hy * bounds.width;
-
-            for(int y = minY; y < maxY; y++) {
-                for(int x = minX; x < maxX; x++) {
-                    int px = sx >> 8;
-                    int py = sy >> 8;
-                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
-                        switch(compType){
-                            case AlphaCompositeMode:
-                                srcVal = srcR.getDataElements(px , py , null);
-                                srcRGB = srcCM.getRGB(srcVal);
-                                if(bgcolor != null){
-                                    dstRGB = bgRGB;
-                                }else{
-                                    dstVal = dstR.getDataElements(x, y, null);
-                                    dstRGB = dstCM.getRGB(dstVal);
-                                }
-                                dstRGB = compose(srcRGB, srcCM.isAlphaPremultiplied(),
-                                        dstRGB, dstCM.hasAlpha(), dstCM.isAlphaPremultiplied(),
-                                        rule, srcConstAlpha);
-                                dstVal = dstCM.getDataElements(dstRGB, null);
-                                dstR.setDataElements(x, y, dstVal);
-                                break;
-
-                            case XORMode:
-                                srcVal = srcR.getDataElements(px , py , null);
-                                srcRGB = srcCM.getRGB(srcVal);
-                                dstVal = dstR.getDataElements(x, y, null);
-                                dstRGB = dstCM.getRGB(dstVal);
-                                dstRGB = srcRGB ^ bgRGB;
-
-                                dstRGB = 0xff000000 | dstRGB;
-                                dstVal = dstCM.getDataElements(dstRGB, null);
-                                dstR.setDataElements(x, y, dstVal);
-                                break;
-
-                            default:
-                                // awt.37=Unknown  composite type {0}
-                                throw new IllegalArgumentException(Messages.getString("awt.37", //$NON-NLS-1$
-                                        comp.getClass()));
-                        }
-                    }
-                    sx += hx;
-                    sy += hy;
-                }
-                sx += vx;
-                sy += vy;
-            }
-        }
-
-    }
-
-    private Rectangle2D getBounds2D(AffineTransform at, Rectangle r) {
-        int x = r.x;
-        int y = r.y;
-        int width = r.width;
-        int height = r.height;
-
-        float[] corners = {
-            x, y,
-            x + width, y,
-            x + width, y + height,
-            x, y + height
-        };
-
-        at.transform(corners, 0, corners, 0, 4);
-
-        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0);
-        bounds.add(corners[2], corners[3]);
-        bounds.add(corners[4], corners[5]);
-        bounds.add(corners[6], corners[7]);
-
-        return bounds;
-    }
-
-    private int compose(int srcRGB, boolean isSrcAlphaPre,
-            int dstRGB, boolean dstHasAlpha, boolean isDstAlphaPre,
-            int rule, int srcConstAlpha){
-
-        int sa, sr, sg, sb, da, dr, dg, db;
-
-        sa = (srcRGB >> 24) & 0xff;
-        sr = (srcRGB >> 16) & 0xff;
-        sg = (srcRGB >> 8) & 0xff;
-        sb = srcRGB & 0xff;
-
-        if(isSrcAlphaPre){
-            sa = mulLUT[srcConstAlpha][sa] & 0xff;
-            sr = mulLUT[srcConstAlpha][sr] & 0xff;
-            sg = mulLUT[srcConstAlpha][sg] & 0xff;
-            sb = mulLUT[srcConstAlpha][sb] & 0xff;
-        }else{
-            sa = mulLUT[srcConstAlpha][sa] & 0xff;
-            sr = mulLUT[sa][sr] & 0xff;
-            sg = mulLUT[sa][sg] & 0xff;
-            sb = mulLUT[sa][sb] & 0xff;
-        }
-
-        da = (dstRGB >> 24) & 0xff;
-        dr = (dstRGB >> 16) & 0xff;
-        dg = (dstRGB >> 8) & 0xff;
-        db = dstRGB & 0xff;
-
-        if(!isDstAlphaPre){
-            dr = mulLUT[da][dr] & 0xff;
-            dg = mulLUT[da][dg] & 0xff;
-            db = mulLUT[da][db] & 0xff;
-        }
-
-        int Fs = 0;
-        int Fd = 0;
-        switch(rule){
-        case AlphaComposite.CLEAR:
-            break;
-
-        case AlphaComposite.DST:
-            Fd = 255;
-            break;
-
-        case AlphaComposite.DST_ATOP:
-            Fs = 255 - da;
-            Fd = sa;
-            break;
-
-        case AlphaComposite.DST_IN:
-            Fd = sa;
-            break;
-
-        case AlphaComposite.DST_OUT:
-            Fd = 255 - sa;
-            break;
-
-        case AlphaComposite.DST_OVER:
-            Fs = 255 - da;
-            Fd = 255;
-            break;
-
-        case AlphaComposite.SRC:
-            Fs = 255;
-            break;
-
-        case AlphaComposite.SRC_ATOP:
-            Fs = da;
-            Fd = 255 - sa;
-            break;
-
-        case AlphaComposite.SRC_IN:
-            Fs = da;
-            break;
-
-        case AlphaComposite.SRC_OUT:
-            Fs = 255 - da;
-            break;
-
-        case AlphaComposite.SRC_OVER:
-            Fs = 255;
-            Fd = 255 - sa;
-            break;
-
-        case AlphaComposite.XOR:
-            Fs = 255 - da;
-            Fd = 255 - sa;
-            break;
-        }
-        dr = (mulLUT[sr][Fs] & 0xff) + (mulLUT[dr][Fd] & 0xff);
-        dg = (mulLUT[sg][Fs] & 0xff) + (mulLUT[dg][Fd] & 0xff);
-        db = (mulLUT[sb][Fs] & 0xff) + (mulLUT[db][Fd] & 0xff);
-
-        da = (mulLUT[sa][Fs] & 0xff) + (mulLUT[da][Fd] & 0xff);
-
-        if(!isDstAlphaPre){
-            if(da != 255){
-                dr = divLUT[da][dr] & 0xff;
-                dg = divLUT[da][dg] & 0xff;
-                db = divLUT[da][db] & 0xff;
-            }
-        }
-        if(!dstHasAlpha) {
-            da = 0xff;
-        }
-        dstRGB = (da << 24) | (dr << 16) | (dg << 8) | db;
-
-        return dstRGB;
-
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaLineRasterizer.java b/awt/org/apache/harmony/awt/gl/render/JavaLineRasterizer.java
deleted file mode 100644
index eb6f7b5..0000000
--- a/awt/org/apache/harmony/awt/gl/render/JavaLineRasterizer.java
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.render;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-
-
-public class JavaLineRasterizer {
-
-    /**
-     *  LineDasher class provides dashing for particular dash style
-     */
-    public static class LineDasher {
-
-        int index;
-        float pos;
-        float phase;
-        float dash[];
-        float inv[];
-        boolean visible;
-
-        public LineDasher() {
-        }
-
-        public LineDasher(float dash[], float phase) {
-            this.dash = dash;
-            this.phase = phase;
-
-            inv = new float[dash.length];
-            int j = dash.length;
-            for (float element : dash) {
-                inv[--j] = element;
-            }
-            index = 0;
-            while (phase > dash[index]) {
-                phase -= dash[index];
-                index = (index + 1) % dash.length;
-            }
-            visible = index % 2 == 0;
-        }
-
-        void move(float step) { // main dasher
-            pos += step;
-            step += phase;
-            while(step >= dash[index]) {
-                step -= dash[index];
-                index = (index + 1) % dash.length;
-                visible = !visible;
-            }
-            phase = step;
-        }
-
-        float nextDash() {
-            phase = 0.0f;
-            index = (index + 1) % dash.length;
-            visible = !visible;
-            return dash[index];
-        }
-
-        LineDasher createDiagonal(double k, float length, boolean invert) {
-            LineDasher local = new LineDasher();
-            local.dash = new float[dash.length];
-            if (invert) { // inverted dasher
-                move(length);
-                local.phase = (float)((dash[index] - phase) * k);
-                local.visible = visible;
-                local.index = inv.length - index - 1;
-                for(int i = 0; i < inv.length; i++) {
-                    local.dash[i] = (float)(inv[i] * k);
-                }
-            } else {
-                local.phase = (float)(phase * k);
-                local.visible = visible;
-                local.index = index;
-                for(int i = 0; i < dash.length; i++) {
-                    local.dash[i] = (float)(dash[i] * k);
-                }
-                move(length);
-            }
-            return local;
-        }
-
-        LineDasher createOrtogonal(float length, boolean invert) {
-            LineDasher local = new LineDasher();
-            local.dash = new float[dash.length];
-            if (invert) { // inverted dasher
-                move(length);
-                local.phase = dash[index] - phase;
-                local.visible = visible;
-                local.index = inv.length - index - 1;
-                local.dash = inv;
-            } else {
-                local.phase = phase;
-                local.visible = visible;
-                local.index = index;
-                local.dash = dash;
-                move(length);
-            }
-            return local;
-        }
-
-        LineDasher createChild(float start) {
-            LineDasher child = new LineDasher();
-            child.phase = phase;
-            child.visible = visible;
-            child.index = index;
-            child.dash = dash;
-            child.move(start);
-            return child;
-        }
-
-    }
-
-    /**
-     * Line class provides rasterization for different line types
-     */
-    abstract static class Line {
-
-        int x1, y1, x2, y2;
-        int x, y;
-        MultiRectArea dst;
-
-        Line(int x1, int y1, int x2, int y2, MultiRectArea dst) {
-            this.x1 = x1;
-            this.y1 = y1;
-            this.x2 = x2;
-            this.y2 = y2;
-            this.dst = dst;
-        }
-
-        static abstract class Diag extends Line {
-            int dx, dy, adx, ady, sx, sy;
-            int eBase, ePos, eNeg;
-            int xcount;
-            int e;
-
-            Diag(int x1, int y1, int x2, int y2, MultiRectArea dst) {
-                super(x1, y1, x2, y2, dst);
-                dx = x2 - x1;
-                dy = y2 - y1;
-                sy = 1;
-                if (dx > 0) {
-                    adx = dx;
-                    sx = 1;
-                } else {
-                    adx = -dx;
-                    sx = -1;
-                }
-                ady = dy;
-            }
-
-            float getLength() {
-                return (float)Math.sqrt(dx * dx + dy * dy);
-            }
-
-            static class Hor extends Diag {
-
-                Hor(int x1, int y1, int x2, int y2, MultiRectArea dst) {
-                    super(x1, y1, x2, y2, dst);
-                    eBase = ady + ady - adx;
-                    ePos = 2 * (ady - adx);
-                    eNeg = ady + ady;
-                    xcount = adx;
-                }
-
-                @Override
-                void rasterize() {
-                    e = eBase;
-                    x = x1;
-                    y = y1;
-                    rasterize(xcount);
-                }
-
-                @Override
-                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
-                    e = eBase + 2 * (ady * Math.abs(nx1 - x1) - adx * Math.abs(ny1 - y1));
-                    x = nx1;
-                    y = ny1;
-                    rasterize(dx > 0 ? nx2 - nx1 : nx1 - nx2);
-                }
-
-                @Override
-                void rasterize(int count) {
-                    int px = x;
-                    while (count-- > 0) {
-                        if (e >= 0) {
-                            if (sx > 0) {
-                                dst.addRect(px, y, x, y);
-                            } else {
-                                dst.addRect(x, y, px, y);
-                            }
-                            x += sx;
-                            y += sy;
-                            e += ePos;
-                            px = x;
-                        } else {
-                            e += eNeg;
-                            x += sx;
-                        }
-                    }
-                    if (sx > 0) {
-                        dst.addRect(px, y, x, y);
-                    } else {
-                        dst.addRect(x, y, px, y);
-                    }
-                }
-
-                @Override
-                void skip(int count) {
-                    while (count-- > 0) {
-                        x += sx;
-                        if (e >= 0) {
-                            y += sy;
-                            e += ePos;
-                        } else {
-                            e += eNeg;
-                        }
-                    }
-                }
-
-            }
-
-            static class Ver extends Diag {
-
-                Ver(int x1, int y1, int x2, int y2, MultiRectArea dst) {
-                    super(x1, y1, x2, y2, dst);
-                    eBase = adx + adx - ady;
-                    ePos = 2 * (adx - ady);
-                    eNeg = adx + adx;
-                    xcount = ady;
-                }
-
-                @Override
-                void rasterize() {
-                    e = eBase;
-                    x = x1;
-                    y = y1;
-                    rasterize(xcount);
-                }
-
-                @Override
-                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
-                    e = eBase + 2 * (adx * Math.abs(ny1 - y1) - ady * Math.abs(nx1 - x1));
-                    x = nx1;
-                    y = ny1;
-                    rasterize(ny2 - ny1);
-                }
-
-                @Override
-                void rasterize(int count) {
-                    int py = y;
-                    while (count-- > 0) {
-                        if (e >= 0) {
-                            dst.addRect(x, py, x, y);
-                            x += sx;
-                            y += sy;
-                            e += ePos;
-                            py = y;
-                        } else {
-                            y += sy;
-                            e += eNeg;
-                        }
-                    }
-                    dst.addRect(x, py, x, y);
-                }
-
-                @Override
-                void skip(int count) {
-                    while (count-- > 0) {
-                        y += sy;
-                        if (e >= 0) {
-                            x += sx;
-                            e += ePos;
-                        } else {
-                            e += eNeg;
-                        }
-                    }
-                }
-
-            }
-
-            static class HorDashed extends Hor {
-
-                LineDasher local;
-
-                HorDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher, boolean invert) {
-                    super(x1, y1, x2, y2, dst);
-                    float length = getLength();
-                    local = dasher.createDiagonal(xcount / length, length, invert);
-                }
-
-                @Override
-                void rasterize() {
-                    e = eBase;
-                    x = x1;
-                    y = y1;
-                    rasterizeDash(xcount, local);
-                }
-
-                @Override
-                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
-                    e = eBase + 2 * (ady * Math.abs(nx1 - x1) - adx * Math.abs(ny1 - y1));
-                    x = nx1;
-                    y = ny1;
-                    rasterizeDash(Math.abs(nx2 - nx1), local.createChild(Math.abs(nx1 - x1)));
-                }
-
-            }
-
-            static class VerDashed extends Ver {
-
-                LineDasher local;
-
-                VerDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher, boolean invert) {
-                    super(x1, y1, x2, y2, dst);
-                    float length = getLength();
-                    local = dasher.createDiagonal(xcount / length, length, invert);
-                }
-
-                @Override
-                void rasterize() {
-                    e = eBase;
-                    x = x1;
-                    y = y1;
-                    rasterizeDash(xcount, local);
-                }
-
-                @Override
-                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
-                    e = eBase + 2 * (adx * Math.abs(ny1 - y1) - ady * Math.abs(nx1 - x1));
-                    x = nx1;
-                    y = ny1;
-                    rasterizeDash(ny2 - ny1, local.createChild(ny1 - y1));
-                }
-
-            }
-
-            @Override
-            void rasterize(int[] clip, int index) {
-                int cx1 = clip[index + 0];
-                int cy1 = clip[index + 1];
-                int cx2 = clip[index + 2] + 1;
-                int cy2 = clip[index + 3] + 1;
-
-                int code1 =
-                    (x1 < cx1 ? 1 : 0) | (x1 >= cx2 ? 2 : 0) |
-                    (y1 < cy1 ? 8 : 0) | (y1 >= cy2 ? 4 : 0);
-                int code2 =
-                    (x2 < cx1 ? 1 : 0) | (x2 >= cx2 ? 2 : 0) |
-                    (y2 < cy1 ? 8 : 0) | (y2 >= cy2 ? 4 : 0);
-
-                // Outside
-                if ((code1 & code2) != 0) {
-                    return;
-                }
-
-                // Inside
-                if (code1 == 0 && code2 == 0) {
-                    rasterize();
-                    return;
-                }
-
-                // Clip
-                int nx1 = x1;
-                int ny1 = y1;
-                int nx2 = x2;
-                int ny2 = y2;
-                // need to clip
-                cx1 -= x1; cx2 -= x1;
-                cy1 -= y1; cy2 -= y1;
-//                int d;
-                int newx1 = 0, newy1 = 0, newx2 = 0, newy2 = 0;
-                if (code1 != 0) {
-                    newx1 = Integer.MAX_VALUE;
-                    if ((code1 & 8) != 0) {
-                        // clip point 1 with top clip bound
-                        newy1 = cy1;
-                        newx1 = clipY(dx, dy, newy1, true);
-
-                    } else if ((code1 & 4) != 0) {
-                        // clip point 1 with bottom clip bound
-                        newy1 = cy2 - 1;
-                        newx1 = clipY(dx, dy, newy1, false);
-                    }
-                    if ((code1 & 1) != 0 && (cx1 > newx1 || newx1 == Integer.MAX_VALUE)) {
-                        // clip point 1 with left clip bound
-                        newx1 = cx1;
-                        newy1 = clipX(dx, dy, newx1, false);
-                    } else if ((code1 & 2) != 0 && (newx1 >= cx2 || newx1 == Integer.MAX_VALUE)) {
-                        // clip point 1 with right clip bound
-                        newx1 = cx2 - 1;
-                        newy1 = clipX(dx, dy, newx1, false);
-                    }
-                    if (newx1 < cx1 || newx1 >= cx2 || newy1 < cy1 || newy1 >= cy2) {
-                        return;
-                    }
-//                    d = 2 * (ady * Math.abs(newx1) - adx * Math.abs(newy1)) + 2 * ady - adx;
-                } else {
-//                    d = (ady << 1) - adx;
-                }
-
-                if (code2 != 0) {
-                    newx2=Integer.MAX_VALUE;
-                    if ((code2 & 8) != 0) {
-                        // clip point 2 with top clip bound
-                        newy2 = cy1;
-                        newx2 = clipY(dx, dy, newy2, true);
-                    } else if ((code2 & 4) != 0) {
-                        // clip point 2 with bottom clip bound
-                        newy2 = cy2 - 1;
-                        newx2 = clipY(dx, dy, newy2, false);
-                    }
-                    if ((code2 & 1) != 0 && (cx1 > newx2 || newx2 == Integer.MAX_VALUE)) {
-                        // clip point 2 with left clip bound
-                        newx2 = cx1;
-                        newy2 = clipX(dx, dy, newx2, false);
-                    } else if ((code2 & 2) != 0 && (newx2 >= cx2 || newx2 == Integer.MAX_VALUE)) {
-                        // clip point 2 with right clip bound
-                        newx2 = cx2 - 1;
-                        newy2 = clipX(dx, dy, newx2, false);
-                    }
-                    if (newx2 < cx1 || newx2 >= cx2 || newy2 < cy1 || newy2 >= cy2) {
-                        return;
-                    }
-                    nx2 = x1 + newx2;
-                    ny2 = y1 + newy2;
-                }
-                nx1 = x1 + newx1;
-                ny1 = y1 + newy1;
-
-                rasterizeClipped(nx1, ny1, nx2, ny2);
-            }
-
-            abstract void rasterizeClipped(int nx1, int ny1, int nx2, int ny2);
-
-        }
-
-        static abstract class Ortog extends Line {
-
-            Ortog(int x1, int y1, int x2, int y2, MultiRectArea dst) {
-                super(x1, y1, x2, y2, dst);
-            }
-
-            static class Hor extends Ortog {
-
-                int dx;
-
-                Hor(int x1, int y1, int x2, int y2, MultiRectArea dst) {
-                    super(x1, y1, x2, y2, dst);
-                    dx = x2 - x1;
-                }
-
-                @Override
-                void rasterize() {
-                    if (dx > 0) {
-                        dst.addRect(x1, y1, x2, y2);
-                    } else {
-                        dst.addRect(x2, y2, x1, y1);
-                    }
-                }
-
-                @Override
-                void rasterize(int step) {
-                    int px = x;
-                    if (dx > 0) {
-                        x += step;
-                        dst.addRect(px, y1, x - 1, y2);
-                    } else {
-                        x -= step;
-                        dst.addRect(x + 1, y2, px, y1);
-                    }
-                }
-
-                @Override
-                void skip(int step) {
-                    if (dx > 0) {
-                        x += step;
-                    } else {
-                        x -= step;
-                    }
-                }
-
-                void rasterizeClipped(int nx1, int nx2) {
-                    if (nx1 < nx2) {
-                        dst.addRect(nx1, y1, nx2, y1);
-                    } else {
-                        dst.addRect(nx2, y1, nx1, y1);
-                    }
-                }
-
-                @Override
-                void rasterize(int[] clip, int index) {
-                    if (y1 >= clip[index + 1] && y1 <= clip[index + 3]) {
-                        int cx1 = clip[index + 0];
-                        int cx2 = clip[index + 2];
-                        if (x1 <= cx2 && x2 >= cx1) {
-                            int nx1, nx2;
-                            if (dx > 0) {
-                                nx1 = Math.max(x1, cx1);
-                                nx2 = Math.min(x2, cx2);
-                            } else {
-                                nx2 = Math.max(x2, cx1);
-                                nx1 = Math.min(x1, cx2);
-                            }
-                            rasterizeClipped(nx1, nx2);
-                        }
-                    }
-                }
-
-            }
-
-            static class Ver extends Ortog {
-
-                int dy;
-
-                Ver(int x1, int y1, int x2, int y2, MultiRectArea dst) {
-                    super(x1, y1, x2, y2, dst);
-                    dy = y2 - y1;
-                }
-
-                @Override
-                void rasterize() {
-                    dst.addRect(x1, y1, x2, y2);
-                }
-
-                @Override
-                void rasterize(int step) {
-                    int py = y;
-                    y += step;
-                    dst.addRect(x1, py, x2, y - 1);
-                }
-
-                @Override
-                void skip(int step) {
-                    y += step;
-                }
-
-                void rasterizeClipped(int ny1, int ny2) {
-                    dst.addRect(x1, ny1, x1, ny2);
-                }
-
-                @Override
-                void rasterize(int[] clip, int index) {
-                    if (x1 >= clip[index] && x1 <= clip[index + 2]) {
-                        int cy1 = clip[index + 1];
-                        int cy2 = clip[index + 3];
-                        if (y1 <= cy2 && y2 >= cy1) {
-                            rasterizeClipped(Math.max(y1, cy1), Math.min(y2, cy2));
-                        }
-                    }
-                }
-
-            }
-
-            static class HorDashed extends Hor {
-
-                LineDasher local;
-
-                HorDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher) {
-                    super(x1, y1, x2, y2, dst);
-                    dx = x2 - x1;
-                    local = dasher.createOrtogonal(Math.abs(dx), false);
-                }
-
-                @Override
-                void rasterize() {
-                    x = x1;
-                    y = y1;
-                    rasterizeDash(Math.abs(dx), local);
-                }
-
-                @Override
-                void rasterizeClipped(int nx1, int nx2) {
-                    x = nx1;
-                    y = y1;
-                    rasterizeDash(Math.abs(nx2 - nx1), local.createChild(Math.abs(nx1 - x1)));
-                }
-
-            }
-
-            static class VerDashed extends Ver {
-
-                LineDasher local;
-
-                VerDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher, boolean invert) {
-                    super(x1, y1, x2, y2, dst);
-                    dy = y2 - y1;
-                    local = dasher.createOrtogonal(dy, invert);
-                }
-
-                @Override
-                void rasterize() {
-                    x = x1;
-                    y = y1;
-                    rasterizeDash(dy, local);
-                }
-
-                @Override
-                void rasterizeClipped(int ny1, int ny2) {
-                    x = x1;
-                    y = ny1;
-                    rasterizeDash(ny2 - ny1, local.createChild(ny1));
-                }
-
-            }
-
-        }
-
-        abstract void rasterize();
-        abstract void rasterize(int[] clip, int index);
-        abstract void rasterize(int count);
-        abstract void skip(int count);
-
-        void rasterizeDash(int count, LineDasher dasher) {
-            float delta = dasher.dash[dasher.index] - dasher.phase;
-            int step = (int)delta;
-            delta -= step;
-            while(count > step) {
-                if (dasher.visible) {
-                    rasterize(step);
-                } else {
-                    skip(step);
-                }
-                count -= step;
-                delta += dasher.nextDash();
-                step = (int)delta;
-                delta -= step;
-            }
-            if (count > 0 && dasher.visible) {
-                rasterize(count);
-                dasher.move(count);
-            }
-        }
-
-    }
-
-    /**
-     * Common clipping method
-     */
-    static int clip(int dX1, int dX2, int cX, boolean top) {
-        int adX1 = dX1 < 0 ? -dX1 : dX1;
-        int adX2 = dX2 < 0 ? -dX2 : dX2;
-        if (adX1 <= adX2) {
-            // obtuse intersection angle
-            return ((dX1 << 1) * cX + (dX1 > 0 ? dX2 : -dX2)) / (dX2 << 1);
-        }
-        int k;
-        if (top) {
-            k = -dX1 + (dX2 < 0 ? 0 : dX1 > 0 ? (dX2 << 1) : -(dX2 << 1));
-        } else {
-            k = dX1 + (dX2 > 0 ? 0 : dX1 > 0 ? (dX2 << 1) : -(dX2 << 1));
-        }
-
-        k += dX1 > 0 == dX2 > 0 ? -1 : 1;
-        return ((dX1 << 1) * cX + k) / (dX2 << 1);
-    }
-
-    /**
-     * Clipping along X axis
-     */
-    static int clipX(int dx, int dy, int cy, boolean top) {
-        return clip(dy, dx, cy, top);
-    }
-
-    /**
-     * Clipping along Y axis
-     */
-    static int clipY(int dx, int dy, int cx, boolean top) {
-        return clip(dx, dy, cx, top);
-    }
-
-    /**
-     * Rasterizes line using clippind and dashing style
-     * @param x1 - the x coordinate of the first control point
-     * @param y1 - the y coordinate of the first control point
-     * @param x2 - the x coordinate of the second control point
-     * @param y2 - the y coordinate of the second control point
-     * @param clip - the MultiRectArea object of clipping area
-     * @param dasher - the dasher style
-     * @param invert - the invert indicator, always false
-     * @return a MultiRectArea of rasterizer line
-     */
-    public static MultiRectArea rasterize(int x1, int y1, int x2, int y2, MultiRectArea clip, LineDasher dasher, boolean invert) {
-
-        MultiRectArea dst = new MultiRectArea(false);
-        int dx = x2 - x1;
-        int dy = y2 - y1;
-
-        // Point
-        if (dx == 0 && dy == 0) {
-            if ((clip == null || clip.contains(x1, y1)) && (dasher == null || dasher.visible)) {
-                dst = new MultiRectArea(x1, y1, x1, y1);
-            }
-            return dst;
-        }
-
-        if (dy < 0) {
-            return rasterize(x2, y2, x1, y1, clip, dasher, true);
-        }
-
-        Line line;
-        if (dasher == null) {
-            if (dx == 0) {
-                line = new Line.Ortog.Ver(x1, y1, x2, y2, dst);
-            } else
-                if (dy == 0) {
-                    line = new Line.Ortog.Hor(x1, y1, x2, y2, dst);
-                } else {
-                    if (dy < Math.abs(dx)) {
-                        line = new Line.Diag.Hor(x1, y1, x2, y2, dst);
-                    } else {
-                        line = new Line.Diag.Ver(x1, y1, x2, y2, dst);
-                    }
-                }
-        } else {
-            if (dx == 0) {
-                line = new Line.Ortog.VerDashed(x1, y1, x2, y2, dst, dasher, invert);
-            } else
-                if (dy == 0) {
-                    line = new Line.Ortog.HorDashed(x1, y1, x2, y2, dst, dasher);
-                } else {
-                    if (dy < Math.abs(dx)) {
-                        line = new Line.Diag.HorDashed(x1, y1, x2, y2, dst, dasher, invert);
-                    } else {
-                        line = new Line.Diag.VerDashed(x1, y1, x2, y2, dst, dasher, invert);
-                    }
-                }
-        }
-
-
-        if (clip == null || clip.isEmpty()) {
-            line.rasterize();
-        } else {
-            for(int i = 1; i < clip.rect[0]; i += 4) {
-                line.rasterize(clip.rect, i);
-            }
-        }
-
-        return dst;
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaShapeRasterizer.java b/awt/org/apache/harmony/awt/gl/render/JavaShapeRasterizer.java
deleted file mode 100644
index dbaaf53..0000000
--- a/awt/org/apache/harmony/awt/gl/render/JavaShapeRasterizer.java
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.render;
-
-import java.awt.Shape;
-import java.awt.geom.PathIterator;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.internal.nls.Messages;
-
-public class JavaShapeRasterizer {
-
-    static final int POINT_CAPACITY = 16;
-
-    int edgesCount;
-    int edgeCur;
-    int[] edgesX;
-    int[] edgesY;
-    int[] edgesYS; // Y coordinate of edge START point
-    int[] edgesN;
-    int[] edgesDY;
-    int[] bounds;
-    int boundCount;
-    boolean[] edgesExt; // Extremal points
-
-    int activeCount;
-    float[] activeX;
-    int[] activeYEnd;
-    float[] activeXStep;
-    int[] activeDY;
-    boolean[] activeExt;
-
-    int[] crossX;
-    int[] crossDY;
-
-    Filler filler;
-
-    /**
-     * Rasterization filler for different path rules
-     */
-    static abstract class Filler {
-
-        static class NonZero extends Filler {
-            @Override
-            void add(MultiRectArea.LineCash rect, int[] points, int[] orient, int length, int y) {
-
-                int[] dst = new int[length];
-                int dstLength = 1;
-                dst[0] = points[0];
-                int count = 0;
-                boolean inside = true;
-                for(int i = 0; i < length; i++) {
-                    count += orient[i] > 0 ? 1 : -1;
-                    if (count == 0) {
-                        dst[dstLength++] = points[i];
-                        inside = false;
-                    } else {
-                        if (!inside) {
-                            dst[dstLength++] = points[i];
-                            inside = true;
-                        }
-                    }
-
-                }
-
-                for(int i = 1; i < dstLength; i += 2) {
-                    dst[i]--;
-                }
-
-                dstLength = excludeEmpty(dst, dstLength);
-//              System.out.println("test");
-
-                dstLength = union(dst, dstLength);
-
-                rect.addLine(dst, dstLength);
-            }
-        }
-
-        static class EvenOdd extends Filler {
-            @Override
-            void add(MultiRectArea.LineCash rect, int[] points, int[] orient, int length, int y) {
-    /*
-                int[] buf = new int[length];
-                int j = 0;
-                for(int i = 0; i < length - 1; i++) {
-                    if (points[i] != points[i + 1]) {
-                        buf[j++] = points[i];
-                    }
-                }
-    */
-                for(int i = 1; i < length; i += 2) {
-                    points[i]--;
-                }
-
-                length = excludeEmpty(points, length);
-//              System.out.println("test");
-
-                length = union(points, length);
-                rect.addLine(points, length);
-    /*
-                for(int i = 0; i < length;) {
-                    rect.add(points[i++], y, points[i++], y);
-                }
-    */
-            }
-        }
-
-        abstract void add(MultiRectArea.LineCash rect, int[] points, int[] orient, int length, int y);
-
-        static int excludeEmpty(int[] points, int length) {
-            int i = 0;
-            while(i < length) {
-                if (points[i] <= points[i + 1]) {
-                    i += 2;
-                } else {
-                    length -= 2;
-                    System.arraycopy(points, i + 2, points, i, length - i);
-                }
-            }
-            return length;
-        }
-
-        static int union(int[] points, int length) {
-            int i = 1;
-            while(i < length - 1) {
-                if (points[i] < points[i - 1]) {
-                    System.arraycopy(points, i + 1, points, i - 1, length - i - 1);
-                    length -= 2;
-                } else
-                if (points[i] >= points[i + 1] - 1) {
-                    System.arraycopy(points, i + 2, points, i, length - i - 2);
-                    length -= 2;
-                } else {
-                    i += 2;
-                }
-            }
-            return length;
-        }
-
-    }
-
-    public JavaShapeRasterizer() {
-    }
-
-    /**
-     * Checks buffer size and realloc if necessary
-     */
-    int[] checkBufSize(int[] buf, int size) {
-        if (size == buf.length) {
-            int[] tmp;
-            tmp = new int[size + POINT_CAPACITY];
-            System.arraycopy(buf, 0, tmp, 0, buf.length);
-            buf = tmp;
-        }
-        return buf;
-    }
-
-    /**
-     * Adds to the buffers new edge 
-     */
-    void addEdge(int x, int y, int num) {
-        edgesX = checkBufSize(edgesX, edgesCount);
-        edgesY = checkBufSize(edgesY, edgesCount);
-        edgesN = checkBufSize(edgesN, edgesCount);
-        edgesX[edgesCount] = x;
-        edgesY[edgesCount] = y;
-        edgesN[edgesCount] = (num << 16) | edgesCount;
-        edgesCount++;
-    }
-
-    /**
-     * Prepare all buffers and variable to rasterize shape 
-     */
-    void makeBuffer(PathIterator path, double flatness) {
-        edgesX = new int[POINT_CAPACITY];
-        edgesY = new int[POINT_CAPACITY];
-        edgesN = new int[POINT_CAPACITY];
-        bounds = new int[POINT_CAPACITY];
-        boundCount = 0;
-        edgesCount = 0;
-
-        if (path.getWindingRule() == PathIterator.WIND_EVEN_ODD) {
-            filler = new Filler.EvenOdd();
-        } else {
-            filler = new Filler.NonZero();
-        }
-        float[] coords = new float[2];
-        boolean closed = true;
-        while (!path.isDone()) {
-            switch(path.currentSegment(coords)) {
-            case PathIterator.SEG_MOVETO:
-                if (!closed) {
-                    boundCount++;
-                    bounds = checkBufSize(bounds, boundCount);
-                    bounds[boundCount] = edgesCount;
-                }
-                addEdge((int)coords[0], (int)coords[1], boundCount);
-                closed = false;
-                break;
-            case PathIterator.SEG_LINETO:
-                addEdge((int)coords[0], (int)coords[1], boundCount);
-                break;
-            case PathIterator.SEG_CLOSE:
-                boundCount++;
-                bounds = checkBufSize(bounds, boundCount);
-                bounds[boundCount] = edgesCount;
-                closed = true;
-                break;
-            default:
-                // awt.36=Wrong segment
-                throw new RuntimeException(Messages.getString("awt.36")); //$NON-NLS-1$
-            }
-            path.next();
-        }
-        if (!closed) {
-            boundCount++;
-            bounds = checkBufSize(bounds, boundCount);
-            bounds[boundCount] = edgesCount;
-        }
-    }
-
-    /**
-     * Sort buffers
-     */
-    void sort(int[] master, int[] slave, int length) {
-        for(int i = 0; i < length - 1; i++) {
-            int num = i;
-            int min = master[num];
-            for(int j = i + 1; j < length; j++) {
-                if (master[j] < min) {
-                    num = j;
-                    min = master[num];
-                }
-            }
-            if (num != i) {
-                master[num] = master[i];
-                master[i] = min;
-                min = slave[num];
-                slave[num] = slave[i];
-                slave[i] = min;
-            }
-        }
-    }
-
-    int getNext(int cur) {
-        int n = edgesN[cur];
-        int bound = n >> 16;
-        int num = (n & 0xFFFF) + 1;
-        if (num == bounds[bound + 1]) {
-            return bounds[bound];
-        }
-        return num;
-    }
-
-    int getPrev(int cur) {
-        int n = edgesN[cur];
-        int bound = n >> 16;
-        int num = (n & 0xFFFF) - 1;
-        if (num < bounds[bound]) {
-            return bounds[bound + 1] - 1;
-        }
-        return num;
-    }
-
-    int getNextShape(int cur) {
-        int bound = edgesN[cur] >> 16;
-        return bounds[bound + 1];
-    }
-
-    void init() {
-
-        edgesYS = new int[edgesCount];
-        System.arraycopy(edgesY, 0, edgesYS, 0, edgesCount);
-        // Create edgesDY
-        edgesDY = new int[edgesCount];
-        for(int i = 0; i < edgesCount; i++) {
-            int dy = edgesY[getNext(i)] - edgesY[i];
-            edgesDY[i] = dy;
-        }
-
-        // Create edgesExt
-        edgesExt = new boolean[edgesCount];
-        int prev = -1;
-        int i = 0;
-        int pos = 0;
-        while(i < edgesCount) {
-
-            TOP: {
-                do {
-                    if (edgesDY[i] > 0) {
-                        break TOP;
-                    }
-                    i = getNext(i);
-                } while (i != pos);
-                i = pos = getNextShape(i);
-                continue;
-            }
-
-            BOTTOM: {
-                do {
-                    if (edgesDY[i] < 0) {
-                        break BOTTOM;
-                    }
-                    if (edgesDY[i] > 0) {
-                        prev = i;
-                    }
-                    i = getNext(i);
-                } while (i != pos);
-                i = pos = getNextShape(i);
-                continue;
-            }
-
-            if (prev != -1) {
-                edgesExt[prev] = true;
-            }
-            edgesExt[i] = true;
-        }
-
-        // Sort edgesY and edgesN
-        sort(edgesYS, edgesN, edgesCount);
-
-        edgeCur = 0;
-        activeCount = 0;
-        activeX = new float[edgesCount];
-        activeYEnd = new int[edgesCount];
-        activeXStep = new float[edgesCount];
-        activeDY = new int[edgesCount];
-        activeExt = new boolean[edgesCount];
-
-        crossX = new int[edgesCount];
-        crossDY = new int[edgesCount];
-    }
-
-    /**
-     * Marks edge as active
-     */
-    void addActiveEdge(int levelY, int start, int end, boolean back) {
-        int dy = back ? -edgesDY[end] : edgesDY[start];
-        if (dy <= 0) {
-            return;
-        }
-        int x1 = edgesX[start];
-        int dx = edgesX[end] - x1;
-        activeX[activeCount] = x1;
-        activeYEnd[activeCount] = edgesY[end];
-        activeXStep[activeCount] = dx / (float)dy;
-        activeDY[activeCount] = back ? -dy : dy;
-        activeExt[activeCount] = back ? edgesExt[end] : edgesExt[start];
-        activeCount++;
-    }
-
-    /**
-     * Find new active edges
-     */
-    int findActiveEdges(int levelY) {
-
-        int edgeActive = edgeCur;
-        while (edgeActive < edgesCount && edgesYS[edgeActive] == levelY) {
-            edgeActive++;
-        }
-
-        int activeNext = edgeActive;
-
-        while (edgeActive > edgeCur) {
-            edgeActive--;
-            int num = edgesN[edgeActive] & 0xFFFF;
-            addActiveEdge(levelY, num, getPrev(edgeActive), true);
-            addActiveEdge(levelY, num, getNext(edgeActive), false);
-        }
-
-        edgeCur = activeNext;
-
-        if (activeNext == edgesCount) {
-            return edgesY[edgesCount - 1];
-        }
-        return edgesYS[activeNext];
-    }
-
-    /**
-     * Rasterizes shape with particular flatness
-     * @param shape - the souze Shape to be rasterized
-     * @param flatness - the rasterization flatness
-     * @return a MultiRectArea of rasterized shape
-     */
-    public MultiRectArea rasterize(Shape shape, double flatness) {
-
-        PathIterator path = shape.getPathIterator(null, flatness);
-
-        // Shape is empty
-        if (path.isDone()) {
-            return new MultiRectArea();
-        }
-
-        makeBuffer(path, flatness);
-
-        init();
-
-        int y = edgesYS[0];
-        int nextY = y;
-        int crossCount;
-
-        MultiRectArea.LineCash rect = new MultiRectArea.LineCash(edgesCount);
-        rect.setLine(y);
-
-        while(y <= nextY) {
-
-            crossCount = 0;
-
-            if (y == nextY) {
-
-                int i = activeCount;
-                while(i > 0) {
-                    i--;
-                    if (activeYEnd[i] == y) {
-
-                        activeCount--;
-                        int length = activeCount - i;
-                        if (length != 0) {
-                            int pos = i + 1;
-                            System.arraycopy(activeX, pos, activeX, i, length);
-                            System.arraycopy(activeYEnd, pos, activeYEnd, i, length);
-                            System.arraycopy(activeXStep, pos, activeXStep, i, length);
-                            System.arraycopy(activeDY, pos, activeDY, i, length);
-                            System.arraycopy(activeExt, pos, activeExt, i, length);
-                        }
-                    }
-                }
-
-                nextY = findActiveEdges(y);
-            }
-
-            // Get X crossings
-            for(int i = 0; i < activeCount; i++) {
-                crossX[crossCount] = (int)Math.ceil(activeX[i]);
-                crossDY[crossCount] = activeDY[i];
-                crossCount++;
-            }
-
-            if (crossCount == 0) {
-                rect.skipLine();
-            } else {
-                // Sort X crossings
-                sort(crossX, crossDY, crossCount);
-                filler.add(rect, crossX, crossDY, crossCount, y);
-            }
-
-            for(int i = 0; i < activeCount; i++) {
-                activeX[i] += activeXStep[i];
-            }
-
-            y++;
-        }
-
-        return rect;
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java b/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java
deleted file mode 100644
index 322ba57..0000000
--- a/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Ilya S. Okomin
- * @version $Revision$
- */
-package org.apache.harmony.awt.gl.render;
-
-import java.awt.*;
-import java.awt.image.*;
-
-
-import java.awt.font.GlyphMetrics;
-import java.awt.font.GlyphVector;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-
-import org.apache.harmony.awt.gl.TextRenderer;
-import org.apache.harmony.awt.gl.font.CommonGlyphVector;
-import org.apache.harmony.awt.gl.font.FontPeerImpl;
-import org.apache.harmony.awt.gl.font.Glyph;
-import org.apache.harmony.awt.gl.image.BufferedImageGraphics2D;
-
-public class JavaTextRenderer extends TextRenderer {
-
-    public static final JavaTextRenderer inst = new JavaTextRenderer();
-
-    @Override
-    public void drawGlyphVector(Graphics2D g, GlyphVector glyphVector,
-            float x, float y) {
-
-        AffineTransform at = g.getTransform();
-        Rectangle c = g.getClipBounds();
-        if (at != null){
-            int atType = at.getType();
-            if (atType == AffineTransform.TYPE_TRANSLATION) {
-                c.translate((int)Math.round(at.getTranslateX()), (int)Math.round(at.getTranslateY()));
-            }
-        }
-
-        WritableRaster wr = ((BufferedImageGraphics2D)g).getWritableRaster();
-        ColorModel cm = ((BufferedImageGraphics2D)g).getColorModel();
-
-        Rectangle rBounds = wr.getBounds();
-
-        Object color = cm.getDataElements(g.getColor().getRGB(), null);
-
-        drawClipGlyphVector(wr, color, glyphVector, (int)Math.round(x + at.getTranslateX()), (int)Math.round(y + at.getTranslateY()),
-        Math.max(c.x,rBounds.x),
-        Math.max(c.y,rBounds.y),
-        Math.min((int)Math.round(c.getMaxX()), (int)Math.round(rBounds.getMaxX())),
-        Math.min((int)Math.round(c.getMaxY()), (int)Math.round(rBounds.getMaxY())));
-
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    public void drawString(Graphics2D g, String str, float x, float y) {
-        AffineTransform at = g.getTransform();
-        Rectangle c = g.getClipBounds();
-        if (at != null){
-            int atType = at.getType();
-            if (atType == AffineTransform.TYPE_TRANSLATION) {
-                c.translate((int)Math.round(at.getTranslateX()), (int)Math.round(at.getTranslateY()));
-            }
-        }
-        WritableRaster wr = ((BufferedImageGraphics2D)g).getWritableRaster();
-        ColorModel cm = ((BufferedImageGraphics2D)g).getColorModel();
-        Rectangle rBounds = wr.getBounds();
-
-        Object color = cm.getDataElements(g.getColor().getRGB(), null);
-
-        drawClipString(wr, color, str, (FontPeerImpl) (g.getFont().getPeer()),
-                (int)Math.round(x + at.getTranslateX()), (int)Math.round(y + at.getTranslateY()),
-                Math.max(c.x,rBounds.x),
-                Math.max(c.y,rBounds.y),
-                Math.min((int)Math.round(c.getMaxX()), (int)Math.round(rBounds.getMaxX())),
-                Math.min((int)Math.round(c.getMaxY()), (int)Math.round(rBounds.getMaxY())));
-
-    }
-
-    /**
-     * 
-     * Draws string on specified raster at desired position.
-     *  
-     * @param raster specified WritableRaster to draw at
-     * @param color color of the text
-     * @param glyphVector GlyphVector object to draw
-     * @param x start X position to draw
-     * @param y start Y position to draw
-     * @param cMinX minimum x of the raster area to draw
-     * @param cMinY minimum y of the raster area to draw
-     * @param cMaxX maximum x of the raster area to draw
-     * @param cMaxY maximum y of the raster area to draw
-     */
-    public void drawClipGlyphVector(WritableRaster raster, Object color,
-            GlyphVector glyphVector, int x, int y,
-            int cMinX, int cMinY, int cMaxX, int cMaxY) {
-        // TODO: implement complex clipping
-
-        int xSrcSurf, ySrcSurf; // Start point in String rectangle
-        int xDstSurf, yDstSurf; // Start point in Surface rectangle
-        int clWidth, clHeight;
-
-        for (int i = 0; i < glyphVector.getNumGlyphs(); i++) {
-            Glyph gl = ((CommonGlyphVector) glyphVector).vector[i];
-
-            if (gl.getPointWidth() == 0) {
-                continue;
-            }
-
-            byte[] data = gl.getBitmap();
-            if (data != null) {
-                Point2D pos = glyphVector.getGlyphPosition(i);
-
-                xSrcSurf = 0;//gl.bmp_left;
-                ySrcSurf = 0;//gl.bmp_rows - gl.bmp_top;
-
-                xDstSurf = x + (int)pos.getX() + (int) gl.getGlyphPointMetrics().getLSB();// + gl.bmp_left;
-                yDstSurf = y - gl.bmp_top/*getPointHeight()*/  + (int) pos.getY();// - (gl.bmp_rows-gl.bmp_top);
-
-                int textWidth = gl.bmp_width;
-                int textHeight = gl.getPointHeight();
-
-                // if Regions don't intersect
-                if ((xDstSurf > cMaxX) || (yDstSurf > cMaxY) || (xDstSurf + textWidth < cMinX)
-                        || (yDstSurf + textHeight < cMinY)) {
-                    // Nothing to do
-                } else {
-                    if (xDstSurf >= cMinX) {
-                        clWidth = Math.min(textWidth, cMaxX - xDstSurf);
-                    } else {
-                        xSrcSurf += cMinX - xDstSurf;
-                        clWidth = Math.min(cMaxX - cMinX, textWidth - (cMinX - xDstSurf));
-                        xDstSurf = cMinX;
-                    }
-                    if (yDstSurf >= cMinY) {
-                        clHeight = Math.min(textHeight, cMaxY - yDstSurf);
-                    } else {
-                        ySrcSurf += cMinY - yDstSurf;
-                        clHeight = Math.min(cMaxY - cMinY, textHeight - (cMinY - yDstSurf));
-                        yDstSurf = cMinY;
-                    }
-                    //     Drawing on the Raster
-                    for (int h=0; h<clHeight; h++){
-                        for (int w=0; w < clWidth ; w++) {
-                            byte currByte = data[(ySrcSurf + h)*gl.bmp_pitch + (xSrcSurf+w)/8];
-                            boolean emptyByte = ((currByte & (1 << (7 - ((xSrcSurf+w) % 8)))) != 0);
-                            if (emptyByte) {
-                                raster.setDataElements(xDstSurf+w, yDstSurf+h, color);
-                            } else {
-                                // Nothing to do
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-    
-    /**
-     * Draws string on specified raster at desired position.
-     *  
-     * @param raster specified WritableRaster to draw at
-     * @param color color of the text
-     * @param str text to draw
-     * @param font font peer to use for drawing text
-     * @param x start X position to draw
-     * @param y start Y position to draw
-     * @param cMinX minimum x of the raster area to draw
-     * @param cMinY minimum y of the raster area to draw
-     * @param cMaxX maximum x of the raster area to draw
-     * @param cMaxY maximum y of the raster area to draw
-     */    
-    public void drawClipString(WritableRaster raster, Object color, String str,
-            FontPeerImpl font, int x, int y, int cMinX, int cMinY, int cMaxX,
-            int cMaxY) {
-        // TODO: implement complex clipping
-
-        int xSrcSurf, ySrcSurf; // Start point in String rectangle
-        int xDstSurf, yDstSurf; // Start point in Surface rectangle
-        int clWidth, clHeight;
-
-        char[] chars = str.toCharArray();
-
-        int xBaseLine = x;
-        int yBaseLine = y;
-
-        for (char element : chars) {
-            Glyph gl = font.getGlyph(element);
-            GlyphMetrics pointMetrics = gl.getGlyphPointMetrics();
-            if (gl.getWidth() == 0) {
-                xBaseLine += pointMetrics.getAdvanceX();
-                continue;
-            }
-
-            byte[] data = gl.getBitmap();
-            if (data == null) {
-                xBaseLine += pointMetrics.getAdvanceX();
-            } else {
-
-                xSrcSurf = 0;
-                ySrcSurf = 0;
-
-                xDstSurf = Math.round(xBaseLine + gl.getGlyphPointMetrics().getLSB());
-                yDstSurf = yBaseLine - gl.bmp_top;
-
-                int textWidth = gl.bmp_width;
-                int textHeight = gl.getPointHeight();
-
-                // if Regions don't intersect
-                if ((xDstSurf > cMaxX) || (yDstSurf > cMaxY) || (xDstSurf + textWidth < cMinX)
-                        || (yDstSurf + textHeight < cMinY)) {
-                    // Nothing to do
-                } else {
-                    if (xDstSurf >= cMinX) {
-                        clWidth = Math.min(textWidth, cMaxX - xDstSurf);
-                    } else {
-                        xSrcSurf += cMinX - xDstSurf;
-                        clWidth = Math.min(cMaxX - cMinX, textWidth - (cMinX - xDstSurf));
-                        xDstSurf = cMinX;
-                    }
-                    if (yDstSurf >= cMinY) {
-                        clHeight = Math.min(textHeight, cMaxY - yDstSurf);
-                    } else {
-                        ySrcSurf += cMinY - yDstSurf;
-                        clHeight = Math.min(cMaxY - cMinY, textHeight - (cMinY - yDstSurf));
-                        yDstSurf = cMinY;
-                    }
-
-                    // Drawing on the Raster
-                    for (int h=0; h<clHeight; h++){
-                        for (int w=0; w < clWidth ; w++) {
-                            byte currByte = data[(ySrcSurf + h)*gl.bmp_pitch + (xSrcSurf+w)/8];
-                            boolean emptyByte = ((currByte & (1 << (7 - ((xSrcSurf+w) % 8)))) != 0);
-                            if (emptyByte) {
-                                raster.setDataElements(xDstSurf+w, yDstSurf+h, color);
-                            } else {
-                                // Nothing to do
-                            }
-                        }
-                    }
-                }
-                xBaseLine += pointMetrics.getAdvanceX();
-            }
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/render/NativeImageBlitter.java b/awt/org/apache/harmony/awt/gl/render/NativeImageBlitter.java
deleted file mode 100644
index b0ebc97..0000000
--- a/awt/org/apache/harmony/awt/gl/render/NativeImageBlitter.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- * Created on 26.11.2005
- *
- */
-package org.apache.harmony.awt.gl.render;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-
-import org.apache.harmony.awt.gl.ImageSurface;
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.gl.Surface;
-import org.apache.harmony.awt.gl.XORComposite;
-
-/**
- * This kind of blitters is intended for drawing one image on the buffered
- * or volatile image. For the moment we can blit natively Buffered Images which 
- * have sRGB, Linear_RGB, Linear_Gray Color Space and type different 
- * from BufferedImage.TYPE_CUSTOM, Volatile Images and Images which received 
- * using Toolkit and Component classes.
- */
-public class NativeImageBlitter implements Blitter {
-
-
-    final static NativeImageBlitter inst = new NativeImageBlitter();
-
-    public static NativeImageBlitter getInstance(){
-        return inst;
-    }
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, AffineTransform sysxform,
-            AffineTransform xform, Composite comp, Color bgcolor,
-            MultiRectArea clip) {
-
-        if(!srcSurf.isNativeDrawable()){
-            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
-                    sysxform, xform, comp, bgcolor, clip);
-        }else{
-            if(xform == null){
-                blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
-                        sysxform, comp, bgcolor, clip);
-            }else{
-                double scaleX = xform.getScaleX();
-                double scaleY = xform.getScaleY();
-                double scaledX = dstX / scaleX;
-                double scaledY = dstY / scaleY;
-                AffineTransform at = new AffineTransform();
-                at.setToTranslation(scaledX, scaledY);
-                xform.concatenate(at);
-                sysxform.concatenate(xform);
-                blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
-                        sysxform, comp, bgcolor, clip);
-            }
-        }
-    }
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, AffineTransform sysxform,
-            Composite comp, Color bgcolor, MultiRectArea clip) {
-
-        if(!srcSurf.isNativeDrawable()){
-            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
-                    sysxform, comp, bgcolor, clip);
-        }else{
-            int type = sysxform.getType();
-            switch(type){
-                case AffineTransform.TYPE_TRANSLATION:
-                    dstX += sysxform.getTranslateX();
-                    dstY += sysxform.getTranslateY();
-                case AffineTransform.TYPE_IDENTITY:
-                    blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
-                            width, height, comp, bgcolor, clip);
-                    break;
-                default:
-                    // TODO Need to realize Affine Transformation
-                    if(srcSurf instanceof ImageSurface){
-                        JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, 
-                                dstSurf, width, height,
-                                sysxform, comp, bgcolor, clip);
-                    }else{
-                        int w = srcSurf.getWidth();
-                        int h = srcSurf.getHeight();
-                        BufferedImage tmp = new BufferedImage(w, h, 
-                                BufferedImage.TYPE_INT_RGB);
-                        Surface tmpSurf = Surface.getImageSurface(tmp);
-                        blit(0, 0, srcSurf, 0, 0, tmpSurf,
-                                w, h, AlphaComposite.SrcOver, null, null);
-                        JavaBlitter.inst.blit(srcX, srcY, tmpSurf, dstX, dstY, 
-                                dstSurf, width, height,
-                                sysxform, comp, bgcolor, clip);
-                    }
-            }
-        }
-    }
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, Composite comp,
-            Color bgcolor, MultiRectArea clip) {
-
-        if(!srcSurf.isNativeDrawable()){
-            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
-                    comp, bgcolor, clip);
-        }else{
-            long dstSurfStruct = dstSurf.getSurfaceDataPtr();
-            Object dstData = dstSurf.getData();
-            int clipRects[];
-            if(clip != null){
-                clipRects = clip.rect;
-            }else{
-                clipRects = new int[]{5, 0, 0, dstSurf.getWidth(),
-                        dstSurf.getHeight()};
-            }
-
-            if(!(srcSurf instanceof ImageSurface)){
-                srcSurf = srcSurf.getImageSurface();
-                if(bgcolor != null){
-                    bgcolor = null;
-                }
-            }
-
-            long srcSurfStruct = srcSurf.getSurfaceDataPtr();
-            Object srcData = srcSurf.getData();
-            if(comp instanceof AlphaComposite){
-                AlphaComposite ac = (AlphaComposite) comp;
-                int compType = ac.getRule();
-                float alpha = ac.getAlpha();
-                if(bgcolor != null){
-                    bltBG(srcX, srcY, srcSurfStruct, srcData,
-                            dstX, dstY, dstSurfStruct, dstData,
-                            width, height, bgcolor.getRGB(),
-                            compType, alpha, clipRects, srcSurf.invalidated());
-                    dstSurf.invalidate();
-                    srcSurf.validate();
-                }else{
-                    blt(srcX, srcY, srcSurfStruct, srcData,
-                            dstX, dstY, dstSurfStruct, dstData,
-                            width, height, compType, alpha,
-                            clipRects, srcSurf.invalidated());
-                    dstSurf.invalidate();
-                    srcSurf.validate();
-                }
-            }else if(comp instanceof XORComposite){
-                XORComposite xcomp = (XORComposite) comp;
-                xor(srcX, srcY, srcSurfStruct, srcData,
-                        dstX, dstY, dstSurfStruct, dstData,
-                        width, height, xcomp.getXORColor().getRGB(),
-                        clipRects, srcSurf.invalidated());
-                dstSurf.invalidate();
-                srcSurf.validate();
-            }else{
-                if(srcSurf instanceof ImageSurface){
-                    JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, 
-                            dstSurf, width, height,
-                            comp, bgcolor, clip);
-                }else{
-                    int w = srcSurf.getWidth();
-                    int h = srcSurf.getHeight();
-                    BufferedImage tmp = new BufferedImage(w, h, 
-                            BufferedImage.TYPE_INT_RGB);
-                    Surface tmpSurf = Surface.getImageSurface(tmp);
-                    long tmpSurfStruct = tmpSurf.getSurfaceDataPtr();
-                    Object tmpData = tmpSurf.getData();
-                    int tmpClip[] = new int[]{5, 0, 0, srcSurf.getWidth(),
-                            srcSurf.getHeight()};
-                    
-                    blt(0, 0, srcSurfStruct, srcData, 0, 0,
-                            tmpSurfStruct, tmpData, w, h, 
-                            AlphaComposite.SRC_OVER,
-                            1.0f, tmpClip, srcSurf.invalidated());
-                    srcSurf.validate();
-                    JavaBlitter.inst.blit(srcX, srcY, tmpSurf, dstX, dstY, 
-                            dstSurf, width, height,
-                            comp, bgcolor, clip);
-                }
-            }
-        }
-
-    }
-
-    private native void bltBG(int srcX, int srcY, long srsSurfDataPtr,
-            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
-            Object dstData, int width, int height, int bgcolor,
-            int compType, float alpha, int clip[], boolean invalidated);
-
-    private native void blt(int srcX, int srcY, long srsSurfDataPtr,
-            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
-            Object dstData, int width, int height, int compType,
-            float alpha, int clip[], boolean invalidated);
-
-    private native void xor(int srcX, int srcY, long srsSurfDataPtr,
-            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
-            Object dstData, int width, int height, int xorcolor,
-            int clip[], boolean invalidated);
-
-
-}
diff --git a/awt/org/apache/harmony/awt/gl/render/NullBlitter.java b/awt/org/apache/harmony/awt/gl/render/NullBlitter.java
deleted file mode 100644
index 9032e4e..0000000
--- a/awt/org/apache/harmony/awt/gl/render/NullBlitter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Igor V. Stolyarov
- * @version $Revision$
- * Created on 07.12.2005
- *
- */
-package org.apache.harmony.awt.gl.render;
-
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.geom.AffineTransform;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.gl.Surface;
-
-
-public class NullBlitter implements Blitter {
-
-    static Blitter inst = new NullBlitter();
-    public static Blitter getInstance(){
-        return inst;
-    }
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, AffineTransform sysxform,
-            AffineTransform xform, Composite comp, Color bgcolor,
-            MultiRectArea clip) {
-    }
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, AffineTransform sysxform,
-            Composite comp, Color bgcolor, MultiRectArea clip) {
-    }
-
-    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
-            Surface dstSurf, int width, int height, Composite comp,
-            Color bgcolor, MultiRectArea clip) {
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/im/InputMethodContext.java b/awt/org/apache/harmony/awt/im/InputMethodContext.java
deleted file mode 100644
index 45ed11f..0000000
--- a/awt/org/apache/harmony/awt/im/InputMethodContext.java
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/** 
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package org.apache.harmony.awt.im;
-
-//???AWT
-import java.awt.AWTEvent;
-import java.awt.Component;
-//import java.awt.KeyboardFocusManager;
-import java.awt.Rectangle;
-//import java.awt.Window;
-import java.awt.event.FocusEvent;
-import java.awt.event.InputMethodEvent;
-import java.awt.event.KeyEvent;
-import java.awt.font.TextHitInfo;
-import java.awt.im.InputContext;
-import java.awt.im.InputMethodRequests;
-import java.awt.im.spi.InputMethod;
-import java.awt.im.spi.InputMethodDescriptor;
-import java.lang.Character.Subset;
-import java.text.AttributedCharacterIterator;
-import java.text.AttributedCharacterIterator.Attribute;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-//???AWT
-//import javax.swing.JFrame;
-
-import org.apache.harmony.awt.wtk.NativeIM;
-
-/**
- * Implementation of InputMethodContext
- * interface, also provides all useful
- * functionality of InputContext
- * 
- */
-public class InputMethodContext extends InputContext implements
-        java.awt.im.spi.InputMethodContext {    
-
-    //???AWT
-    private InputMethod inputMethod; // current IM
-    private Component client; // current "active" client component
-    //???AWT: private CompositionWindow composeWindow; // composition Window    
-    private final Map<InputMethodDescriptor, InputMethod> imInstances; // Map<InputMethodDescriptor, InputMethod>
-    private final Map<Locale, InputMethod> localeIM; // Map<Locale, InputMethod> last user-selected IM for locale
-    private final Set<InputMethod> notifyIM; // set of IMs to notify of client window bounds changes
-    
-    /**
-     * a flag indicating that IM should be notified of client window
-     * position/visibility changes as soon as it is activated(new client
-     * appears)
-     */    
-    private boolean pendingClientNotify;
-    private Component nextComp; // component to gain focus after endComposition()
-    //???AWT: private final Set<Window> imWindows; // set of all IM windows created by this instance
-    private final NativeIM nativeIM;
-    
-
- 
-    public InputMethodContext() {
-        notifyIM = new HashSet<InputMethod>();
-//???AWT:        imWindows = new HashSet<Window>();
-        imInstances = new HashMap<InputMethodDescriptor, InputMethod>();
-        localeIM = new HashMap<Locale, InputMethod>();
-        selectInputMethod(Locale.US); // not default?
-        nativeIM = (NativeIM) inputMethod;
-    }
-
-    //???AWT
-    /*
-    @Override
-    public void dispatchEvent(AWTEvent event) {
-        int id = event.getID(); 
-        if ((id >= FocusEvent.FOCUS_FIRST) && (id <=FocusEvent.FOCUS_LAST)) {
-            dispatchFocusEvent((FocusEvent) event);
-        } else {
-            // handle special KEY_PRESSED
-            // event to show IM selection menu
-            if (id == KeyEvent.KEY_PRESSED) {
-                KeyEvent ke = (KeyEvent) event;
-                IMManager.selectIM(ke, this, 
-                                   IMManager.getWindow(ke.getComponent()));
-            }
-            // dispatch all input events to the current IM:
-            if (inputMethod != null) {
-                inputMethod.dispatchEvent(event);
-            }
-        }
-    }
-    
-    private void dispatchFocusEvent(FocusEvent fe) {
-        switch (fe.getID()) {
-        case FocusEvent.FOCUS_LOST:            
-            if (inputMethod != null) {
-                inputMethod.deactivate(fe.isTemporary());                
-            }
-            break;
-        case FocusEvent.FOCUS_GAINED:
-            
-            Component comp = fe.getComponent();
-            if (imWindows.contains(comp)) {
-                // prevent activating when IM windows
-                // attached to this context gain focus                
-                return;
-            }
-            InputMethodContext lastActive = IMManager.getLastActiveIMC();
-            if ((lastActive != this) && (lastActive != null)) {
-                lastActive.hideWindows();
-            }
-            if (inputMethod != null) {
-                activateIM(inputMethod);
-                if (!getCompositionWindow().isEmpty()) {
-                    IMManager.showCompositionWindow(composeWindow);
-                }
-                if (client == comp) {
-                    if (nextComp != null) {
-                        // temporarily got focus to
-                        // end composition
-                        endComposition();
-
-                        // transfer focus to new client
-                        client = nextComp;
-                        nextComp = null;
-                        client.requestFocusInWindow();
-                    }
-                } else if ((client != null) && getCompositionWindow().isVisible()) {
-                    // temporarily return focus back
-                    // to previous client to be able
-                    // to end composition
-                    nextComp = comp;
-                    client.requestFocusInWindow();
-                } else {
-                    client = comp;
-                }
-            }
-            if (pendingClientNotify) {
-                notifyClientWindowChange(IMManager.getWindow(comp).getBounds());
-            }
-            break;
-        }
-
-    }
-
-    private void activateIM(InputMethod im) {
-        im.activate();
-        if ((nativeIM != null) && (im != nativeIM)) {
-            // when Java IM is active
-            // native input method editor must be
-            // explicitly disabled
-            nativeIM.disableIME();
-        }
-        IMManager.setLastActiveIMC(this);
-    }
-
-    @SuppressWarnings("deprecation")
-    private void hideWindows() {
-        if (inputMethod != null) {
-            inputMethod.hideWindows();
-        }
-        if (composeWindow != null) {
-            composeWindow.hide();
-        }
-    }
-
-    private void createCompositionWindow() {
-        composeWindow = new CompositionWindow(client);        
-    }
-    
-    private CompositionWindow getCompositionWindow() {
-        if (composeWindow == null) {
-            createCompositionWindow();
-        }
-        composeWindow.setClient(client);
-        return composeWindow;        
-    }
-    */
-    
-    /**
-     * Gets input method requests for the current client
-     * irrespective of input style.
-     * @return input method requests of composition window if
-     * client is passive,
-     * otherwise input method requests of client
-     */
-    private InputMethodRequests getIMRequests() {
-        InputMethodRequests imRequests = null;
-    
-        if (client != null) {
-            imRequests = client.getInputMethodRequests();
-            //???AWT
-            /*
-            if (imRequests == null) {                
-                imRequests = getCompositionWindow().getInputMethodRequests();
-            }
-            */
-        }
-        
-        return imRequests;
-    }
-    
-    /**
-     * Gets input method requests for the current client & input style.
-     * @return input method requests of composition window if
-     * input style is "below-the-spot"(or client is passive),
-     * otherwise client input method requests
-     */
-    private InputMethodRequests getStyleIMRequests() {
-        //???AWT
-        /*
-        if (IMManager.belowTheSpot()) {
-            return getCompositionWindow().getInputMethodRequests();
-        }
-        */
-        return getIMRequests();
-    }
-    
-    @Override
-    public void dispose() {
-        if (inputMethod != null) {
-            closeIM(inputMethod);
-            inputMethod.dispose();
-        }
-        notifyIM.clear();
-        super.dispose();
-    }
-
-    @Override
-    public void endComposition() {
-        if (inputMethod != null) {
-            inputMethod.endComposition();
-        }
-        super.endComposition();
-    }
-
-    @Override
-    public Object getInputMethodControlObject() {
-        if (inputMethod != null) {
-            return inputMethod.getControlObject();
-        }
-        return super.getInputMethodControlObject();
-    }
-
-    @Override
-    public Locale getLocale() {
-        if (inputMethod != null) {
-            return inputMethod.getLocale();
-        }
-        return super.getLocale();
-    }
-
-    @Override
-    public boolean isCompositionEnabled() {
-        if (inputMethod != null) {
-            return inputMethod.isCompositionEnabled();
-        }
-        return super.isCompositionEnabled();
-    }
-
-    @Override
-    public void reconvert() {
-        if (inputMethod != null) {
-            inputMethod.reconvert();
-        }
-        super.reconvert();
-    }
-
-    //???AWT
-    /*
-    @Override
-    public void removeNotify(Component client) {
-        if ((inputMethod != null) && (client == this.client)) {
-            inputMethod.removeNotify();
-            client = null;
-            // set flag indicating that IM should be notified
-            // as soon as it is activated(new client appears)
-            pendingClientNotify = true;
-        }
-        
-        super.removeNotify(client);
-    }
-    */
-
-    @Override
-    public boolean selectInputMethod(Locale locale) {        
-        
-        if ((inputMethod != null) && inputMethod.setLocale(locale)) {
-            return true;
-        }
-        // first
-        // take last user-selected IM for locale            
-        InputMethod newIM = localeIM.get(locale);
-        
-        // if not found search through IM descriptors
-        // and take already created instance if exists
-        // or create, store new IM instance in descriptor->instance map
-        //???AWT
-        /*
-        if (newIM == null) {
-            try {
-                newIM = getIMInstance(IMManager.getIMDescriptors().iterator(),
-                                      locale);
-            } catch (Exception e) {
-                // ignore exceptions - just return false
-            }
-        }
-        */
-        
-        return switchToIM(locale, newIM);
-    }
-
-    private boolean switchToIM(Locale locale, InputMethod newIM) {
-        //???AWT
-        /*
-        if (newIM != null) {
-            closeIM(inputMethod);
-            client = KeyboardFocusManager.
-            getCurrentKeyboardFocusManager().getFocusOwner();
-            initIM(newIM, locale);
-            inputMethod = newIM;
-            
-            return true;
-        }
-        */
-        return false;
-    }
-    
-    /**
-     * Is called when IM is selected from UI
-     */
-    void selectIM(InputMethodDescriptor imd, Locale locale) {
-        try {
-            switchToIM(locale, getIMInstance(imd));            
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Gets input method instance for the given
-     * locale from the given list of descriptors
-     * @param descriptors iterator of the list of IM descriptors
-     * @param locale the locale to be supported by the IM
-     * @return input method instance
-     * @throws Exception
-     */
-    private InputMethod getIMInstance(Iterator<InputMethodDescriptor> descriptors,
-                                      Locale locale) throws Exception {
-        while (descriptors.hasNext()) {
-            InputMethodDescriptor desc = descriptors.next();
-            Locale[] locs = desc.getAvailableLocales();
-            for (Locale element : locs) {
-                if (locale.equals(element)) {
-                    return getIMInstance(desc);
-                }
-            }
-        }
-        return null;
-    }
-
-    private InputMethod getIMInstance(InputMethodDescriptor imd) throws Exception {
-        InputMethod im = imInstances.get(imd);
-        if (im == null) {
-            im = imd.createInputMethod();
-            im.setInputMethodContext(this);
-            imInstances.put(imd, im);
-        }
-        return im;
-    }
-    
-    private void initIM(InputMethod im, Locale locale) {
-        if (im == null) {
-            return;
-        }
-        im.setLocale(locale);
-        im.setCharacterSubsets(null);
-        //???AWT: activateIM(im);
-        try {
-            im.setCompositionEnabled(inputMethod != null ? 
-                                     inputMethod.isCompositionEnabled() : true);
-        } catch (UnsupportedOperationException uoe) {
-
-        }
-        
-    }
-
-    private void closeIM(InputMethod im) {
-        if (im == null) {
-            return;
-        }
-        if (im.isCompositionEnabled()) {
-            im.endComposition();
-        }
-        
-        im.deactivate(true);
-        im.hideWindows();
-        
-    }
-    
-    @Override
-    public void setCharacterSubsets(Subset[] subsets) {
-        if (inputMethod != null) {
-            inputMethod.setCharacterSubsets(subsets);
-        }
-        super.setCharacterSubsets(subsets);
-    }
-
-    @Override
-    public void setCompositionEnabled(boolean enable) {
-        if (inputMethod != null) {
-            inputMethod.setCompositionEnabled(enable);
-        }
-        super.setCompositionEnabled(enable);
-    }
-
-    //???AWT
-    /*
-    public JFrame createInputMethodJFrame(String title,
-                                          boolean attachToInputContext) {
-        JFrame jf = new IMJFrame(title, attachToInputContext ? this : null);
-        imWindows.add(jf);
-        return jf;
-    }
-
-    public Window createInputMethodWindow(String title,
-                                          boolean attachToInputContext) {
-        Window w = new IMWindow(title, attachToInputContext ? this : null);
-        imWindows.add(w);
-        return w;
-    }
-    */
-    
-    @SuppressWarnings("deprecation")
-    public void dispatchInputMethodEvent(int id,
-                                         AttributedCharacterIterator text,
-                                         int committedCharacterCount,
-                                         TextHitInfo caret,
-                                         TextHitInfo visiblePosition) {
-        if (client == null) {
-            return;
-        }
-        //???AWT
-        /*
-        InputMethodEvent ime = new InputMethodEvent(client, id, text,
-                                                    committedCharacterCount,
-                                                    caret, visiblePosition);
-        
-
-        if ((client.getInputMethodRequests() != null) &&
-            !IMManager.belowTheSpot()) {
-            
-            client.dispatchEvent(ime);
-        } else {
-            
-            // show/hide composition window if necessary
-            if (committedCharacterCount < text.getEndIndex()) {
-                IMManager.showCompositionWindow(getCompositionWindow());
-            } else {
-                getCompositionWindow().hide();
-            }
-            composeWindow.getActiveClient().dispatchEvent(ime);
-        }
-        */
-        
-    }
-
-    public void enableClientWindowNotification(InputMethod inputMethod,
-                                               boolean enable) {
-        if (enable) {
-            notifyIM.add(inputMethod);
-            //???AWT
-            /*
-            if (client != null) {
-                notifyClientWindowChange(IMManager.getWindow(client).getBounds());
-            } else {
-                pendingClientNotify = true;
-            }
-            */
-        } else {
-            notifyIM.remove(inputMethod);
-        }
-        
-    }
-
-    public AttributedCharacterIterator cancelLatestCommittedText(
-                                                                 Attribute[] attributes) {
-        return getIMRequests().cancelLatestCommittedText(attributes);
-    }
-
-    public AttributedCharacterIterator getCommittedText(int beginIndex,
-                                                        int endIndex,
-                                                        Attribute[] attributes) {
-        return getIMRequests().getCommittedText(beginIndex, endIndex,
-                                                attributes);
-    }
-
-    public int getCommittedTextLength() {
-        return getIMRequests().getCommittedTextLength();
-    }
-
-    public int getInsertPositionOffset() {
-        return getIMRequests().getInsertPositionOffset();
-    }
-
-    public TextHitInfo getLocationOffset(int x, int y) {
-        InputMethodRequests imr = getStyleIMRequests();
-        if (imr != null) {
-            return imr.getLocationOffset(x, y);
-        }
-        return null;
-    }
-
-    public AttributedCharacterIterator getSelectedText(Attribute[] attributes) {
-        return getIMRequests().getSelectedText(attributes);
-    }
-
-    public Rectangle getTextLocation(TextHitInfo offset) {        
-        return getStyleIMRequests().getTextLocation(offset);
-    }
-    
-    /**
-     * To be called by AWT when client Window's bounds/visibility/state
-     * change
-     */
-    public void notifyClientWindowChange(Rectangle bounds) {
-        if (notifyIM.contains(inputMethod)) {
-            inputMethod.notifyClientWindowChange(bounds);
-        }
-        pendingClientNotify = false;
-    }
-
-    public final InputMethod getInputMethod() {
-        return inputMethod;
-    }
-
-    public final Component getClient() {
-        return client;
-    }
-
-    public final NativeIM getNativeIM() {
-        return nativeIM;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/internal/nls/Messages.java b/awt/org/apache/harmony/awt/internal/nls/Messages.java
deleted file mode 100644
index c340358..0000000
--- a/awt/org/apache/harmony/awt/internal/nls/Messages.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-package org.apache.harmony.awt.internal.nls;
-
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-deleted
-/*
- * For Android, this module is a separate library and not part of the
- * boot classpath, so its resources won't be found on the boot classpath
- * as is assumed by MsgHelp.getString(). We instead use a local MsgHelp
- * which bottoms out in a call to the useful part of its lower-level
- * namesake.
- */
-//import org.apache.harmony.kernel.vm.VM;
-//import org.apache.harmony.luni.util.MsgHelp;
-// END android-deleted
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.awt.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-deleted
-    //private static final String sResource =
-    //    "org.apache.harmony.awt.internal.nls.messages";
-    // END android-deleted
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java b/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java
deleted file mode 100644
index b57fe11..0000000
--- a/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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 implementation is based on the class of the same name in
- * org.apache.harmony.luni.util.
- */
-
-package org.apache.harmony.awt.internal.nls;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.logging.Logger;
-import java.util.Locale;
-import java.util.PropertyResourceBundle;
-import java.util.ResourceBundle;
-import java.util.MissingResourceException;
-
-/**
- * This class contains helper methods for loading resource bundles and
- * formatting external message strings.
- */
-public final class MsgHelp {
-    /** name of the resource for this class */
-    private static final String RESOURCE_NAME =
-        "/org/apache/harmony/awt/internal/nls/messages.properties";
-
-    /** the resource bundle for this class */
-    private static final ResourceBundle THE_BUNDLE;
-
-    static {
-        ResourceBundle rb = null;
-
-        try {
-            InputStream in = MsgHelp.class.getResourceAsStream(
-                    RESOURCE_NAME);
-            rb = new PropertyResourceBundle(in);
-        } catch (IOException ex) {
-            Logger.global.warning("Couldn't read resource bundle: " +
-                    ex);
-        } catch (RuntimeException ex) {
-            // Shouldn't happen, but deal at least somewhat gracefully.
-            Logger.global.warning("Couldn't find resource bundle: " +
-                    ex);
-        }
-
-        THE_BUNDLE = rb;
-    }
-    
-    public static String getString(String msg) {
-        if (THE_BUNDLE == null) {
-            return msg;
-        }
-        try {
-            return THE_BUNDLE.getString(msg);
-        } catch (MissingResourceException e) {
-            return "Missing message: " + msg;
-        }
-    }
-    
-    static public String getString(String msg, Object[] args) {
-        String format = msg;
-        if (THE_BUNDLE != null) {
-            try {
-                format = THE_BUNDLE.getString(msg);
-            } catch (MissingResourceException e) {
-            }
-        }
-
-        return org.apache.harmony.luni.util.MsgHelp.format(format, args);
-    }
-}
diff --git a/awt/org/apache/harmony/awt/state/MenuItemState.java b/awt/org/apache/harmony/awt/state/MenuItemState.java
deleted file mode 100644
index b13e50b..0000000
--- a/awt/org/apache/harmony/awt/state/MenuItemState.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt.state;
-
-import java.awt.Dimension;
-import java.awt.Rectangle;
-
-/**
- * State of menu item
- */
-
-public interface MenuItemState {
-
-    String getText();
-    Rectangle getTextBounds();
-    void setTextBounds(int x, int y, int w, int h);
-
-    String getShortcut();
-    Rectangle getShortcutBounds();
-    void setShortcutBounds(int x, int y, int w, int h);
-
-    Rectangle getItemBounds();
-    void setItemBounds(int x, int y, int w, int h);
-
-    boolean isMenu();
-    boolean isChecked();
-    boolean isEnabled();
-
-    boolean isCheckBox();
-    boolean isSeparator();
-
-    Dimension getMenuSize();
-}
diff --git a/awt/org/apache/harmony/awt/state/MenuState.java b/awt/org/apache/harmony/awt/state/MenuState.java
deleted file mode 100644
index 564a49a..0000000
--- a/awt/org/apache/harmony/awt/state/MenuState.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt.state;
-
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Point;
-
-/**
- * State of pop-up or drop-down menu
- */
-
-public interface MenuState {
-    int getWidth();
-    int getHeight();
-    Point getLocation();
-
-    void setSize(int w, int h);
-
-    Font getFont();
-    boolean isFontSet();
-    FontMetrics getFontMetrics(Font f);
-
-    int getItemCount();
-    int getSelectedItemIndex();
-
-    MenuItemState getItem(int index);
-}
diff --git a/awt/org/apache/harmony/awt/state/State.java b/awt/org/apache/harmony/awt/state/State.java
deleted file mode 100644
index 4b8706d..0000000
--- a/awt/org/apache/harmony/awt/state/State.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt.state;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Rectangle;
-
-/**
- * State of the component
- */
-public interface State {
-
-    boolean isEnabled();
-    boolean isVisible();
-    boolean isFocused();
-
-    Font getFont();
-    boolean isFontSet();
-    FontMetrics getFontMetrics();
-
-    Color getBackground();
-    boolean isBackgroundSet();
-
-    Color getTextColor();
-    boolean isTextColorSet();
-
-    Rectangle getBounds();
-    Dimension getSize();
-
-    Dimension getDefaultMinimumSize();
-    void setDefaultMinimumSize(Dimension size);
-
-    long getWindowId();
-}
diff --git a/awt/org/apache/harmony/awt/wtk/CreationParams.java b/awt/org/apache/harmony/awt/wtk/CreationParams.java
deleted file mode 100644
index 63c581d..0000000
--- a/awt/org/apache/harmony/awt/wtk/CreationParams.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-/**
- * This class describes cross-platform NativeWindow creation params
- * See also WindowFactory.createWindow
- */
-public class CreationParams {
-    /**
-     * Initial state is maximized verticaly
-     */
-    public final long MAXIMIZED_VERT = 1;
-    /**
-     * Initial state is maximized horizontaly
-     */
-    public final long MAXIMIZED_HORIZ = 2;
-    /**
-     * Initial state is maximized both
-     * horizontaly and verticaly
-     */
-    public final long MAXIMIZED = 3;
-
-    /**
-     * The top-level window that has all possible decorations,
-     * has no owner and is displayed in taskbar
-     */
-    public final static int DECOR_TYPE_FRAME = 1;
-    /**
-     * The dialog window
-     */
-    public final static int DECOR_TYPE_DIALOG = 2;
-    /**
-     * The transient undecorated pop-up window
-     */
-    public final static int DECOR_TYPE_POPUP = 3;
-    /**
-     * The undecoraded pop-up window
-     */
-    public final static int DECOR_TYPE_UNDECOR = 4;
-    /**
-     * Non-MDI child window
-     */
-    public final static int DECOR_TYPE_NONE = 0;
-
-    /**
-     * Initial x.
-     */
-    public int x = 0;
-    /**
-     * Initial y.
-     */
-    public int y = 0;
-    /**
-     * Initial width.
-     */
-    public int w = 1;
-    /**
-     * Initial height.
-     */
-    public int h = 1;
-    /**
-     * The decoration type of the top-level window. The possible values are:
-     * DECOR_TYPE_FRAME, DECOR_TYPE_DIALOG, DECOR_TYPE_POPUP and DECOR_TYPE_UNDECOR
-     */
-    public int decorType = DECOR_TYPE_NONE;
-    /**
-     * Window is child of parent, otherwise it's
-     * toplevel(child of desktop) window owned by parent.
-     */
-    public boolean child = false;
-    /**
-     * Window is resizable
-     */
-    public boolean resizable = true;
-    /**
-     * The window has no decorations
-     */
-    public boolean undecorated = false;
-    /**
-     * Initial visibility state.
-     */
-    public boolean visible = false;
-    /**
-     * Window is ALWAYS topmost in Z order.
-     */
-    public boolean topmost = false;
-    /**
-     * Window is disabled.
-     */
-    public boolean disabled = false;
-    /**
-     * Window initially iconified.
-     */
-    public boolean iconified = false;
-    /**
-     * Bitwise OR of MAXIMIZED_* constants.
-     * Means if window is initially maximized.
-     */
-    public int maximizedState = 0;
-    /**
-     * Tells that window position should be determined by native windowing system 
-     */
-    public boolean locationByPlatform = false;
-    /**
-     * Id of parent or owner window, see child field
-     * For non-child window without owner equals 0.
-     */
-    public long parentId = 0;
-    /**
-     * Name wich is displayed on titlebar, taskbar and visible
-     * for system requests.
-     */
-    public String name = null;
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/wtk/CursorFactory.java b/awt/org/apache/harmony/awt/wtk/CursorFactory.java
deleted file mode 100644
index 35e7d33..0000000
--- a/awt/org/apache/harmony/awt/wtk/CursorFactory.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.Dimension;
-import java.awt.Image;
-
-/**
- * Provides factory for NativeCursor
- */
-public abstract class CursorFactory {
-    protected NativeCursor[] systemCursors = {
-            null, null, null, null,
-            null, null, null, null,
-            null, null, null, null,
-            null, null,
-    };
-    /**
-     * Creates and returns NativeCursor for predefined
-     * Java Cursor
-     *
-     * @param type - type of predefined Java Cursor
-     * @return created cursor
-     */
-    public abstract NativeCursor createCursor(int type);
-
-    /**
-     * Gets a cached instance of system(predefined) native cursor
-     * or creates a new one. This is a platform-independent method.
-     *
-     * @param type - type of predefined Java Cursor
-     * @return created cursor
-     */
-    public NativeCursor getCursor(int type) {
-        if (type >= 0 && type < systemCursors.length) {
-            NativeCursor cursor = systemCursors[type];
-            if (cursor == null) {
-                cursor = createCursor(type);
-                systemCursors[type] = cursor;
-            }
-            return cursor;
-        }
-        return null;
-    }
-    /**
-     * Creates and returns custom NativeCursor from image
-     *
-     * @param img - image(source) to create cursor from
-     * @param xHotSpot - x coordinate of the hotspot relative to the source's origin
-     * @param yHotSpot - y coordinate of the hotspot relative to the source's origin
-     * @return created cursor
-     */
-    public abstract NativeCursor createCustomCursor(Image img, int xHotSpot, int yHotSpot);
-
-    /**
-     * Query native system for the best cursor size closest to specified dimensions
-     * @param prefWidth - preferred width
-     * @param prefHeight - preferred height
-     * @return closest supported dimensions to ones specified
-     */
-    public abstract Dimension getBestCursorSize(int prefWidth, int prefHeight);
-
-    /**
-     * @return maximum number of colors supported by custom cursors
-     */
-    public abstract int getMaximumCursorColors();
-}
diff --git a/awt/org/apache/harmony/awt/wtk/GraphicsFactory.java b/awt/org/apache/harmony/awt/wtk/GraphicsFactory.java
deleted file mode 100644
index 0d7c84f..0000000
--- a/awt/org/apache/harmony/awt/wtk/GraphicsFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov, Alexey A. Petrenko, Oleg V. Khaschansky
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.GraphicsEnvironment;
-import java.awt.peer.FontPeer;
-import org.apache.harmony.awt.gl.MultiRectArea;
-import org.apache.harmony.awt.gl.font.FontManager;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-
-
-/**
- * GraphicsFactory interface defines methods for Graphics2D 
- * and font stuff instances factories.
- */
-public interface GraphicsFactory {
-    static final FontMetrics cacheFM[] =  new FontMetrics[10];
-    
-    /**
-     * This method creates Graphics2D instance for specified native window.
-     *  
-     * @param win Native window to draw
-     * @param translateX Translation along X axis
-     * @param translateY Translation along Y axis
-     * @param clip Clipping area for a new Graphics2D instance
-     * @return New Graphics2D instance for specified native window
-     * @deprecated
-     */
-    @Deprecated
-    Graphics2D getGraphics2D(NativeWindow win, int translateX, int translateY, MultiRectArea clip);
-
-    /**
-     * This method creates Graphics2D instance for specified native window.
-     *  
-     * @param win Native window to draw
-     * @param translateX Translation along X axis
-     * @param translateY Translation along Y axis
-     * @param width Width of drawing area
-     * @param height Height of drawing area
-     * @return New Graphics2D instance for specified native window
-     */
-    Graphics2D getGraphics2D(NativeWindow win, int translateX, int translateY, int width, int height);
-    // ???AWT: not standard harmony
-    Graphics2D getGraphics2D(Canvas c, Paint p);
-    
-    /**
-     * Creates instance of GraphicsEnvironment for specified WindowFactory
-     *  
-     * @param wf WindowFactory
-     * @return New instance of GraphicsEnvironment
-     */
-    GraphicsEnvironment createGraphicsEnvironment(WindowFactory wf);
-    
-    // Font methods
-    FontMetrics getFontMetrics(Font font);
-    FontManager getFontManager();
-    FontPeer getFontPeer(Font font);
-    Font embedFont(String fontFilePath);
-}
diff --git a/awt/org/apache/harmony/awt/wtk/KeyInfo.java b/awt/org/apache/harmony/awt/wtk/KeyInfo.java
deleted file mode 100644
index 1f8a29a..0000000
--- a/awt/org/apache/harmony/awt/wtk/KeyInfo.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.event.KeyEvent;
-
-/**
- * Keystroke information
- */
-
-public final class KeyInfo {
-
-    public int vKey;
-    public int keyLocation;
-    public final StringBuffer keyChars;
-
-    public static final int DEFAULT_VKEY = KeyEvent.VK_UNDEFINED;
-    public static final int DEFAULT_LOCATION = KeyEvent.KEY_LOCATION_STANDARD;
-
-    public KeyInfo() {
-        vKey = DEFAULT_VKEY;
-        keyLocation = DEFAULT_LOCATION;
-        keyChars = new StringBuffer();
-    }
-
-    public void setKeyChars(char ch) {
-        keyChars.setLength(0);
-        keyChars.append(ch);
-    }
-
-    public void setKeyChars(StringBuffer sb) {
-        keyChars.setLength(0);
-        keyChars.append(sb);
-    }
-}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeCursor.java b/awt/org/apache/harmony/awt/wtk/NativeCursor.java
deleted file mode 100644
index 2c6eb1e..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeCursor.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-/**
- * The interface provides access to platform dependent functionality
- * for the class java.awt.Cursor.
- */
-public interface NativeCursor {
-    /**
-     * Sets the current cursor shape
-     * to this cursor when a pointer is inside
-     * @param winID - window(currently used only on X11)
-     */
-    void setCursor(long winID);
-    /**
-     * Destroys the native resource associated with
-     * this cursor
-     */
-    void destroyCursor();
-
-    /**
-     * @return Native handle associated with this cursor
-     */
-    long getId();
-
-}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeEvent.java b/awt/org/apache/harmony/awt/wtk/NativeEvent.java
deleted file mode 100644
index 1471c1a..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeEvent.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Mikhail Danilov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.Insets;
-import java.awt.Rectangle;
-import java.awt.Point;
-import java.awt.event.KeyEvent;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-
-
-/**
- * The interface describing cross-platform translation of system
- * messages.
- *
- * <p/>Some messages can appear only on specific platform,
- * but they still can have cross-platform interpretation if the
- * application should be aware of them and can react using
- * cross-platform API.
- *
- */
-public abstract class NativeEvent {
-
-    /**
-     * Message has no common cross-platform
-     * interpretation and should be skipped.
-     */
-    public static final int ID_PLATFORM = 0;
-
-    /**
-     * Window bounds have changed.
-     */
-    public static final int ID_BOUNDS_CHANGED = -1;
-
-    /**
-     * Window decoration size has changed.
-     */
-    public static final int ID_INSETS_CHANGED = -2;
-
-    /**
-     * Window was just created (WM_CREATE on Windows)
-     */
-    public static final int ID_CREATED = -3;
-
-    /**
-     * Mouse grab was canceled by the native system
-     */
-    public static final int ID_MOUSE_GRAB_CANCELED = -4;
-
-    /**
-     * System color scheme or visual theme was changed
-     */
-    public static final int ID_THEME_CHANGED = -5;
-
-    protected long windowId;
-    protected int eventId;
-    protected long otherWindowId;
-
-    protected Point screenPos;
-    protected Point localPos;
-    protected Rectangle windowRect;
-
-    protected int modifiers;
-    protected int mouseButton;
-    protected int wheelRotation;
-
-    protected KeyInfo keyInfo = new KeyInfo();
-
-    protected int windowState = -1;
-    protected long time;
-
-    /**
-     * Returns the system window id of the event recipient.
-     * @return HWND on Windows, xwindnow on X
-     */
-    public long getWindowId() {
-        return windowId;
-    }
-
-    /**
-     * Returns cross-platform event id
-     * should be one of ID_* constants or
-     * id constants from java.awt.AWTEvent subclasess
-     * @return cross-platform event id
-     */
-    public int getEventId() {
-        return eventId;
-    }
-
-    /**
-     * Returns the position of cursor when event occured relative to
-     * top-left corner of recipient window
-     * @return position of cursor in local coordinates
-     */
-    public Point getLocalPos() {
-        return localPos;
-    }
-
-    /**
-     * Returns the position of cursor when event occured
-     * in screen coordinates.
-     * @return position of cursor in screen coordinates
-     */
-    public Point getScreenPos() {
-        return screenPos;
-    }
-
-    /**
-     * The recipient window bounds when the event occured
-     * @return window bounds
-     */
-    public Rectangle getWindowRect() {
-        return windowRect;
-    }
-
-    /**
-     * Returns the state of keyboard and mouse buttons when the event
-     * occured if event from mouse or keyboard, for other events can
-     * return junk values. The value is bitwise OR of
-     * java.awt.event.InputEvent *_DOWN constants.
-     *
-     * Method is aware of system mouse button swap for left-hand
-     * mouse and return swapped values.
-     * @return bitwise OR of java.awt.event.InputEvent *_DOWN constants
-     */
-    public int getInputModifiers() {
-        return modifiers;
-    }
-
-    /**
-     * Returns the iconified/maximized state of recipient window if
-     * event is state related, for other events can junk values.
-     * The value has the same meaning as Frame.getExtendedState
-     * It's bitwise OR of ICONIFIED, MAXIMIZED_HORIZ, MAXIMIZED_VERT
-     * @return bitwise OR of ICONIFIED, MAXIMIZED_HORIZ, MAXIMIZED_VERT
-     */
-    public int getWindowState() {
-        return windowState;
-    }
-
-    /**
-     * The same meaning as java.awt.event.getKeyCode
-     * @return java.awt.event VK_* constant
-     */
-    public int getVKey() {
-        return (keyInfo != null) ? keyInfo.vKey : KeyInfo.DEFAULT_VKEY;
-    }
-
-    /**
-     * The same meaning as java.awt.event.getKeyLocation
-     * @return java.awt.event KEY_LOCATION_* constant
-     */
-    public int getKeyLocation() {
-        return (keyInfo != null) ? keyInfo.keyLocation : KeyInfo.DEFAULT_LOCATION;
-    }
-
-    /**
-     * Return the string of characters associated with the event
-     * Has meaning only for KEY_PRESSED as should be translated to
-     * serie of KEY_TYPED events. For dead keys and input methods
-     * one key press can generate multiple key chars.
-     * @return string of characters
-     */
-    public StringBuffer getKeyChars() {
-        if (keyInfo == null) {
-            return null;
-        }
-        if (keyInfo.vKey == KeyEvent.VK_ENTER) {
-            keyInfo.keyChars.setLength(0);
-            keyInfo.setKeyChars('\n');
-        }
-        return keyInfo.keyChars;
-    }
-
-    public char getLastChar() {
-        if (keyInfo == null || keyInfo.keyChars.length() == 0) {
-            return KeyEvent.CHAR_UNDEFINED;
-        }
-        return keyInfo.keyChars.charAt(keyInfo.keyChars.length()-1);
-    }
-
-    /**
-     * Returns the number of mouse button which changed it's state,
-     * otherwise 0.
-     * Left button is 1, middle button is 2, right button is 3.
-     *
-     * Method is aware of system mouse button swap for left-hand
-     * mouse and return swapped values.
-     * @return mouse button number
-     */
-    public int getMouseButton() {
-        return mouseButton;
-    }
-
-    /**
-     * Returns time when the message was received
-     * @return time in milliseconds
-     */
-    public long getTime() {
-        return time;
-    }
-
-    /**
-     * For the focus event contains the oposite window.
-     * This means it lost focus if recipient gains it,
-     * or will gain focus if recipient looses it.
-     * @return HWND on Windows, xwindnow on X
-     */
-    public long getOtherWindowId() {
-        return otherWindowId;
-    }
-
-    /**
-     * Returns the "dirty" area of the window as set of non-intersecting
-     * rectangles. This area is to be painted.
-     * @return non-empty array of null if empty
-     */
-    public abstract MultiRectArea getClipRects();
-
-    /**
-     * Returns the "dirty" area of the window as one rectangle.
-     * This area is to be painted.
-     * @return non-null Rectangle
-     */
-    public abstract Rectangle getClipBounds();
-
-    /**
-     * Returns the window insets. Insets is area which belongs to
-     * window somehow but is outside of it's client area,
-     * it usually contains system provided border and titlebar.
-     * @return non-null java.awt.Insets
-     */
-    public abstract Insets getInsets();
-
-    /**
-     * Returns true if event is popup menu trigger.
-     * @return boolean flag
-     */
-    public abstract boolean getTrigger();
-
-    /**
-     * Returns the number of "clicks" the mouse wheel was rotated.
-     * @return negative values if the mouse wheel was rotated up/away from the user,
-     * and positive values if the mouse wheel was rotated down/ towards the user
-     */
-    public int getWheelRotation() {
-        return wheelRotation;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeEventQueue.java b/awt/org/apache/harmony/awt/wtk/NativeEventQueue.java
deleted file mode 100644
index 0738cd1..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeEventQueue.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Mikhail Danilov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.util.LinkedList;
-
-
-/**
- * Describes the cross-platform native event queue interface
- *
- * <p/> The implementation constructor should remember thread it was
- * created. All other methods would be called obly from this thread,
- * except awake().
- */
-public abstract class NativeEventQueue {
-    
-    private ShutdownWatchdog shutdownWatchdog;
-    private class EventMonitor {}
-    private final Object eventMonitor = new EventMonitor();
-    private final LinkedList<NativeEvent> eventQueue = new LinkedList<NativeEvent>();
-
-    public static abstract class Task {
-        public volatile Object returnValue;
-
-        public abstract void perform();
-    }
-    
-    /**
-     * Blocks current thread until native event queue is not empty
-     * or awaken from other thread by awake().
-     *
-     * <p/>Should be called only on tread which
-     * will process native events.
-     *
-     * @return if event loop should be stopped
-     */
-    public abstract boolean waitEvent();
-
-    /**
-     * Determines whether or not the native event queue is empty.
-     * An queue is empty if it contains no messages waiting.
-     *
-     * @return true if the queue is empty; false otherwise
-     */
-    public boolean isEmpty() {
-        synchronized(eventQueue) {
-            return eventQueue.isEmpty();
-        }
-    }
-
-    public NativeEvent getNextEvent() {
-        synchronized (eventQueue) {
-            if (eventQueue.isEmpty()) {
-                shutdownWatchdog.setNativeQueueEmpty(true);
-                return null;
-            }
-            return eventQueue.remove(0);
-        }
-    }
-    
-    protected void addEvent(NativeEvent event) {
-        synchronized (eventQueue) {
-            eventQueue.add(event);
-            shutdownWatchdog.setNativeQueueEmpty(false);
-        }
-        synchronized (eventMonitor) {
-            eventMonitor.notify();
-        }
-    }
-
-    public final Object getEventMonitor() {
-        return eventMonitor;
-    }
-
-    public abstract void awake();
-
-    /**
-     * Gets AWT system window ID.
-     *
-     * @return AWT system window ID
-     */
-    public abstract long getJavaWindow();
-
-    /**
-     * Add NativeEvent to the queue
-     */
-    public abstract void dispatchEvent();
-
-    public abstract void performTask(Task task);
-
-    public abstract void performLater(Task task);
-    
-    public final void setShutdownWatchdog(ShutdownWatchdog watchdog) {
-        synchronized (eventQueue) {
-            shutdownWatchdog = watchdog;
-        }
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeEventThread.java b/awt/org/apache/harmony/awt/wtk/NativeEventThread.java
deleted file mode 100644
index d50add4..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeEventThread.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-
-/**
- * NativeEventThread
- */
-public class NativeEventThread extends Thread {
-    
-    public interface Init {
-        WTK init();
-    }
-    
-    NativeEventQueue nativeQueue;
-    Init init;
-    
-    private WTK wtk;
-    
-    public NativeEventThread() {
-        super("AWT-NativeEventThread"); //$NON-NLS-1$
-        setDaemon(true);
-    }
-
-    @Override
-    public void run() {
-        synchronized (this) {
-            try {
-                wtk = init.init();
-                nativeQueue = wtk.getNativeEventQueue();
-            } finally {
-                notifyAll();
-            }
-        }
-        
-        runModalLoop();
-    }
-
-    void runModalLoop() {
-        while (nativeQueue.waitEvent()) {
-            nativeQueue.dispatchEvent();
-        }
-    }
-    
-    public void start(Init init) {
-        synchronized (this) {
-            this.init = init;
-            super.start();
-            try {
-                wait();
-            } catch (InterruptedException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-    
-    public WTK getWTK() {
-        return wtk;
-    }
-}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeIM.java b/awt/org/apache/harmony/awt/wtk/NativeIM.java
deleted file mode 100644
index 1626f4a..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeIM.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/** 
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.AWTEvent;
-import java.awt.AWTException;
-import java.awt.Image;
-import java.awt.Rectangle;
-import java.awt.im.spi.InputMethod;
-import java.awt.im.spi.InputMethodContext;
-import java.awt.im.spi.InputMethodDescriptor;
-import java.lang.Character.Subset;
-import java.util.Locale;
-
-/**
- * A cross-platform interface for native input
- * method sub-system functionality.
- */
-public abstract class NativeIM implements InputMethod, InputMethodDescriptor {
-    protected InputMethodContext imc;
-
-    public void activate() {
-
-    }
-
-    public void deactivate(boolean isTemporary) {
-
-    }
-
-    public void dispatchEvent(AWTEvent event) {
-
-    }
-
-    public void dispose() {
-
-    }
-
-    public void endComposition() {
-
-    }
-
-    public Object getControlObject() {
-        return null;
-    }
-
-    public Locale getLocale() {
-        return null;
-    }
-
-    public void hideWindows() {
-
-    }
-
-    public boolean isCompositionEnabled() {
-        return false;
-    }
-
-    public void notifyClientWindowChange(Rectangle bounds) {
-
-    }
-
-    public void reconvert() {
-
-    }
-
-    public void removeNotify() {
-
-    }
-
-    public void setCharacterSubsets(Subset[] subsets) {
-
-    }
-    
-    public void setCompositionEnabled(boolean enable) {
-
-    }
-
-    public void setInputMethodContext(InputMethodContext context) {
-        imc = context;
-    }
-
-    public boolean setLocale(Locale locale) {
-        return false;
-    }
-
-    public Locale[] getAvailableLocales() throws AWTException {
-    	return new Locale[]{Locale.getDefault(), Locale.ENGLISH};
-        //return new Locale[]{Locale.getDefault(), Locale.US};
-    }
-
-    public InputMethod createInputMethod() throws Exception {        
-        return this;
-    }
-
-    public String getInputMethodDisplayName(Locale inputLocale,
-                                            Locale displayLanguage) {
-        return "System input methods"; //$NON-NLS-1$
-    }
-
-    public Image getInputMethodIcon(Locale inputLocale) {
-        return null;
-    }
-
-    public boolean hasDynamicLocaleList() {
-        return false;
-    }
-    
-    public abstract void disableIME();
-    
-//    public abstract void disableIME(long id);
-
-}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeMouseInfo.java b/awt/org/apache/harmony/awt/wtk/NativeMouseInfo.java
deleted file mode 100644
index 0696975..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeMouseInfo.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.Point;
-
-/**
- * The interface provides access to platform dependent functionality
- * for classes java.awt.PointerInfo & java.awt.MouseInfo.
- */
-public interface NativeMouseInfo {
-
-    /**
-     * Returns the Point that represents
-     * the coordinates of the pointer on the screen.
-     */
-    Point getLocation();
-
-    /**
-     * Returns the number of buttons on the mouse.
-     * If no mouse is installed returns -1.
-     */
-    int getNumberOfButtons();
-}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeRobot.java b/awt/org/apache/harmony/awt/wtk/NativeRobot.java
deleted file mode 100644
index 0b354d0..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeRobot.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Dmitry A. Durnev
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.Color;
-import java.awt.Rectangle;
-import java.awt.image.BufferedImage;
-
-/**
- * A cross-platform interface for java.awt.Robot implementation
- */
-public interface NativeRobot {
-
-    /**
-     * @see java.awt.Robot#createScreenCapture(Rectangle)
-     * @param screenRect rectangle to capture in screen coordinates
-     * @return the captured image or null if
-     * capture failed.
-     */
-    BufferedImage createScreenCapture(Rectangle screenRect);
-
-    /**
-     * @see java.awt.Robot#getPixelColor(int, int)
-     */
-    Color getPixel(int x, int y);
-
-    /**
-     * Generate a native system keyboard input event.
-     * @param keycode A Java virtual key code
-     * @param press A key is pressed if true, released otherwise
-     * @see java.awt.Robot#keyPress(int)
-     * @throws IllegalArgumentException if keycode is invalid in the native system
-     */
-    void keyEvent(int keycode, boolean press);
-
-    /**
-     * Generate a native system mouse button(s) press or release event.
-     * @param buttons A mask of Java mouse button flags
-     * @param press buttons are pressed if true, released otherwise
-     * @see java.awt.Robot#mousePress(int)
-     */
-    void mouseButton(int buttons, boolean press);
-
-    /**
-     * Generate a native system mouse motion event.
-     *
-     * @see java.awt.Robot#mouseMove(int, int)
-     */
-    void mouseMove(int x, int y);
-
-    /**
-     * Generate a native system mouse wheel event.
-     *
-     * @see java.awt.Robot#mouseWheel(int)
-     */
-    void mouseWheel(int wheelAmt);
-}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeWindow.java b/awt/org/apache/harmony/awt/wtk/NativeWindow.java
deleted file mode 100644
index 73fd6c0..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeWindow.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Mikhail Danilov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.Image;
-import java.awt.Insets;
-import java.awt.Point;
-import java.awt.Rectangle;
-
-import org.apache.harmony.awt.gl.MultiRectArea;
-
-
-/**
- * Provides cross-platform way to manipulate native window.
- *
- * Results of methods are reported through native messages.
- */
-public interface NativeWindow {
-    /**
-     * Returns system id of the associated window
-     * @return HWND on Windows, xwindow on X
-     */
-    long getId();
-
-    /**
-     * Shows/hides window
-     * @param v - new visibility
-     */
-    void setVisible(boolean v);
-
-    /**
-     * Means only size should be changed
-     */
-    static final int BOUNDS_NOMOVE = 1;
-
-    /**
-     * Means only position should be changed
-     */
-    static final int BOUNDS_NOSIZE = 2;
-
-    /**
-     * Tries to set desired window bounds. It's not gurantied the
-     * property will have the desired value. The value change
-     * should be reported by system event (as for other properties).
-     *
-     * <p/>  If child, position is relative to parent window.
-     * @param x - desired x
-     * @param y - desired y
-     * @param w - desired width
-     * @param h - desired height
-     * @param boundsMask - bitwise OR of BOUNDS_* constants.
-     * Governs the new bounds interpretation.
-     */
-    void setBounds(int x, int y, int w, int h, int boundsMask);
-
-    /**
-     * Returns last notified window bounds. This means the last bounds
-     * reported by system event.
-     *
-     * <p/>  If child, position is relative to parent window.
-     * @return last notified window bounds
-     */
-    Rectangle getBounds();
-
-    /**
-     * Returns last notified insets. This means the last insets
-     * reported by system event. Insets are margins around client area
-     * ocupied by system provided decor, ususally border and titlebar.
-     * @return last notified insets
-     */
-    Insets getInsets();
-
-    /**
-     * Enables/disables processing of input (key, mouse) event
-     * by window. If disabled input events are ignored.
-     * @param value - if enabled
-     */
-    void setEnabled(boolean value);
-
-    /**
-     * Sets the "focusable" window state.
-     * @param value - if true makes window focusable
-     */
-    void setFocusable(boolean value);
-
-    /**
-     *
-     * @return current focusable window state
-     */
-    boolean isFocusable();
-
-    /**
-     * Tries to set application input focus to the window or clear
-     * current focus from focused window.
-     *
-     * <p/> For toplevel windows it's not gurantied focus will land in
-     * desired window even if function returns true. Focus traversal should be tracked
-     * by processing system events.
-     *
-     * @param focus  - if true sets focus, else clears focus
-     * @return if success
-     */
-    boolean setFocus(boolean focus);
-
-    /**
-     * Destroys the asscoiated window.
-     * Attempts to use it thereafter can result in
-     * unpredictable bechavior.
-     */
-    void dispose();
-
-    /**
-     * Changes window Z-order to place this window under, If w is null
-     * places places this window on the top. Z-order is per parent.
-     * Toplevels a children of desktop in terms of Z-order.
-     * @param w - window to place under.
-     */
-    void placeAfter(NativeWindow w);
-
-    /**
-     * Places window on top of Z-order
-     */
-    void toFront();
-
-    /**
-     * Places window on bottom of Z-order
-     */
-    void toBack();
-
-    /**
-     * Makes the window resizable/not resizable by user
-     * @param value - if resizable
-     */
-    void setResizable(boolean value);
-
-    /**
-     * Sets the window caption
-     * @param title - caption text
-     */
-    void setTitle(String title);
-
-    /**
-     * Activate the mouse event capturing
-     */
-    void grabMouse();
-
-    /**
-     * Deactivate mouse event capturing
-     */
-    void ungrabMouse();
-
-    /**
-     * Set extended state for top-level window.
-     *
-     * @param state - new state, bitmask of ICONIFIED, MAXIMIZED_BOTH, etc.
-     */
-    void setState(int state);
-
-    /**
-     * Set the image to be displayed in the minimized icon for
-     * top-level [decorated] window.
-     * @param image the icon image to be displayed
-     */
-    void setIconImage(Image image);
-
-    /**
-     * Makes window top-most if value is true,
-     * non-topmost(normal) otherwise.
-     */
-    void setAlwaysOnTop(boolean value);
-
-    /**
-     * Set desired [top-level] window bounds when being in maximized state.
-     * Fields set to Integer.MAX_VALUE are ignored[system-supplied values are
-     * used instead]
-     */
-    void setMaximizedBounds(Rectangle bounds);
-
-    /**
-     * Get absolute position on the screen
-     */
-    Point getScreenPos();
-
-    /**
-     * Set a window "packed" flag:
-     * the flag indicates that if insets change
-     * client area shouldn't be resized, but frame
-     * must be resized instead
-     */
-    void setPacked(boolean packed);
-    
-    /**
-     * Make window an "input method window" by setting
-     * special window style, e. g. small title bar, no
-     * close, minimize/maximize buttons. For internal
-     * use by input method framework.
-     *
-     */
-    void setIMStyle();
-
-    MultiRectArea getObscuredRegion(Rectangle part);
-}
diff --git a/awt/org/apache/harmony/awt/wtk/ShutdownThread.java b/awt/org/apache/harmony/awt/wtk/ShutdownThread.java
deleted file mode 100644
index 701eb46..0000000
--- a/awt/org/apache/harmony/awt/wtk/ShutdownThread.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Michael Danilov, Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-public final class ShutdownThread extends Thread {
-    
-    public static final class Watchdog {
-    }
-
-    public ShutdownThread() {
-        setName("AWT-Shutdown"); //$NON-NLS-1$
-        setDaemon(false);
-    }
-    
-    private boolean shouldStop = false;
-
-    @Override
-    public void run() {
-        synchronized (this) {
-            notifyAll(); // synchronize the startup
-
-            while (true) {
-                try {
-                    wait();
-                } catch (InterruptedException e) {
-                }
-
-                if (shouldStop) {
-                    notifyAll(); // synchronize the shutdown
-                    return;
-                }
-            }
-        }
-    }
-
-    @Override
-    public void start() {
-        synchronized (this) {
-            super.start();
-            try {
-                wait();
-            } catch (InterruptedException e) {
-                // awt.26=Shutdown thread was interrupted while starting
-                throw new RuntimeException(
-                        Messages.getString("awt.26")); //$NON-NLS-1$
-            }
-        }
-    }
-
-    public void shutdown() {
-        synchronized (this) {
-            shouldStop = true;
-            notifyAll();
-            try {
-                wait();
-            } catch (InterruptedException e) {
-                // awt.27=Shutdown thread was interrupted while stopping
-                throw new RuntimeException(
-                        Messages.getString("awt.27")); //$NON-NLS-1$
-            }
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/awt/wtk/ShutdownWatchdog.java b/awt/org/apache/harmony/awt/wtk/ShutdownWatchdog.java
deleted file mode 100644
index 6efa519..0000000
--- a/awt/org/apache/harmony/awt/wtk/ShutdownWatchdog.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/** 
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-/**
- * Shutdown Watchdog
- */
-public final class ShutdownWatchdog {
-    
-    private boolean nativeQueueEmpty = true;
-    private boolean awtQueueEmpty = true;
-    private boolean windowListEmpty = true;
-
-    private boolean forcedShutdown = false;
-    
-    private ShutdownThread thread;
-
-    public synchronized void setNativeQueueEmpty(boolean empty) {
-        nativeQueueEmpty = empty;
-        checkShutdown();
-    }
-
-    public synchronized void setAwtQueueEmpty(boolean empty) {
-        awtQueueEmpty = empty;
-        checkShutdown();
-    }
-
-    public synchronized void setWindowListEmpty(boolean empty) {
-        windowListEmpty = empty;
-        checkShutdown();
-    }
-    
-    public synchronized void forceShutdown() {
-        forcedShutdown = true;
-        shutdown();
-    }
-    
-    public synchronized void start() {
-        keepAlive();
-    }
-
-    private void checkShutdown() {
-        if (canShutdown()) {
-            shutdown();
-        } else {
-            keepAlive();
-        }
-    }
-
-    private boolean canShutdown() {
-        return (nativeQueueEmpty && awtQueueEmpty && windowListEmpty) ||
-                forcedShutdown;
-    }
-
-    private void keepAlive() {
-        if (thread == null) {
-            thread = new ShutdownThread();
-            thread.start();
-        }
-    }
-
-    private void shutdown() {
-        if (thread != null) {
-            thread.shutdown();
-            thread = null;
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/awt/wtk/Synchronizer.java b/awt/org/apache/harmony/awt/wtk/Synchronizer.java
deleted file mode 100644
index 3eeaa0b..0000000
--- a/awt/org/apache/harmony/awt/wtk/Synchronizer.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Mikhail Danilov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.util.Hashtable;
-import java.util.LinkedList;
-
-import org.apache.harmony.awt.internal.nls.Messages;
-
-/**
- * Class synchronizer is to protect AWT state integrity in multithreading environment.
- * It is supposed to have a child class per native platform.
- * The only instance is created on the first use of one of the core AWT classes.
- * Registers WTK on the dispatch thread startup.
- * It is just a special kind of mutex.
- *
- */
-
-public class Synchronizer {
-    //TODO: think about java.util.concurrent use for faster blocking/awaking operations
-    //TODO: think about all synchronized methods. Is there need to synchronize everything?
-
-    /**
-     * This field holds the counter of lock operation.
-     * To free synchronizer unlock method must be called $acquestCounter times.
-     * Equals to 0 when synchronizer is free.
-     */
-    protected int acquestCounter;
-
-    /**
-     * This field holds the owner of synchronizer.
-     * Owner of synchronizer is a last thread that successfully locked synchronizer and
-     * still havn't freed it. Equals to null when synchronizer is free.
-     */
-    protected Thread owner;
-
-    /**
-     * This field holds the wait queue.
-     * Wait queue is a queue where thread wait for synchronizer access.
-     * Empty when synchronizer is free.
-     */
-    protected final LinkedList<Thread> waitQueue = new LinkedList<Thread>();
-
-    /**
-     * The event dispatch thread
-     */
-    protected Thread dispatchThread;
-
-    private final Hashtable<Thread, Integer> storedStates = new Hashtable<Thread, Integer>();
-
-    /**
-     * Acquire the lock for this synchronizer. Nested lock is supported.
-     * If the mutex is already locked by another thread, the current thread will be put
-     * into wait queue until the lock becomes available.
-     * All user threads are served in FIFO order. Dispatch thread has higher priority.
-     * Supposed to be used in Toolkit.lockAWT() only.
-     */
-    public void lock() {
-        synchronized (this) {
-            Thread curThread = Thread.currentThread();
-
-            if (acquestCounter == 0) {
-                acquestCounter = 1;
-                owner = curThread;
-            } else {
-                if (owner == curThread) {
-                    acquestCounter++;
-                } else {
-                    if (curThread == dispatchThread) {
-                        waitQueue.addFirst(curThread);
-                    } else {
-                        waitQueue.addLast(curThread);
-                    }
-                    try {
-                        wait();
-                    } catch (InterruptedException e) {
-                        if (owner != curThread) {
-                            waitQueue.remove(curThread);
-                            // awt.1F=Waiting for resource access thread interrupted not from unlock method.
-                            throw new RuntimeException(Messages
-                                    .getString("awt.1F")); //$NON-NLS-1$
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Release the lock for this synchronizer.
-     * If wait queue is not empty the first waiting thread acquires the lock.
-     * Supposed to be used in Toolkit.unlockAWT() only.
-     */
-    public void unlock() {
-        synchronized (this) {
-            if (acquestCounter == 0) {
-                // awt.20=Can't unlock not locked resource.
-                throw new RuntimeException(Messages.getString("awt.20")); //$NON-NLS-1$
-            }
-            if (owner != Thread.currentThread()) {
-                // awt.21=Not owner can't unlock resource.
-                throw new RuntimeException(Messages.getString("awt.21")); //$NON-NLS-1$
-            }
-
-            acquestCounter--;
-            if (acquestCounter == 0) {
-                if (waitQueue.size() > 0) {
-                    acquestCounter = 1;
-                    owner = waitQueue.removeFirst();
-                    owner.interrupt();
-                } else {
-                    owner = null;
-                }
-            }
-        }
-    }
-
-    /**
-     * Stores state of this synchronizer and frees it.
-     * Supposed to be used in Toolkit.unsafeInvokeAndWaitUnderAWTLock() only in pair with
-     * lockAndRestoreState().
-     * Do not call it directly.
-     */
-    public void storeStateAndFree() {
-        synchronized (this) {
-            Thread curThread = Thread.currentThread();
-
-            if (owner != curThread) {
-                // awt.22=Not owner can't free resource.
-                throw new RuntimeException(Messages.getString("awt.22")); //$NON-NLS-1$
-            }
-            if (storedStates.containsKey(curThread)) {
-                // awt.23=One thread can't store state several times in a row.
-                throw new RuntimeException(Messages.getString("awt.23")); //$NON-NLS-1$
-            }
-
-            storedStates.put(curThread, new Integer(acquestCounter));
-            acquestCounter = 1;
-            unlock();
-        }
-    }
-
-    /**
-     * Locks this synchronizer and restores it's state.
-     * Supposed to be used in Toolkit.unsafeInvokeAndWaitUnderAWTLock() only in pair with
-     * storeStateAndFree().
-     * Do not call it directly.
-     */
-    public void lockAndRestoreState() {
-        synchronized (this) {
-            Thread curThread = Thread.currentThread();
-
-            if (owner == curThread) {
-                // awt.24=Owner can't overwrite resource state. Lock operations may be lost.
-                throw new RuntimeException(
-                        Messages.getString("awt.24")); //$NON-NLS-1$
-            }
-            if (!storedStates.containsKey(curThread)) {
-                // awt.25=No state stored for current thread.
-                throw new RuntimeException(Messages.getString("awt.25")); //$NON-NLS-1$
-            }
-
-            lock();
-            acquestCounter = storedStates.get(curThread).intValue();
-            storedStates.remove(curThread);
-        }
-    }
-
-    /**
-     * Sets references to WTK and event dispatch thread.
-     * Called on toolkit startup.
-     *
-     * @param wtk - reference to WTK instance
-     * @param dispatchThread - reference to event dispatch thread
-     */
-    public void setEnvironment(WTK wtk, Thread dispatchThread) {
-        synchronized (this) {
-            this.dispatchThread = dispatchThread;
-        }
-    }
-
-}
diff --git a/awt/org/apache/harmony/awt/wtk/SystemProperties.java b/awt/org/apache/harmony/awt/wtk/SystemProperties.java
deleted file mode 100644
index 6b59f0e..0000000
--- a/awt/org/apache/harmony/awt/wtk/SystemProperties.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.Font;
-import java.awt.font.TextAttribute;
-import java.awt.im.InputMethodHighlight;
-import java.util.Map;
-
-/**
- * NativeProperties
- */
-
-public interface SystemProperties {
-
-    /**
-     * Get current value of a system color
-     * @param index - one of java.awt.SystemColor constants
-     * @return ARGB value of requested system color
-     */
-    int getSystemColorARGB(int index);
-
-    /**
-     * Get default font for GUI elements such as menus and buttons
-     * @return the font object
-     */
-    Font getDefaultFont();
-    
-    /**
-     * Fill the given Map with system properties
-     */
-    void init(Map<String, ?> desktopProperties);
-
-    /**
-     * Fills the given map with system-dependent visual text
-     * attributes for the abstract description 
-     * of the given input method highlight
-     * @see java.awt.Toolkit.mapInputMethodHighlight()
-     */
-    void mapInputMethodHighlight(InputMethodHighlight highlight, Map<TextAttribute, ?> map);
-}
diff --git a/awt/org/apache/harmony/awt/wtk/WTK.java b/awt/org/apache/harmony/awt/wtk/WTK.java
deleted file mode 100644
index 4162fbd..0000000
--- a/awt/org/apache/harmony/awt/wtk/WTK.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Pavel Dolgov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.GraphicsDevice;
-
-
-public abstract class WTK {
-
-    public abstract GraphicsFactory getGraphicsFactory();
-    public abstract NativeEventQueue getNativeEventQueue();
-    public abstract WindowFactory getWindowFactory();
-
-    /**
-     * Returns platform specific implementation of the interface
-     * org.apache.harmony.awt.wtk.CursorFactory.
-     * @return implementation of CursorFactory
-     */
-    public abstract CursorFactory getCursorFactory();
-
-    /**
-     * Returns platform specific implementation of the interface
-     * org.apache.harmony.awt.wtk.NativeMouseInfo.
-     * @return implementation of NativeMouseInfo
-     */
-    public abstract NativeMouseInfo getNativeMouseInfo();
-
-    public abstract SystemProperties getSystemProperties();
-
-    /**
-     * Returns platform specific implementation of the interface
-     * org.apache.harmony.awt.wtk.NativeRobot.
-     * @return implementation of NativeRobot
-     */
-    public abstract NativeRobot getNativeRobot(GraphicsDevice screen);
-    
-    /**
-     * Returns platform specific implementation of the abstract
-     * class org.apache.harmony.awt.wtk.NativeIM.
-     * @return implementation of NativeIM
-     */
-    public abstract NativeIM getNativeIM();
-}
diff --git a/awt/org/apache/harmony/awt/wtk/WindowFactory.java b/awt/org/apache/harmony/awt/wtk/WindowFactory.java
deleted file mode 100644
index 23604da..0000000
--- a/awt/org/apache/harmony/awt/wtk/WindowFactory.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Mikhail Danilov
- * @version $Revision$
- */
-package org.apache.harmony.awt.wtk;
-
-import java.awt.Dimension;
-import java.awt.Point;
-
-/**
- * Provides factory for NativeWindow
- */
-public interface WindowFactory {
-    /**
-     * Creates and returns NativeWindow with desired
-     * creation params
-     *
-     * @param p - initial window properties
-     * @return created window
-     */
-    NativeWindow createWindow(CreationParams p);
-    /**
-     * Create NativeWindow instance connected to existing native resource
-     * @param nativeWindowId - id of existing window
-     * @return created NativeWindow instance
-     */
-    NativeWindow attachWindow(long nativeWindowId);
-    /**
-     * Returns NativeWindow instance if created by this instance of
-     * WindowFactory, otherwise null
-     *
-     * @param id - HWND on Windows xwindow on X
-     * @return NativeWindow or null if unknown
-     */
-    NativeWindow getWindowById(long id);
-    /**
-     * Returns NativeWindow instance of the top-level window
-     * that contains a specified point and was
-     * created by this instance of WindowFactory
-     * @param p - Point to check
-     * @return NativeWindow or null if the point is
-     * not within a window created by this WindowFactory
-     */
-    NativeWindow getWindowFromPoint(Point p);
-
-    /**
-     * Returns whether native system supports the state for windows.
-     * This method tells whether the UI concept of, say, maximization or iconification is supported.
-     * It will always return false for "compound" states like Frame.ICONIFIED|Frame.MAXIMIZED_VERT.
-     * In other words, the rule of thumb is that only queries with a single frame state
-     * constant as an argument are meaningful.
-     *
-     * @param state - one of named frame state constants.
-     * @return true is this frame state is supported by this Toolkit implementation, false otherwise.
-     */
-    boolean isWindowStateSupported(int state);
-
-    /**
-     * @see org.apache.harmony.awt.ComponentInternals
-     */
-    void setCaretPosition(int x, int y);
-
-    /**
-     * Request size of arbitrary native window
-     * @param id - window ID
-     * @return window size
-     */
-    Dimension getWindowSizeById(long id);
-}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/beans/internal/nls/Messages.java b/awt/org/apache/harmony/beans/internal/nls/Messages.java
deleted file mode 100644
index 51e8168..0000000
--- a/awt/org/apache/harmony/beans/internal/nls/Messages.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-package org.apache.harmony.beans.internal.nls;
-
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-deleted
-/*
- * For Android, this module is a separate library and not part of the
- * boot classpath, so its resources won't be found on the boot classpath
- * as is assumed by MsgHelp.getString(). We instead use a local MsgHelp
- * which bottoms out in a call to the useful part of its lower-level
- * namesake.
- */
-//import org.apache.harmony.kernel.vm.VM;
-//import org.apache.harmony.luni.util.MsgHelp;
-// END android-deleted
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.beans.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-deleted
-    // private static final String sResource =
-    //     "org.apache.harmony.beans.internal.nls.messages"; //$NON-NLS-1$
-    // END android-deleted
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/awt/org/apache/harmony/beans/internal/nls/MsgHelp.java b/awt/org/apache/harmony/beans/internal/nls/MsgHelp.java
deleted file mode 100644
index 68faabfa..0000000
--- a/awt/org/apache/harmony/beans/internal/nls/MsgHelp.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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 implementation is based on the class of the same name in
- * org.apache.harmony.luni.util.
- */
-
-package org.apache.harmony.beans.internal.nls;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.logging.Logger;
-import java.util.Locale;
-import java.util.PropertyResourceBundle;
-import java.util.ResourceBundle;
-import java.util.MissingResourceException;
-
-/**
- * This class contains helper methods for loading resource bundles and
- * formatting external message strings.
- */
-public final class MsgHelp {
-    /** name of the resource for this class */
-    private static final String RESOURCE_NAME =
-        "/org/apache/harmony/beans/internal/nls/messages.properties";
-
-    /** the resource bundle for this class */
-    private static final ResourceBundle THE_BUNDLE;
-
-    static {
-        ResourceBundle rb = null;
-
-        try {
-            InputStream in = MsgHelp.class.getResourceAsStream(
-                    RESOURCE_NAME);
-            rb = new PropertyResourceBundle(in);
-        } catch (IOException ex) {
-            Logger.global.warning("Couldn't read resource bundle: " +
-                    ex);
-        } catch (RuntimeException ex) {
-            // Shouldn't happen, but deal at least somewhat gracefully.
-            Logger.global.warning("Couldn't find resource bundle: " +
-                    ex);
-        }
-
-        THE_BUNDLE = rb;
-    }
-    
-    public static String getString(String msg) {
-        if (THE_BUNDLE == null) {
-            return msg;
-        }
-        try {
-            return THE_BUNDLE.getString(msg);
-        } catch (MissingResourceException e) {
-            return "Missing message: " + msg;
-        }
-    }
-    
-    static public String getString(String msg, Object[] args) {
-        String format = msg;
-        if (THE_BUNDLE != null) {
-            try {
-                format = THE_BUNDLE.getString(msg);
-            } catch (MissingResourceException e) {
-            }
-        }
-
-        return org.apache.harmony.luni.util.MsgHelp.format(format, args);
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java b/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java
deleted file mode 100644
index 498e1bb..0000000
--- a/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-package org.apache.harmony.x.imageio.internal.nls;
-
-import org.apache.harmony.luni.util.MsgHelp;
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.x.imageio.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    private static final String sResource =
-        "org.apache.harmony.x.imageio.internal.nls.messages"; //$NON-NLS-1$
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        return MsgHelp.getString(sResource, msg);
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        return MsgHelp.getString(sResource, msg, args);
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties b/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties
deleted file mode 100644
index 8a49dd8..0000000
--- a/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-# 
-
-# messages for EN locale
-imageio.1=Wrong bitDepth-numBands composition
\ No newline at end of file
diff --git a/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java b/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java
deleted file mode 100644
index caeefdd5..0000000
--- a/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-
-package org.apache.harmony.x.imageio.metadata;
-
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import javax.imageio.metadata.IIOMetadataFormat;
-import javax.imageio.metadata.IIOMetadataFormatImpl;
-
-public class IIOMetadataUtils {
-    private IIOMetadataUtils() {} 
-
-    public static IIOMetadataFormat instantiateMetadataFormat(
-            String formatName, boolean standardFormatSupported,
-            String nativeMetadataFormatName, String nativeMetadataFormatClassName,
-            String [] extraMetadataFormatNames, String [] extraMetadataFormatClassNames
-    ) {
-        if (formatName == null) {
-            throw new IllegalArgumentException("formatName == null!");
-        }
-        if (formatName.equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {
-            if (standardFormatSupported) {
-                return IIOMetadataFormatImpl.getStandardFormatInstance();
-            }
-        }
-
-        String className = null;
-
-        if (formatName.equals(nativeMetadataFormatName)) {
-            className = nativeMetadataFormatClassName;
-        } else if (extraMetadataFormatNames != null) {
-            for (int i = 0; i < extraMetadataFormatNames.length; i++) {
-                if (formatName.equals(extraMetadataFormatNames[i])) {
-                    className = extraMetadataFormatClassNames[i];
-                    break;
-                }
-            }
-        }
-
-        if (className == null) {
-            throw new IllegalArgumentException("Unsupported format name");
-        }
-
-        // Get the context class loader and try to use it first
-        ClassLoader contextClassloader = AccessController.doPrivileged(
-                new PrivilegedAction<ClassLoader>() {
-                    public ClassLoader run() {
-                        return Thread.currentThread().getContextClassLoader();
-                    }
-        });
-
-        Class cls;
-
-        try {
-            cls = Class.forName(className, true, contextClassloader);
-        } catch (ClassNotFoundException e) {
-            try {
-                // Use current class loader
-                cls = Class.forName(className);
-            } catch (ClassNotFoundException e1) {
-                throw new IllegalStateException ("Can't obtain format");
-            }
-        }
-
-        try {
-            //???AWT:
-            //Method getInstance = cls.getMethod("getInstance");
-            //return (IIOMetadataFormat) getInstance.invoke(null);
-            return null;
-        } catch (Exception e) {
-            IllegalStateException e1 = new IllegalStateException("Can't obtain format");
-            e1.initCause(e); // Add some details to the message
-            throw e1;
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java
deleted file mode 100644
index 051f906..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem Rafikov
- * @version $Revision: 1.2 $
- */
-package org.apache.harmony.x.imageio.plugins.jpeg;
-
-import javax.imageio.stream.ImageInputStream;
-
-import org.apache.harmony.awt.gl.image.DecodingImageSource;
-
-import java.io.InputStream;
-import java.io.IOException;
-
-/**
- * This allows usage of the java2d jpegdecoder with ImageInputStream in
- * the JPEGImageReader. Temporary, only to make JPEGImageReader#read(..)
- * working.
- *
- */
-public class IISDecodingImageSource extends DecodingImageSource {
-
-    private final InputStream is;
-
-    public IISDecodingImageSource(ImageInputStream iis) {
-        is = new IISToInputStreamWrapper(iis);
-    }
-
-    @Override
-    protected boolean checkConnection() {
-        return true;
-    }
-
-    @Override
-    protected InputStream getInputStream() {
-        return is;
-    }
-
-    static class IISToInputStreamWrapper extends InputStream {
-
-        private ImageInputStream input;
-
-        public IISToInputStreamWrapper(ImageInputStream input) {
-            this.input=input;
-        }
-
-        @Override
-        public int read() throws IOException {
-            return input.read();
-        }
-
-        @Override
-        public int read(byte[] b) throws IOException {
-            return input.read(b);
-        }
-
-        @Override
-        public int read(byte[] b, int off, int len) throws IOException {
-            return input.read(b, off, len);
-        }
-
-        @Override
-        public long skip(long n) throws IOException {
-            return input.skipBytes(n);
-        }
-
-        @Override
-        public boolean markSupported() {
-        	return true;  // This is orig
-        	
-            // ???AWT: FIXME
-        	// This is an error in Harmony. Not all input streams
-        	// have mark support and it is not ok to just return true. 
-        	// There should be an input.markSupported(). However, if 
-        	// this call returns false, nothing works anymore.
-        	
-        	// The backside is that BitmapFactory uses a call to markSupport()
-        	// to find out if it needs to warp the stream in a
-        	// BufferedInputStream to get mark support, and this fails!
-        	
-        	// Currently, the hack is in BitmapFactory, where we always
-        	// wrap the stream in a BufferedInputStream.
-        }
-
-        @Override
-        public void mark(int readlimit) {
-            input.mark();
-        }
-
-        @Override
-        public void reset() throws IOException {
-            input.reset();
-        }
-
-        @Override
-        public void close() throws IOException {
-            input.close();
-        }
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java
deleted file mode 100644
index 067a825..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.2 $
- */
-package org.apache.harmony.x.imageio.plugins.jpeg;
-
-public class JPEGConsts {
-
-    private JPEGConsts() {}
-
-    public static final int SOI = 0xD8;
-
-    //-- IJG (Independed JPEG Group) color spaces
-    public static final int JCS_UNKNOW = 0;
-    public static final int JCS_GRAYSCALE = 1;
-    public static final int JCS_RGB = 2;
-    public static final int JCS_YCbCr = 3;
-    public static final int JCS_CMYK = 4;
-    public static final int JCS_YCC = 5;
-    public static final int JCS_RGBA = 6;
-    public static final int JCS_YCbCrA = 7;
-    public static final int JCS_YCCA = 10;
-    public static final int JCS_YCCK = 11;
-
-    public static int[][] BAND_OFFSETS = {{}, {0}, {0, 1}, {0, 1, 2}, {0, 1, 2, 3}};
-
-    public static final float DEFAULT_JPEG_COMPRESSION_QUALITY = 0.75f;
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java
deleted file mode 100644
index 110ed23..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.4 $
- */
-package org.apache.harmony.x.imageio.plugins.jpeg;
-
-
-import javax.imageio.ImageReader;
-import javax.imageio.ImageReadParam;
-import javax.imageio.ImageTypeSpecifier;
-import javax.imageio.plugins.jpeg.JPEGImageReadParam;
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.metadata.IIOMetadata;
-import javax.imageio.spi.ImageReaderSpi;
-
-import org.apache.harmony.awt.gl.image.DecodingImageSource;
-import org.apache.harmony.awt.gl.image.OffscreenImage;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.awt.image.BufferedImage;
-
-/**
- * This implementation uses org.apache.harmony.awt.gl.image.JpegDecoder to read
- * an image. The only implemented method is read(..);
- *
- * TODO: Implements generic decoder to be used by javad2 and imageio
- *
- * @see org.apache.harmony.awt.gl.image.JpegDecoder
- * @see org.apache.harmony.x.imageio.plugins.jpeg.IISDecodingImageSource
- */
-public class JPEGImageReader extends ImageReader {
-
-    ImageInputStream iis;
-
-    public JPEGImageReader(ImageReaderSpi imageReaderSpi) {
-        super(imageReaderSpi);
-    }
-
-    @Override
-    public int getHeight(int i) throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    @Override
-    public int getWidth(int i) throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    @Override
-    public int getNumImages(boolean b) throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    @Override
-    public Iterator<ImageTypeSpecifier> getImageTypes(int i) throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    @Override
-    public IIOMetadata getStreamMetadata() throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    @Override
-    public IIOMetadata getImageMetadata(int i) throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    @Override
-    public BufferedImage read(int i, ImageReadParam imageReadParam) throws IOException {
-        if (iis == null) {
-            throw new IllegalArgumentException("input stream == null");
-        }
-
-        DecodingImageSource source = new IISDecodingImageSource(iis);
-        OffscreenImage image = new OffscreenImage(source);
-        source.addConsumer(image);
-        source.load();
-        // The interrupted flag should be cleared because ImageDecoder interrupts
-        // current thread while decoding. The same technique is used in
-        // ImageLoader#run(). Another solution can be to create
-        // a separate decoding thread. However, decoder keeps its own pool
-        // of threads so creating a new thread will be just a waste of resources.
-        Thread.interrupted();
-        return image.getBufferedImage();
-    }
-
-    @Override
-    public BufferedImage read(int i) throws IOException {
-        return read(i, null);
-    }
-
-    @Override
-    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
-        super.setInput(input, seekForwardOnly, ignoreMetadata);
-        iis = (ImageInputStream) input;
-    }
-
-    @Override
-    public ImageReadParam getDefaultReadParam() {
-        return new JPEGImageReadParam();
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java
deleted file mode 100644
index c719ce7..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-package org.apache.harmony.x.imageio.plugins.jpeg;
-
-import java.io.IOException;
-import java.util.Locale;
-import javax.imageio.ImageReader;
-import javax.imageio.spi.ImageReaderSpi;
-import javax.imageio.spi.ServiceRegistry;
-import javax.imageio.stream.ImageInputStream;
-
-public class JPEGImageReaderSpi extends ImageReaderSpi {
-
-    public JPEGImageReaderSpi() {
-        super(JPEGSpiConsts.vendorName, JPEGSpiConsts.version,
-                JPEGSpiConsts.names, JPEGSpiConsts.suffixes,
-                JPEGSpiConsts.MIMETypes, JPEGSpiConsts.readerClassName,
-                STANDARD_INPUT_TYPE, JPEGSpiConsts.writerSpiNames,
-                JPEGSpiConsts.supportsStandardStreamMetadataFormat,
-                JPEGSpiConsts.nativeStreamMetadataFormatName,
-                JPEGSpiConsts.nativeStreamMetadataFormatClassName,
-                JPEGSpiConsts.extraStreamMetadataFormatNames,
-                JPEGSpiConsts.extraStreamMetadataFormatClassNames,
-                JPEGSpiConsts.supportsStandardImageMetadataFormat,
-                JPEGSpiConsts.nativeImageMetadataFormatName,
-                JPEGSpiConsts.nativeImageMetadataFormatClassName,
-                JPEGSpiConsts.extraImageMetadataFormatNames,
-                JPEGSpiConsts.extraImageMetadataFormatClassNames);
-    }
-
-
-    @Override
-    public boolean canDecodeInput(Object source) throws IOException {
-        ImageInputStream markable = (ImageInputStream) source;
-        try {
-            markable.mark();
-
-            byte[] signature = new byte[3];
-            markable.seek(0);
-            markable.read(signature, 0, 3);
-            markable.reset();
-
-            if ((signature[0] & 0xFF) == 0xFF &&
-                    (signature[1] & 0xFF) == JPEGConsts.SOI &&
-                    (signature[2] & 0xFF) == 0xFF) { // JPEG
-                return true;
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return false;
-    }
-
-    @Override
-    public ImageReader createReaderInstance(Object extension) throws IOException {
-        return new JPEGImageReader(this);
-    }
-
-    @Override
-    public String getDescription(Locale locale) {
-        return "DRL JPEG decoder";
-    }
-
-    @Override
-    public void onRegistration(ServiceRegistry registry, Class<?> category) {
-        // super.onRegistration(registry, category);
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java
deleted file mode 100644
index ae3e876..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-package org.apache.harmony.x.imageio.plugins.jpeg;
-
-import com.android.internal.awt.ImageOutputStreamWrapper;
-
-import javax.imageio.ImageWriter;
-import javax.imageio.IIOImage;
-import javax.imageio.ImageTypeSpecifier;
-import javax.imageio.ImageWriteParam;
-import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
-import javax.imageio.stream.ImageOutputStream;
-import javax.imageio.spi.ImageWriterSpi;
-import javax.imageio.metadata.IIOMetadata;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap.CompressFormat;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.awt.image.*;
-import java.awt.*;
-import java.awt.color.ColorSpace;
-
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-public class JPEGImageWriter extends ImageWriter {
-
-    // /* ???AWT: Debugging
-    private static final boolean DEBUG = false;
-    private static Bitmap bm;
-    public static Bitmap getBitmap() {
-        return bm;
-    }
-    private static BufferedImage bufImg;
-    public static BufferedImage getBufImage() {
-        return bufImg;
-    }
-    static private RenderedImage renImg;
-    static public RenderedImage getRenImage() {
-        return renImg;
-    }
-    // */
-    
-    private long cinfo;
-    private RenderedImage image;
-    private Raster sourceRaster;
-    private WritableRaster scanRaster;
-    private int srcXOff = 0;
-    private int srcYOff = 0;
-    private int srcWidth;
-    private int srcHeight;
-
-    //-- y step for image subsampling
-    private int deltaY = 1;
-    //-- x step for image subsampling
-    private int deltaX = 1;
-
-    private ImageOutputStream ios;
-
-    public JPEGImageWriter(ImageWriterSpi imageWriterSpi) {
-        super(imageWriterSpi);
-        //???AWT: cinfo = initCompressionObj();
-        cinfo = System.currentTimeMillis();
-    }
-
-    static {
-        //???AWT
-        /*
-        System.loadLibrary("jpegencoder");
-        initWriterIds(ImageOutputStream.class);
-        */
-    }
-
-    @Override
-    public void write(IIOMetadata iioMetadata, IIOImage iioImage, ImageWriteParam param)
-            throws IOException {
-
-        if (ios == null) {
-            throw new IllegalArgumentException("ios == null");
-        }
-        if (iioImage == null) {
-            throw new IllegalArgumentException("Image equals null");
-        }
-
-        RenderedImage img = null;
-        if (!iioImage.hasRaster()) {
-            img = iioImage.getRenderedImage();
-            if (img instanceof BufferedImage) {
-                sourceRaster = ((BufferedImage) img).getRaster();
-            } else {
-                sourceRaster = img.getData();
-            }
-        } else {
-            sourceRaster = iioImage.getRaster();
-        }
-        
-        // AWT???: Debugging
-        if (DEBUG) {
-            if( img==null ) {
-                System.out.println("****J: Image is NULL");
-            } else {
-                renImg = img;
-                bufImg = (BufferedImage)img;
-            }
-        }
-
-        int numBands = sourceRaster.getNumBands();
-        int sourceIJGCs = img == null ? JPEGConsts.JCS_UNKNOW : getSourceCSType(img);
-
-        srcWidth = sourceRaster.getWidth();
-        srcHeight = sourceRaster.getHeight();
-
-        int destWidth = srcWidth;
-        int destHeight = srcHeight;
-
-        boolean progressive = false;
-         
-        if (param != null) {
-            Rectangle reg = param.getSourceRegion();
-            if (reg != null) {
-                srcXOff = reg.x;
-                srcYOff = reg.y;
-
-                srcWidth = reg.width + srcXOff > srcWidth
-                        ? srcWidth - srcXOff
-                        : reg.width;
-                srcHeight = reg.height + srcYOff > srcHeight
-                        ? srcHeight - srcYOff
-                        : reg.height;
-            }
-
-            //-- TODO uncomment when JPEGImageWriteParam be implemented
-            //-- Only default progressive mode yet
-            // progressive = param.getProgressiveMode() ==  ImageWriteParam.MODE_DEFAULT;
-
-            //-- def is 1
-            deltaX = param.getSourceXSubsampling();
-            deltaY = param.getSourceYSubsampling();
-
-            //-- def is 0
-            int offsetX = param.getSubsamplingXOffset();
-            int offsetY = param.getSubsamplingYOffset();
-
-            srcXOff += offsetX;
-            srcYOff += offsetY;
-            srcWidth -= offsetX;
-            srcHeight -= offsetY;
-
-            destWidth = (srcWidth + deltaX - 1) / deltaX;
-            destHeight = (srcHeight + deltaY - 1) / deltaY;
-        }
-
-        //-- default DQTs (see JPEGQTable java doc and JPEG spec K1 & K2 tables)
-        //-- at http://www.w3.org/Graphics/JPEG/itu-t81.pdf
-        //-- Only figuring out how to set DQT in IJG library for future metadata
-        //-- support. IJG def tables are the same.
-        //JPEGQTable[] dqt = new JPEGQTable[2];
-//        int[][] dqt = null;
-//        int[][] dqt = new int[2][];
-//        dqt[0] = JPEGQTable.K1Div2Luminance.getTable();
-//        dqt[1] = JPEGQTable.K2Div2Chrominance.getTable();
-        
-        //???AWT: I think we don't need this amymore
-        /*
-        //-- using default color space
-        //-- TODO: Take destination cs from param or use default if there is no cs
-        int destIJGCs = img == null ? JPEGConsts.JCS_UNKNOW : getDestinationCSType(img);
-
-        DataBufferByte dbuffer = new DataBufferByte(numBands * srcWidth);
-
-        scanRaster = Raster.createInterleavedRaster(dbuffer, srcWidth, 1,
-                numBands * srcWidth, numBands, JPEGConsts.BAND_OFFSETS[numBands], null);
-
-        encode(dbuffer.getData(), srcWidth, destWidth, destHeight, deltaX,
-                sourceIJGCs, destIJGCs, numBands, progressive,
-                null, cinfo);
-        */
-        
-        SampleModel model = sourceRaster.getSampleModel();
-        
-        if (model instanceof SinglePixelPackedSampleModel) {
-            DataBufferInt ibuf = (DataBufferInt)sourceRaster.getDataBuffer();
-            int[] pixels = ibuf.getData();
-            
-            // Create a bitmap with the pixel
-            bm = Bitmap.createBitmap(pixels, srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
-            
-            // Use Bitmap.compress() to write the image
-            ImageOutputStreamWrapper iosw = new ImageOutputStreamWrapper(ios);
-            bm.compress(CompressFormat.JPEG, 100, iosw);
-        } else {
-            // ???AWT: Add support for other color models
-            throw new RuntimeException("Color model not supported yet");
-        }
-
-    }
-
-    @Override
-    public void dispose() {
-        super.dispose();
-        if (cinfo != 0) {
-            //???AWT: dispose(cinfo);
-            cinfo = 0;
-            ios = null;
-        }
-    }
-
-
-    public IIOMetadata getDefaultStreamMetadata(ImageWriteParam imageWriteParam) {
-        throw new UnsupportedOperationException("not supported yet");
-    }
-
-    public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageTypeSpecifier, ImageWriteParam imageWriteParam) {
-        throw new UnsupportedOperationException("not supported yet");
-    }
-
-    @Override
-    public IIOMetadata convertStreamMetadata(IIOMetadata iioMetadata, ImageWriteParam imageWriteParam) {
-        throw new UnsupportedOperationException("not supported yet");
-    }
-
-    @Override
-    public IIOMetadata convertImageMetadata(IIOMetadata iioMetadata, ImageTypeSpecifier imageTypeSpecifier, ImageWriteParam imageWriteParam) {
-        throw new UnsupportedOperationException("not supported yet");
-    }
-
-    @Override
-    public void setOutput(Object output) {
-        super.setOutput(output);
-        ios = (ImageOutputStream) output;
-        //???AWT: setIOS(ios, cinfo);
-        sourceRaster = null;
-        scanRaster = null;
-        srcXOff = 0;
-        srcYOff = 0;
-        srcWidth = 0;
-        srcHeight = 0;
-        deltaY = 1;
-    }
-
-    /**
-     * Frees resources
-     * @param structPointer
-     */
-    //???AWT: private native void dispose(long structPointer);
-
-    /**
-     * Inits methods Ids for native to java callbacks
-     * @param iosClass
-     */
-    //???AWT: private native static void initWriterIds(Class<ImageOutputStream> iosClass);
-
-    /**
-     * Inits compression objects
-     * @return pointer to the native structure
-     */
-    //???AWT: private native long initCompressionObj();
-
-    /**
-     * Sets image output stream in IJG layer
-     * @param stream
-     */
-    //???AWT: private native void setIOS(ImageOutputStream stream, long structPointer);
-
-    /**
-     * Runs encoding process.
-     *
-     * @param data image data buffer to encode
-     * @param srcWidth - source width
-     * @param width - destination width
-     * @param height destination height
-     * @param deltaX - x subsampling step
-     * @param inColorSpace - original color space
-     * @param outColorSpace - destination color space
-     * @param numBands - number of bands
-     * @param cinfo - native handler
-     * @return
-     */
-    //???AWT:
-    /*
-    private native boolean encode(byte[] data, int srcWidth,
-                                  int width, int height, int deltaX,
-                                  int inColorSpace, int outColorSpace,
-                                  int numBands, boolean progressive,
-                                  int[][] dqt,
-                                  long cinfo);
-    */
-
-    /**
-     * Callback for getting a next scanline
-     * @param scanline scan line number
-     */
-    @SuppressWarnings("unused")
-    private void getScanLine(int scanline) {
-        //-- TODO: processImageProgress in ImageWriter
-        Raster child = sourceRaster.createChild(srcXOff,
-                srcYOff + scanline * deltaY, srcWidth, 1, 0, 0, null);
-
-        scanRaster.setRect(child);
-    }
-
-    /**
-     * Maps color space types to IJG color spaces
-     * @param image
-     * @return
-     */
-    private int getSourceCSType(RenderedImage image) {
-        int type = JPEGConsts.JCS_UNKNOW;
-        ColorModel cm = image.getColorModel();
-
-        if (null == cm) {
-            return type;
-        }
-
-        if (cm instanceof IndexColorModel) {
-            throw new UnsupportedOperationException("IndexColorModel is not supported yet");
-        }
-
-        boolean hasAlpha = cm.hasAlpha();
-        ColorSpace cs = cm.getColorSpace();
-        switch(cs.getType()) {
-            case ColorSpace.TYPE_GRAY:
-                type = JPEGConsts.JCS_GRAYSCALE;
-                break;
-           case ColorSpace.TYPE_RGB:
-                type = hasAlpha ? JPEGConsts.JCS_RGBA : JPEGConsts.JCS_RGB;
-                break;
-           case ColorSpace.TYPE_YCbCr:
-                type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
-                break;
-           case ColorSpace.TYPE_3CLR:
-                 type = hasAlpha ? JPEGConsts.JCS_YCCA : JPEGConsts.JCS_YCC;
-                 break;
-           case ColorSpace.TYPE_CMYK:
-                  type = JPEGConsts.JCS_CMYK;
-                  break;
-        }
-        return type;
-    }
-
-    /**
-     * Returns destination color space.
-     * (YCbCr[A] for RGB)
-     *
-     * @param image
-     * @return
-     */
-    private int getDestinationCSType(RenderedImage image) {
-        int type = JPEGConsts.JCS_UNKNOW;
-        ColorModel cm = image.getColorModel();
-        if (null != cm) {
-            boolean hasAlpha = cm.hasAlpha();
-            ColorSpace cs = cm.getColorSpace();
-
-            switch(cs.getType()) {
-                case ColorSpace.TYPE_GRAY:
-                    type = JPEGConsts.JCS_GRAYSCALE;
-                    break;
-               case ColorSpace.TYPE_RGB:
-                    type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
-                    break;
-               case ColorSpace.TYPE_YCbCr:
-                    type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
-                    break;
-               case ColorSpace.TYPE_3CLR:
-                     type = hasAlpha ? JPEGConsts.JCS_YCCA : JPEGConsts.JCS_YCC;
-                     break;
-               case ColorSpace.TYPE_CMYK:
-                      type = JPEGConsts.JCS_CMYK;
-                      break;
-            }
-        }
-        return type;
-    }
-
-    public ImageWriteParam getDefaultWriteParam() {
-        return new JPEGImageWriteParam(getLocale());
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java
deleted file mode 100644
index b7990e0..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
-package org.apache.harmony.x.imageio.plugins.jpeg;
-
-import javax.imageio.spi.ImageWriterSpi;
-import javax.imageio.ImageWriter;
-import javax.imageio.ImageTypeSpecifier;
-import java.io.IOException;
-import java.util.Locale;
-
-public class JPEGImageWriterSpi extends ImageWriterSpi {
-
-    public JPEGImageWriterSpi() {
-        super(JPEGSpiConsts.vendorName, JPEGSpiConsts.version,
-                JPEGSpiConsts.names, JPEGSpiConsts.suffixes, JPEGSpiConsts.MIMETypes,
-                JPEGSpiConsts.writerClassName, STANDARD_OUTPUT_TYPE,
-                JPEGSpiConsts.readerSpiNames, JPEGSpiConsts.supportsStandardStreamMetadataFormat /*TODO: support st. metadata format*/,
-                JPEGSpiConsts.nativeStreamMetadataFormatName, JPEGSpiConsts.nativeStreamMetadataFormatClassName,
-                JPEGSpiConsts.extraStreamMetadataFormatNames, JPEGSpiConsts.extraStreamMetadataFormatClassNames,
-                JPEGSpiConsts.supportsStandardImageMetadataFormat, JPEGSpiConsts.nativeImageMetadataFormatName, JPEGSpiConsts.nativeImageMetadataFormatClassName,
-                JPEGSpiConsts.extraImageMetadataFormatNames, JPEGSpiConsts.extraImageMetadataFormatClassNames);
-    }
-
-    @Override
-    public boolean canEncodeImage(ImageTypeSpecifier imageTypeSpecifier) {
-        return true;
-    }
-
-    @Override
-    public ImageWriter createWriterInstance(Object o) throws IOException {
-        return new JPEGImageWriter(this);
-    }
-
-    @Override
-    public String getDescription(Locale locale) {
-        return "DRL JPEG Encoder";
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java
deleted file mode 100644
index c3b4a50..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.2 $
- */
-package org.apache.harmony.x.imageio.plugins.jpeg;
-
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.2 $
- */
-public class JPEGSpiConsts {
-    private JPEGSpiConsts() {}
-
-    public static final String vendorName = "Intel Corporation";
-    public static final String version = "0.1 beta";
-
-    static final String readerClassName = "org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReader";
-    static final String writerClassName = "org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriter";
-
-    static final String[] names = {"jpeg", "jpg", "JPEG", "JPG"};
-    static final String[] suffixes = {"jpeg", "jpg"};
-    static final String[] MIMETypes = {"image/jpeg"};
-
-    static final String[] writerSpiNames = {"org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriterSpi"};
-    static final String[] readerSpiNames = {"org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReaderSpi"};
-
-    //-- TODO fill this stuff with correct data
-    static final boolean supportsStandardStreamMetadataFormat = false;
-    static final String nativeStreamMetadataFormatName = null;
-    static final String nativeStreamMetadataFormatClassName = null;
-    static final String[] extraStreamMetadataFormatNames = null;
-    static final String[] extraStreamMetadataFormatClassNames = null;
-    static final boolean supportsStandardImageMetadataFormat = false;
-    static final String nativeImageMetadataFormatName =
-            "org.apache.harmony.x.imageio.plugins.jpeg.MyFormatMetadata_1.0";
-    static final String nativeImageMetadataFormatClassName =
-            "org.apache.harmony.x.imageio.plugins.jpeg.MyFormatMetadata";
-    static final String[] extraImageMetadataFormatNames = null;
-    static final String[] extraImageMetadataFormatClassNames = null;
-
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java
deleted file mode 100644
index 480041c..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-
-package org.apache.harmony.x.imageio.plugins.png;
-
-import org.apache.harmony.awt.gl.image.DecodingImageSource;
-import org.apache.harmony.awt.gl.image.OffscreenImage;
-import org.apache.harmony.x.imageio.plugins.jpeg.IISDecodingImageSource;
-
-import javax.imageio.ImageReader;
-import javax.imageio.ImageTypeSpecifier;
-import javax.imageio.ImageReadParam;
-import javax.imageio.plugins.jpeg.JPEGImageReadParam;
-import javax.imageio.spi.ImageReaderSpi;
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.metadata.IIOMetadata;
-import java.io.IOException;
-import java.util.Iterator;
-import java.awt.image.BufferedImage;
-
-public class PNGImageReader  extends ImageReader {
-    ImageInputStream iis;
-
-    public PNGImageReader(ImageReaderSpi imageReaderSpi) {
-        super(imageReaderSpi);
-    }
-
-    public int getNumImages(boolean allowSearch) throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    public int getWidth(int imageIndex) throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    public int getHeight(int imageIndex) throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    @Override
-    public IIOMetadata getStreamMetadata() throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    @Override
-    public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
-        //-- TODO imlement
-        throw new UnsupportedOperationException("not implemented yet");
-    }
-
-    @Override
-    public BufferedImage read(int i, ImageReadParam imageReadParam) throws IOException {
-        if (iis == null) {
-            throw new IllegalArgumentException("input stream == null");
-        }
-
-        DecodingImageSource source = new IISDecodingImageSource(iis);
-        OffscreenImage image = new OffscreenImage(source);
-        source.addConsumer(image);
-        source.load();
-        // The interrupted flag should be cleared because ImageDecoder interrupts
-        // current thread while decoding (due its architecture).
-        Thread.interrupted();
-        return image.getBufferedImage();
-    }
-
-    @Override
-    public BufferedImage read(int i) throws IOException {
-        return read(i, null);
-    }
-
-    @Override
-    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
-        super.setInput(input, seekForwardOnly, ignoreMetadata);
-        iis = (ImageInputStream) input;
-    }
-
-    @Override
-    public ImageReadParam getDefaultReadParam() {
-        return new ImageReadParam();
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java
deleted file mode 100644
index 50f8b10..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-
-package org.apache.harmony.x.imageio.plugins.png;
-
-import org.apache.harmony.x.imageio.plugins.jpeg.JPEGSpiConsts;
-
-import javax.imageio.spi.ImageReaderSpi;
-import javax.imageio.spi.ServiceRegistry;
-import javax.imageio.ImageReader;
-import javax.imageio.stream.ImageInputStream;
-import java.io.IOException;
-import java.util.Locale;
-
-public class PNGImageReaderSpi extends ImageReaderSpi {
-    static final String PNG_NAMES[] = new String[] {"png", "PNG"};
-    static final String PNG_SUFFIXES[] = new String[] {"png"};
-    static final String PNG_MIME_TYPES[] = new String[] {"image/png"};
-    static final String PNG_READER_CLASS_NAME = "org.apache.harmony.x.imageio.plugins.png.PNGImageReader";
-    static final String PNG_READER_SPI_NAMES[] = {"org.apache.harmony.x.imageio.plugins.png.PNGImageReaderSpi"};
-
-    public PNGImageReaderSpi() {
-        super(
-                JPEGSpiConsts.vendorName, JPEGSpiConsts.version,
-                PNG_NAMES, PNG_SUFFIXES,
-                PNG_MIME_TYPES, PNG_READER_CLASS_NAME,
-                STANDARD_INPUT_TYPE, null,
-                false, null,
-                null, null,
-                null, false, 
-                null, null,
-                null, null
-        );
-    }
-
-    @Override
-    public boolean canDecodeInput(Object source) throws IOException {
-        ImageInputStream markable = (ImageInputStream) source;
-        markable.mark();
-
-        byte[] signature = new byte[8];
-        markable.seek(0);
-
-        int nBytes = markable.read(signature, 0, 8);
-        if(nBytes != 8) markable.read(signature, nBytes, 8-nBytes);
-        markable.reset();
-
-        // PNG signature: 137 80 78 71 13 10 26 10
-        return  (signature[0] & 0xFF) == 137 &&
-                (signature[1] & 0xFF) == 80 &&
-                (signature[2] & 0xFF) == 78 &&
-                (signature[3] & 0xFF) == 71 &&
-                (signature[4] & 0xFF) == 13 &&
-                (signature[5] & 0xFF) == 10 &&
-                (signature[6] & 0xFF) == 26 &&
-                (signature[7] & 0xFF) == 10;
-    }
-
-    @Override
-    public ImageReader createReaderInstance(Object extension) throws IOException {
-        return new PNGImageReader(this);
-    }
-
-    @Override
-    public String getDescription(Locale locale) {
-        return "DRL PNG decoder";
-    }
-
-    @Override
-    public void onRegistration(ServiceRegistry registry, Class<?> category) {
-        super.onRegistration(registry, category);
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java
deleted file mode 100644
index e2a8d7d..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Viskov Nikolay
- * @version $Revision$
- */
-package org.apache.harmony.x.imageio.plugins.png;
-
-import com.android.internal.awt.ImageOutputStreamWrapper;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBufferByte;
-import java.awt.image.DataBufferInt;
-import java.awt.image.IndexColorModel;
-import java.awt.image.Raster;
-import java.awt.image.RenderedImage;
-import java.awt.image.SampleModel;
-import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.WritableRaster;
-import java.io.IOException;
-
-import javax.imageio.IIOImage;
-import javax.imageio.ImageTypeSpecifier;
-import javax.imageio.ImageWriteParam;
-import javax.imageio.ImageWriter;
-import javax.imageio.metadata.IIOMetadata;
-import javax.imageio.spi.ImageWriterSpi;
-import javax.imageio.stream.ImageOutputStream;
-
-import org.apache.harmony.x.imageio.internal.nls.Messages;
-
-import org.apache.harmony.luni.util.NotImplementedException;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.CompressFormat;
-
-public class PNGImageWriter extends ImageWriter {
-    
-    // /* ???AWT: Debugging
-    private static final boolean DEBUG = false;
-    private static Bitmap bm;
-    public static Bitmap getBitmap() {
-        return bm;
-    }
-    // */
-    
-    private static int[][] BAND_OFFSETS = {
-            {}, {
-                0 }, {
-                    0, 1 }, {
-                    0, 1, 2 }, {
-                    0, 1, 2, 3 } };
-
-    // Each pixel is a grayscale sample.
-    private static final int PNG_COLOR_TYPE_GRAY = 0;
-    // Each pixel is an R,G,B triple.
-    private static final int PNG_COLOR_TYPE_RGB = 2;
-    // Each pixel is a palette index, a PLTE chunk must appear.
-    private static final int PNG_COLOR_TYPE_PLTE = 3;
-    // Each pixel is a grayscale sample, followed by an alpha sample.
-    private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
-    // Each pixel is an R,G,B triple, followed by an alpha sample.
-    private static final int PNG_COLOR_TYPE_RGBA = 6;
-    
-    //???AWT: private static native void initIDs(Class<ImageOutputStream> iosClass);
-
-    static {
-        //???AWT
-        /*
-        System.loadLibrary("pngencoder"); //$NON-NLS-1$
-        initIDs(ImageOutputStream.class);
-        */
-    }
-    
-    /*
-    private native int encode(byte[] input, int bytesInBuffer, int bytePixelSize, Object ios, int imageWidth,
-            int imageHeight, int bitDepth, int colorType, int[] palette, int i, boolean b);
-    */
-    
-    protected PNGImageWriter(ImageWriterSpi iwSpi) {
-        super(iwSpi);
-    }
-
-    @Override
-    public IIOMetadata convertStreamMetadata(IIOMetadata arg0, ImageWriteParam arg1) {
-        throw new NotImplementedException();
-    }
-
-    @Override
-    public IIOMetadata convertImageMetadata(IIOMetadata arg0, ImageTypeSpecifier arg1, ImageWriteParam arg2) {
-        throw new NotImplementedException();
-    }
-
-    @Override
-    public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier arg0, ImageWriteParam arg1) {
-        throw new NotImplementedException();
-    }
-
-    @Override
-    public IIOMetadata getDefaultStreamMetadata(ImageWriteParam arg0) {
-        throw new NotImplementedException();
-    }
-
-    @Override
-    public void write(IIOMetadata streamMetadata, IIOImage iioImage, ImageWriteParam param) throws IOException {
-        if (output == null) {
-            throw new IllegalStateException("Output not been set");
-        }
-        if (iioImage == null) {
-            throw new IllegalArgumentException("Image equals null");
-        }
-        // AWT???: I think this is not needed anymore
-        // if (iioImage.hasRaster() && !canWriteRasters()) {
-        //    throw new UnsupportedOperationException("Can't write raster");
-        //}// ImageOutputStreamImpl
-        
-        Raster sourceRaster;
-        RenderedImage img = null;
-        if (!iioImage.hasRaster()) {
-            img = iioImage.getRenderedImage();
-            if (img instanceof BufferedImage) {
-                sourceRaster = ((BufferedImage) img).getRaster();
-            } else {
-                sourceRaster = img.getData();
-            }
-        } else {
-            sourceRaster = iioImage.getRaster();
-        }
-
-        SampleModel model = sourceRaster.getSampleModel();
-        int srcWidth = sourceRaster.getWidth();
-        int srcHeight = sourceRaster.getHeight();
-        int numBands = model.getNumBands();
-        
-        ColorModel colorModel = img.getColorModel();
-        int pixelSize = colorModel.getPixelSize();
-        int bytePixelSize = pixelSize / 8;
-        int bitDepth = pixelSize / numBands;
-        
-        // byte per band
-        int bpb = bitDepth > 8 ? 2 : 1;
-        
-        boolean isInterlace = true;
-        if (param instanceof PNGImageWriterParam) {
-            isInterlace = ((PNGImageWriterParam) param).getInterlace();
-        }
-        
-        int colorType = PNG_COLOR_TYPE_GRAY;
-        int[] palette = null;
-        
-        if (colorModel instanceof IndexColorModel) {
-            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8) {
-//              Wrong bitDepth-numBands composition
-                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
-            }
-            if (numBands != 1) {
-//              Wrong bitDepth-numBands composition
-                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
-            }
-
-            IndexColorModel icm = (IndexColorModel) colorModel;
-            palette = new int[icm.getMapSize()];
-            icm.getRGBs(palette);
-            colorType = PNG_COLOR_TYPE_PLTE;
-        }
-        else if (numBands == 1) {
-            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16) {
-//              Wrong bitDepth-numBands composition
-                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
-            }
-            colorType = PNG_COLOR_TYPE_GRAY;
-        }
-        else if (numBands == 2) {
-            if (bitDepth != 8 && bitDepth != 16) {
-//              Wrong bitDepth-numBands composition
-                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
-            }
-            colorType = PNG_COLOR_TYPE_GRAY_ALPHA;
-        }
-        else if (numBands == 3) {
-            if (bitDepth != 8 && bitDepth != 16) {
-//              Wrong bitDepth-numBands composition
-                throw new IllegalArgumentException(Messages.getString("imageio.1")); //$NON-NLS-1$
-            }
-            colorType = PNG_COLOR_TYPE_RGB;
-        }
-        else if (numBands == 4) {
-            if (bitDepth != 8 && bitDepth != 16) {
-                //Wrong bitDepth-numBands composition
-                throw new IllegalArgumentException(Messages.getString("imageio.1")); //$NON-NLS-1$
-            }
-            colorType = PNG_COLOR_TYPE_RGBA;
-        }
-        
-        /* ???AWT: I think this is not needed anymore
-        int dbufferLenght = bytePixelSize * imageHeight * imageWidth;
-        DataBufferByte dbuffer = new DataBufferByte(dbufferLenght);
-
-        WritableRaster scanRaster = Raster.createInterleavedRaster(dbuffer, imageWidth, imageHeight, bpb * numBands
-                * imageWidth, bpb * numBands, BAND_OFFSETS[numBands], null);
-
-        scanRaster.setRect(((BufferedImage) image).getRaster()// image.getData()
-                .createChild(0, 0, imageWidth, imageHeight, 0, 0, null));
-        */
-
-        if (DEBUG) {
-            System.out.println("**** raster:" + sourceRaster);        
-            System.out.println("**** model:" + model);
-            System.out.println("**** type:" + colorType);
-        }
-        
-        if (model instanceof SinglePixelPackedSampleModel) {
-            DataBufferInt ibuf = (DataBufferInt)sourceRaster.getDataBuffer();
-            int[] pixels = ibuf.getData();
-            
-            // Create a bitmap with the pixel
-            bm = Bitmap.createBitmap(pixels, srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
-            
-            // Use Bitmap.compress() to write the image
-            ImageOutputStream ios = (ImageOutputStream) getOutput();
-            ImageOutputStreamWrapper iosw = new ImageOutputStreamWrapper(ios);
-            bm.compress(CompressFormat.PNG, 100, iosw);
-        } else {
-            // ???AWT: Add support for other color models
-            throw new RuntimeException("Color model not supported yet");
-        }
-    }
-
-    public ImageWriteParam getDefaultWriteParam() {
-        return new PNGImageWriterParam();
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java
deleted file mode 100644
index bf3a000..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Viskov Nikolay
- * @version $Revision$
- */
-package org.apache.harmony.x.imageio.plugins.png;
-
-import javax.imageio.ImageWriteParam;
-
-public class PNGImageWriterParam extends ImageWriteParam {
-
-    private boolean isInterlace = true;
-
-    public PNGImageWriterParam() {
-        super();
-    }
-
-    public boolean getInterlace() {
-        return isInterlace;
-    }
-
-    public void setInterlace(boolean b) {
-        isInterlace = b;
-    }
-
-}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java
deleted file mode 100644
index 6eed14d..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Viskov Nikolay
- * @version $Revision$
- */
-package org.apache.harmony.x.imageio.plugins.png;
-
-import java.awt.image.ColorModel;
-import java.awt.image.DataBufferByte;
-import java.awt.image.IndexColorModel;
-import java.io.IOException;
-import java.util.Locale;
-
-import javax.imageio.ImageTypeSpecifier;
-import javax.imageio.ImageWriter;
-import javax.imageio.spi.ImageWriterSpi;
-
-public class PNGImageWriterSpi extends ImageWriterSpi {
-
-    public PNGImageWriterSpi() {
-        super("Intel Corporation",// vendorName
-                "1.0",// version
-                new String[] {
-                        "png", "PNG" },// names
-                new String[] {
-                        "png", "PNG" },// suffixes
-                new String[] {
-                    "image/png" },// MIMETypes
-                "org.apache.harmony.x.imageio.plugins.png.PNGImageWriter",// writerClassName
-                STANDARD_OUTPUT_TYPE,// outputTypes
-                new String[] {
-                    "org.apache.harmony.x.imageio.plugins.png.PNGImageWriterSpi" },// readerSpiNames
-                false,// supportsStandardStreamMetadataFormat
-                null,// nativeStreamMetadataFormatName
-                null,// nativeStreamMetadataFormatClassName
-                null,// extraStreamMetadataFormatNames
-                null,// extraStreamMetadataFormatClassNames
-                false,// supportsStandardImageMetadataFormat
-                null,// nativeImageMetadataFormatName
-                null,// nativeImageMetadataFormatClassName
-                null,// extraImageMetadataFormatNames
-                null// extraImageMetadataFormatClassNames
-        );
-    }
-
-    @Override
-    public boolean canEncodeImage(ImageTypeSpecifier type) {
-        boolean canEncode = true;
-
-        int numBands = type.getSampleModel().getNumBands();
-
-        ColorModel colorModel = type.getColorModel();
-
-        int bitDepth = colorModel.getPixelSize() / numBands;
-
-        if (colorModel instanceof IndexColorModel) {
-            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8) {
-                canEncode = false;
-            }
-            if (numBands != 1) {
-                canEncode = false;
-            }
-        }
-        else if (numBands == 1) {
-            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16) {
-                canEncode = false;
-            }
-        }
-        else if (numBands == 2) {
-            if (bitDepth != 8 && bitDepth != 16) {
-                canEncode = false;
-            }
-        }
-        else if (numBands == 3) {
-            if (bitDepth != 8 && bitDepth != 16) {
-                canEncode = false;
-            }
-        }
-        else if (numBands == 4) {
-            if (bitDepth != 8 && bitDepth != 16) {
-                canEncode = false;
-            }
-        }
-
-        return canEncode;
-    }
-
-    @Override
-    public ImageWriter createWriterInstance(Object arg0) throws IOException {
-        return new PNGImageWriter(this);
-    }
-
-    @Override
-    public String getDescription(Locale arg0) {
-        return "DRL PNG encoder";
-    }
-
-}
diff --git a/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java
deleted file mode 100644
index d4fdd76..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.2 $
- */
-package org.apache.harmony.x.imageio.spi;
-
-import javax.imageio.spi.ImageInputStreamSpi;
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.stream.FileImageOutputStream;
-import javax.imageio.stream.FileImageInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.util.Locale;
-
-public class FileIISSpi extends ImageInputStreamSpi {
-    private static final String vendor = "Apache";
-
-    private static final String ver = "0.1";
-
-    public FileIISSpi() {
-        super(vendor, ver, File.class);
-    }
-
-    @Override
-    public ImageInputStream createInputStreamInstance(Object input, boolean useCache,
-            File cacheDir) throws IOException {
-        if (File.class.isInstance(input)) {
-            return new FileImageInputStream((File) input);
-        }
-        throw new IllegalArgumentException("input is not an instance of java.io.File");
-    }
-
-    @Override
-    public String getDescription(Locale locale) {
-        return "File IIS Spi";
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java
deleted file mode 100644
index acda6a1..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.2 $
- */
-package org.apache.harmony.x.imageio.spi;
-
-import javax.imageio.spi.ImageOutputStreamSpi;
-import javax.imageio.stream.ImageOutputStream;
-import javax.imageio.stream.FileImageOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.util.Locale;
-
-public class FileIOSSpi extends ImageOutputStreamSpi {
-    private static final String vendor = "Apache";
-
-    private static final String ver = "0.1";
-
-    public FileIOSSpi() {
-        super(vendor, ver, File.class);
-    }
-
-    @Override
-    public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache,
-            File cacheDir) throws IOException {
-        if (output instanceof File) {
-            return new FileImageOutputStream((File) output);
-        }
-        throw new IllegalArgumentException("output is not instance of File");
-    }
-
-    @Override
-    public String getDescription(Locale locale) {
-        return "File IOS Spi";
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java
deleted file mode 100644
index ed2fef0..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-
-package org.apache.harmony.x.imageio.spi;
-
-import javax.imageio.spi.ImageInputStreamSpi;
-import javax.imageio.stream.*;
-import java.io.OutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-
-public class InputStreamIISSpi extends ImageInputStreamSpi {
-    private static final String vendor = "Apache";
-
-    private static final String ver = "0.1";
-
-    public InputStreamIISSpi() {
-        super(vendor, ver, InputStream.class);
-    }
-
-    @Override
-    public String getDescription(Locale locale) {
-        return "Output Stream IOS Spi";
-    }
-
-    @Override
-    public boolean canUseCacheFile() {
-        return true;
-    }
-
-    @Override
-    public ImageInputStream createInputStreamInstance(Object input, boolean useCache, File cacheDir) throws IOException {
-        if (input instanceof InputStream) {
-            if (useCache) {
-                return new FileCacheImageInputStream((InputStream) input, cacheDir);
-            } else {
-                return new MemoryCacheImageInputStream((InputStream) input);
-            }
-        }
-        throw new IllegalArgumentException("Output is not an instance of InputStream");
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java
deleted file mode 100644
index dd1e88d..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-
-package org.apache.harmony.x.imageio.spi;
-
-import javax.imageio.spi.ImageOutputStreamSpi;
-import javax.imageio.stream.ImageOutputStream;
-import javax.imageio.stream.FileCacheImageOutputStream;
-import javax.imageio.stream.MemoryCacheImageOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Locale;
-
-public class OutputStreamIOSSpi extends ImageOutputStreamSpi {
-    private static final String vendor = "Apache";
-
-    private static final String ver = "0.1";
-
-    public OutputStreamIOSSpi() {
-        super(vendor, ver, OutputStream.class);
-    }
-
-    @Override
-    public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache, File cacheDir) throws IOException {
-        if (output instanceof OutputStream) {
-            if (useCache) {
-                return new FileCacheImageOutputStream((OutputStream) output, cacheDir);
-            } else {
-                return new MemoryCacheImageOutputStream((OutputStream) output);
-            }
-        }
-        throw new IllegalArgumentException("Output is not an instance of OutputStream");
-    }
-
-    @Override
-    public String getDescription(Locale locale) {
-        return "Output Stream IOS Spi";
-    }
-
-    @Override
-    public boolean canUseCacheFile() {
-        return true;
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java
deleted file mode 100644
index f97eb87..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.2 $
- */
-package org.apache.harmony.x.imageio.spi;
-
-import javax.imageio.spi.ImageInputStreamSpi;
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.stream.FileImageInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.Locale;
-
-public class RAFIISSpi extends ImageInputStreamSpi {
-    private static final String vendor = "Apache";
-
-    private static final String ver = "0.1";
-
-    public RAFIISSpi() {
-        super(vendor, ver, RandomAccessFile.class);
-    }
-
-    @Override
-    public ImageInputStream createInputStreamInstance(Object input, boolean useCache,
-            File cacheDir) throws IOException {
-        if (RandomAccessFile.class.isInstance(input)) {
-            return new FileImageInputStream((RandomAccessFile) input);
-        }
-        throw new IllegalArgumentException(
-                "input is not an instance of java.io.RandomAccessFile");
-    }
-
-    @Override
-    public String getDescription(Locale locale) {
-        return "RandomAccessFile IIS Spi";
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java
deleted file mode 100644
index a9d3649..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.2 $
- */
-package org.apache.harmony.x.imageio.spi;
-
-import javax.imageio.spi.ImageOutputStreamSpi;
-import javax.imageio.stream.ImageOutputStream;
-import javax.imageio.stream.FileImageOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.Locale;
-
-public class RAFIOSSpi extends ImageOutputStreamSpi {
-    private static final String vendor = "Apache";
-
-    private static final String ver = "0.1";
-
-    public RAFIOSSpi() {
-        super(vendor, ver, RandomAccessFile.class);
-    }
-
-    @Override
-    public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache,
-            File cacheDir) throws IOException {
-        if (output instanceof RandomAccessFile) {
-            return new FileImageOutputStream((RandomAccessFile) output);
-        }
-        throw new IllegalArgumentException("output is not instance of java.io.RandomAccessFile");
-    }
-
-    @Override
-    public String getDescription(Locale locale) {
-        return "RandomAccessFile IOS Spi";
-    }
-}
diff --git a/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java b/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java
deleted file mode 100644
index 64f7b2a..0000000
--- a/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-
-package org.apache.harmony.x.imageio.stream;
-
-import java.util.ArrayList;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-public final class RandomAccessMemoryCache {
-    private static final int BLOCK_SHIFT = 9;
-    private static final int BLOCK_SIZE = 1 << BLOCK_SHIFT;
-    private static final int BLOCK_MASK = BLOCK_SIZE - 1;
-    
-    private long length;
-
-    private int firstUndisposed = 0;
-
-    private ArrayList<byte[]> blocks = new ArrayList<byte[]>();
-
-    public RandomAccessMemoryCache() {
-    }
-
-    public long length() {
-        return length;
-    }
-
-    public void close() {
-        blocks.clear();
-        length = 0;
-    }
-
-    private void grow(long pos) {
-        int blocksNeeded = (int)(pos >> BLOCK_SHIFT) - blocks.size() + 1;
-        for (int i=0; i < blocksNeeded; i++) {
-            blocks.add(new byte[BLOCK_SIZE]);
-        }
-
-        length = pos + 1;
-    }
-
-    public void putData(int oneByte, long pos) {
-        if (pos >= length) {
-            grow(pos);
-        }
-
-        byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
-        block[(int)(pos & BLOCK_MASK)] = (byte) oneByte;
-    }
-
-    public void putData(byte[] buffer, int offset, int count, long pos) {
-        if (count > buffer.length - offset || count < 0 || offset < 0) {
-            throw new IndexOutOfBoundsException();
-        }
-        if (count == 0){
-            return;
-        }
-
-        long lastPos = pos + count - 1;
-        if (lastPos >= length) {
-            grow(lastPos);
-        }
-
-        while (count > 0) {
-            byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
-            int blockOffset = (int)(pos & BLOCK_MASK);
-            int toCopy = Math.min(BLOCK_SIZE - blockOffset, count);
-            System.arraycopy(buffer, offset, block, blockOffset, toCopy);
-            pos += toCopy;
-            count -= toCopy;
-            offset += toCopy;
-        }
-    }
-
-    public int getData(long pos) {
-        if (pos >= length) {
-            return -1;
-        }
-
-        byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
-        return block[(int)(pos & BLOCK_MASK)] & 0xFF;
-    }
-
-    public int getData(byte[] buffer, int offset, int count, long pos) {
-        if (count > buffer.length - offset || count < 0 || offset < 0) {
-            throw new IndexOutOfBoundsException();
-        }
-        if (count == 0) {
-            return 0;
-        }
-        if (pos >= length) {
-            return -1;
-        }
-
-        if (count + pos > length) {
-            count = (int) (length - pos);
-        }
-
-        byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
-        int nbytes = Math.min(count, BLOCK_SIZE - (int)(pos & BLOCK_MASK));
-        System.arraycopy(block, (int)(pos & BLOCK_MASK), buffer, offset, nbytes);
-
-        return nbytes;
-    }
-    /*
-    public void seek(long pos) throws IOException {
-        if (pos < 0) {
-            throw new IOException("seek position is negative");
-        }
-        this.pos = pos; 
-    }
-
-    public void readFully(byte[] buffer) throws IOException {
-        readFully(buffer, 0, buffer.length);
-    }
-
-    public void readFully(byte[] buffer, int offset, int count) throws IOException {
-        if (0 <= offset && offset <= buffer.length && 0 <= count && count <= buffer.length - offset) {
-            while (count > 0) {
-                int result = read(buffer, offset, count);
-                if (result >= 0) {
-                    offset += result;
-                    count -= result;
-                } else {
-                    throw new EOFException();
-                }
-            }
-        } else {
-            throw new IndexOutOfBoundsException();
-        }
-    }
-
-    public long getFilePointer() {
-        return pos;
-    }
-*/
-
-    public void freeBefore(long pos) {
-        int blockIdx = (int)(pos >> BLOCK_SHIFT);
-        if (blockIdx <= firstUndisposed) { // Nothing to do
-            return;
-        }
-
-        for (int i = firstUndisposed; i < blockIdx; i++) {
-            blocks.set(i, null);
-        }
-
-        firstUndisposed = blockIdx;
-    }
-
-    public int appendData(InputStream is, int count) throws IOException {
-        if (count <= 0) {
-            return 0;
-        }
-
-        long startPos = length;
-        long lastPos = length + count - 1;
-        grow(lastPos); // Changes length
-
-        int blockIdx = (int)(startPos >> BLOCK_SHIFT);
-        int offset = (int) (startPos & BLOCK_MASK);
-
-        int bytesAppended = 0;
-
-        while (count > 0) {
-            byte[] block = blocks.get(blockIdx);
-            int toCopy = Math.min(BLOCK_SIZE - offset, count);
-            count -= toCopy;
-
-            while (toCopy > 0) {
-                int bytesRead = is.read(block, offset, toCopy);
-
-                if (bytesRead < 0) {
-                    length -= (count - bytesAppended);
-                    return bytesAppended;
-                }
-
-                toCopy -= bytesRead;
-                offset += bytesRead;
-            }
-
-            blockIdx++;
-            offset = 0;
-        }
-
-        return count;
-    }
-
-    public void getData(OutputStream os, int count, long pos) throws IOException {
-        if (pos + count > length) {
-            throw new IndexOutOfBoundsException("Argument out of cache");
-        }
-
-        int blockIdx = (int)(pos >> BLOCK_SHIFT);
-        int offset = (int) (pos & BLOCK_MASK);
-        if (blockIdx < firstUndisposed) {
-            throw new IndexOutOfBoundsException("The requested data are already disposed");
-        }
-
-        while (count > 0) {
-            byte[] block = blocks.get(blockIdx);
-            int toWrite = Math.min(BLOCK_SIZE - offset, count);
-            os.write(block, offset, toWrite);
-
-            blockIdx++;
-            offset = 0;
-            count -= toWrite;
-        }
-    }
-}
diff --git a/awt/resources/org/apache/harmony/awt/internal/nls/messages.properties b/awt/resources/org/apache/harmony/awt/internal/nls/messages.properties
deleted file mode 100644
index 9f647e9..0000000
--- a/awt/resources/org/apache/harmony/awt/internal/nls/messages.properties
+++ /dev/null
@@ -1,495 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-# 
-
-# messages for EN locale
-awt.00=FontRenderContext is null
-awt.01='{0}' parameter is null
-awt.02='{0}' parameter has zero length
-awt.03='{0}' iterator parameter is null
-awt.04='{0}' iterator parameter has zero length
-awt.05=Operation cannot be null
-awt.06=Unexpected type of the internal data buffer
-awt.07=Transfer data is not available
-awt.08=xfld parse string error: {0}
-awt.09=min range bound value is greater than max range bound
-awt.0A=Cannot use SinglePixedPackedSampleModel for bpp = {0}
-awt.0B=Wrong color model created for drawable
-awt.0C=Unknown visual class
-awt.0D=Invalid transparency
-awt.0E=Dimensions of the image should be positive
-awt.0F=Cannot open display '{0}'
-awt.10=Only 32-bit format is supported for window state operations.
-awt.11=Invalid key code
-awt.12=XTest is not supported by your X server\!
-awt.13=Cannot allocate color named '{0}'
-awt.14=Transfer data is not available
-awt.15=Can not get monitor info
-awt.16=Can not create DC for device
-awt.17=Unknown Composite type : {0}
-awt.18=Transparency is not supported
-awt.19=Illegal size of volatile image
-awt.1A=Failed to register window class {0} GetLastError returned {1}
-awt.1B=Invalid key code
-awt.1C=Failure to create JavaWindow GetLastError returned {0}
-awt.1D=Cannot get data from OLE clipboard
-awt.1E=Attempt to replace WindowProc handler
-awt.1F=Waiting for resource access thread interrupted not from unlock method
-awt.20=Can't unlock not locked resource
-awt.21=Not owner can't unlock resource
-awt.22=Not owner can't free resource
-awt.23=One thread can't store state several times in a row
-awt.24=Owner can't overwrite resource state. Lock operations may be lost
-awt.25=No state stored for current thread
-awt.26=Shutdown thread was interrupted while starting
-awt.27=Shutdown thread was interrupted while stopping
-awt.28=bad index: {0}
-awt.29=Invalid range
-awt.2A=Position not represented by view
-awt.2B=No word at {0}
-awt.2C=Invalid position: {0}
-awt.2D=Invalid direction
-awt.2E={0} not in range {1},{2}
-awt.2F=No more words
-awt.30=wrong number of elements to copy: {0}, size: {1}
-awt.31=no room to copy: {0}, size: {1}
-awt.32=String: '{0}' does not fit
-awt.33=index is out of range
-awt.34=Initial offset in the destination array is wrong: {0}
-awt.35=Wrong number of elements to copy: {0}
-awt.36=Wrong segment
-awt.37=Unknown  composite type {0}
-awt.38=Property name is not defined
-awt.39=This method is not implemented for image obtained from ImageProducer
-awt.3A=Color Model is null
-awt.3B=Incorrect ImageConsumer completion status
-awt.3C=Unknown PNG color type
-awt.3D=Unknown colorspace
-awt.3E=Clone not supported
-awt.3F=Invalid baseline index
-awt.40=Wrong number of metrics\!
-awt.41=Font returned unsupported type of line metrics. This case is known, but not supported yet.
-awt.42=TextHitInfo out of range
-awt.43=glyphIndex is out of vector's limits
-awt.44=beginGlyphIndex is out of vector's range
-awt.45=numEntries is out of vector's range
-awt.46=length of setPositions array differs from the length of positions array
-awt.47=First argument should be byte or short array
-awt.48=The srcIn raster is incompatible with src ColorModel
-awt.49=The dstIn raster is incompatible with dst ColorModel
-awt.4A=The dstOut raster is incompatible with dst ColorModel
-awt.4B=Iterator out of bounds
-awt.4C=Invalid MultiRectArea in method {0}
-awt.4D=The raster is incompatible with this ColorModel
-awt.4E=Unknown native platform.
-awt.4F=Data is not available
-awt.50=Iterator is read-only
-awt.51=Component expected to be a parent
-awt.52=Time interval can't be <= 0
-awt.53=Handler can't be null
-awt.54=Key event for unfocused component
-awt.55=Double mouse enter event for component
-awt.56=Double mouse exit event for component
-awt.57=Double focus gained event for component
-awt.58=Double focus lost event for component
-awt.59=Application has run out of context thread group
-awt.5A=Default class for PrinterJob is not found
-awt.5B=No access to default class for PrinterJob
-awt.5C=Instantiation exception for PrinterJob
-awt.5D={0} is not supported
-awt.5E=pageIndex is more than book size
-awt.5F=wrong orientation
-awt.60=Width and Height mustn't be equal zero both
-awt.61=Unsupported data type: {0}
-awt.62=Wrong mask : {0}
-awt.63=Coordinates are not in bounds
-awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
-awt.65=null argument
-awt.66=Invalid format
-awt.67=subclass is not derived from AWTKeyStroke
-awt.68=subclass could not be instantiated
-awt.69=columns less than zero.
-awt.6A=rows less than zero.
-awt.6B=Queue stack is empty
-awt.6C=Event queue stack is broken
-awt.6D=Point is null
-awt.6E=Color is null
-awt.6F=Index less than zero
-awt.70=MenuItem is null
-awt.71=Parent is null
-awt.72=Key event for unfocused component
-awt.73=no such item
-awt.74=Input parameters a and b should not be null
-awt.75=rows and cols cannot both be zero
-awt.76=rows and cols cannot be negative
-awt.77=default focus traversal policy cannot be null
-awt.78=invalid focus traversal key identifier
-awt.79=cannot set null focus traversal key
-awt.7A=focus traversal keys cannot map to KEY_TYPED events
-awt.7B=focus traversal keys must be unique for a Component
-awt.7C=this KeyboardFocusManager is not installed in the current thread's context
-awt.7D=Property name is null
-awt.7E=invalid hotSpot
-awt.7F=AddLayoutComponent: attempt to add null component
-awt.80=AddLayoutComponent: constraint object must be GridBagConstraints
-awt.81=AddLayoutComponent: {0}
-awt.82=RemoveLayoutComponent: attempt to remove null component
-awt.83=SetConstraints: attempt to get constraints of null component
-awt.84=SetConstraints: attempt to set null constraints
-awt.85=SetConstraints: {0}
-awt.86=MinimumLayoutSize: {0}
-awt.87=PreferredLayoutSize: {0}
-awt.88=LayoutContainer: {0}
-awt.89=LookupConstraints: attempt to get constraints of null component
-awt.8A=AdjustForGravity: attempt to use null constraints
-awt.8B=AdjustForGravity: attempt to use null rectangle
-awt.8C=AdjustForGravity: {0}
-awt.8D=REMINDER component expected after RELATIVE one
-awt.8E=component is out of grid's range
-awt.8F=Weights' overrides array is too long
-awt.90=Lengths' overrides array is too long
-awt.91=Unsupported constraints object: {0}
-awt.92=Constraints object must be String
-awt.93=cannot get component: invalid constraint: {0}
-awt.94=transform can not be null
-awt.95=Wrong start index: {0}
-awt.96=Wrong finish index: {0}
-awt.97=Wrong range length: {0}
-awt.98=Wrong count value, can not be negative: {0}
-awt.99=Wrong [start + count] is out of range: {0}
-awt.9A=Unsupported font format
-awt.9B=Can't create font - bad font data
-awt.9C=wrong value of GridBagConstraints: {0}
-awt.9D=relative grid size parameter goes after absolute grid coordinate
-awt.9E=wrong values sum of GridBagConstraints' gridwidth and gridx
-awt.9F=wrong values sum of GridBagConstraints' gridheight and gridy
-awt.100=component has RELATIVE width and height
-awt.101=position less than zero.
-awt.102=columns less than zero.
-awt.103=item is null
-awt.104=item doesn't exist in the choice menu
-awt.105=index less than zero
-awt.106=specified position is greater than the number of items
-awt.107=Color parameter outside of expected range: component {0}
-awt.108=Alpha value outside of expected range
-awt.109=Color parameter outside of expected range
-awt.10A=Priority must be a value between 0 and 1, inclusive
-awt.10B=aContainer and aComponent cannot be null
-awt.10C=aContainer is not a focus cycle root of aComponent
-awt.10D=aContainer should be focus cycle root or focus traversal policy provider
-awt.10E=focusCycleRoot cannot be null
-awt.10F=improper alignment: {0}
-awt.110=Iterator out of bounds
-awt.111=Parameter npoints is greater than array length
-awt.112=Negative number of points
-awt.113=illegal scrollbar orientation
-awt.114=Image is null
-awt.115=Anchor is null
-awt.116=Invalid value for media
-awt.117=Invalid value for orientationRequested
-awt.118=Invalid value for printerResolution
-awt.119=Invalid value for origin
-awt.11A=Invalid value for printQuality
-awt.11B=Invalid value for printerResolution[]
-awt.11C=Invalid value for color
-awt.11D=Unknown rule
-awt.11E=Wrong alpha value
-awt.11F=parent is not a component
-awt.120=origin is not a descendant of parent
-awt.121=parent must be showing on the screen
-awt.122=Does not support display mode changes
-awt.123=Unsupported display mode: {0}
-awt.124=Cannot change the modality while the dialog is visible
-awt.125=null owner window
-awt.126=Window is showing
-awt.127=Cannot change the decorations while the window is visible
-awt.128=Graphics environment is headless
-awt.129=Not a screen device
-awt.12A=illegal component position
-awt.12B=adding container to itself
-awt.12C=adding container's parent to itself
-awt.12D=adding a window to a container
-awt.12E=Unknown component event id
-awt.12F=Attempt to start nested mouse grab
-awt.130=Attempt to grab mouse in not displayable window
-awt.131=AddLayoutComponent: constraint object must be String
-awt.132=wrong parent for CardLayout
-awt.133=Negative width
-awt.134=Illegal cap
-awt.135=Illegal join
-awt.136=miterLimit less than 1.0f
-awt.137=Negative dashPhase
-awt.138=Zero dash length
-awt.139=Negative dash[{0}]
-awt.13A=All dash lengths zero
-awt.13B=offset off is out of range
-awt.13C=number of elemets len is out of range
-awt.13D=Rectangle width and height must be > 0
-awt.13E=Cannot call method from the event dispatcher thread
-awt.13F=Delay must be to 0 to 60,000ms
-awt.140=Invalid combination of button flags
-awt.141=failed to parse hotspot property for cursor: 
-awt.142=Exception: class {0} {1} occurred while loading: {2}
-awt.143=illegal cursor type
-awt.144=Can be set by scrollpane only
-awt.145=illegal file dialog mode
-awt.146=illegal scrollbar display policy
-awt.147=position greater than 0
-awt.148=child is null
-awt.149=ScrollPane controls layout
-awt.14A=Can not create VolatileImage with specified capabilities
-awt.14B=Only Canvas or Window is allowed
-awt.14C=Number of buffers must be greater than one
-awt.14D=Buffer capabilities should support flipping
-awt.14E=Component should be displayable
-awt.14F=invalid focus traversal key identifier
-awt.150=no parent
-awt.151=component must be showing on the screen to determine its location
-awt.152=Invalid number of copies
-awt.153=Invalid value for maxPage
-awt.154=Invalid value for minPage
-awt.155=Invalid value for fromPage
-awt.156=Invalid value for toPage
-awt.157=Invalid value for pageRanges
-awt.158=Invalid value for destination
-awt.159=Invalid value for dialog
-awt.15A=Invalid value for defaultSelection
-awt.15B=Invalid value for multipleDocumentHandling
-awt.15C=Invalid value for attribute sides
-awt.15D=Invalid colorspace
-awt.15E=Unknown component. Must be REDCOMPONENT, GREENCOMPONENT or BLUECOMPONENT.
-awt.15F=Profile class does not comply with ICC specification
-awt.160=Color space doesn't comply with ICC specification
-awt.161=Unable to open file {0}
-awt.162=Invalid ICC Profile Data
-awt.163=Can't open color profile
-awt.164=Not a predefined color space
-awt.165=Color space doesn't comply with ICC specification
-awt.166=TRC is not a simple gamma value
-awt.167=TRC is a gamma value, not a table
-awt.168=Invalid profile class
-awt.169=Component index out of range
-awt.16A=Invalid component index: {0}
-awt.16B=Not a predefined colorspace
-awt.16C=Can't load class: {0}
-awt.16D=Can't parse MIME type: {0}
-awt.16E=Transferable has null data
-awt.16F=Can't create reader for this representation class
-awt.170=Can't create default D&D cursor: {0}
-awt.171=Attempt to start a drag while an existing drag operation is still executing
-awt.172=Drag source is null
-awt.173=One listener is already exist
-awt.174=dgl is not current listener
-awt.175=Listener mismatch
-awt.176=DropTarget cannot be added as listener to itself
-awt.177=Invalid user action
-awt.178=Invalid source action
-awt.179=Context peer is null
-awt.17A=Trigger event is null
-awt.17B=Can't init ACTION_NONE drag
-awt.17C=Image offset is null
-awt.17D=Transferable is null
-awt.17E=Component associated with the trigger event is null
-awt.17F=DragSource for the trigger event is null
-awt.180=Source actions for the DragGestureRecognizer associated with the trigger event are equal to DnDConstants.ACTION_NONE
-awt.181=Attempt to register context as its listener
-awt.182=dsl is not current listener
-awt.183=Invalid status
-awt.184=Invalid action
-awt.185=Component is null
-awt.186=DragSource is null
-awt.187=Origin is null
-awt.188=Event list is null
-awt.189=Event list is empty
-awt.18A=Context is null
-awt.18B=Invalid button value
-awt.18C=Cannot invoke null runnable
-awt.18D=Source is null
-awt.18E=Wrong event id
-awt.18F=Text must be null for CARET_POSITION_CHANGED
-awt.190=Wrong committedCharacterCount
-awt.191=Invalid keyCode for KEY_TYPED event, must be VK_UNDEFINED
-awt.192=Invalid keyChar for KEY_TYPED event, can't be CHAR_UNDEFINED
-awt.193=Listener can't be zero
-awt.194=Unknown attribute name
-awt.195=Offset is out of bounds
-awt.196=Justification impossible, layout already justified
-awt.197=Endpoints are out of range
-awt.198=Illegal alignment argument
-awt.199=Illegal range argument value: {0}
-awt.19A=start or count arguments are out of text range
-awt.19B=count argument must be positive
-awt.19C=weight must be a positive number
-awt.19D=growLeftLimit must be a positive number
-awt.19E=growRightLimit must be a positive number
-awt.19F=incorrect value for shrinkPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
-awt.200=incorrect value for growPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
-awt.201=shrinkLeftLimit must be a positive number
-awt.202=shrinkRightLimit must be a positive number
-awt.203=Offset limit should be greater than current position
-awt.204=Determinant is zero
-awt.205=Invalid type of Arc: {0}
-awt.206=Flatness is less then zero
-awt.207=Limit is less then zero
-awt.208=Path is null
-awt.209=Invalid winding rule value
-awt.20A=First segment should be SEG_MOVETO type
-awt.20B=unknown input method highlight state
-awt.20C=Number of Bits equals to zero
-awt.20D=The number of bits per pixel is not a power of 2 or pixels span data element boundaries
-awt.20E=Data Bit offset is not a multiple of pixel bit stride
-awt.20F=Number of bands must be only 1
-awt.210=The component value for this ColorModel is signed
-awt.211=Pixel values for this ColorModel are not conveniently representable as a single int
-awt.212=There is more than one component in this ColorModel
-awt.213=This ComponentColorModel does not support the unnormalized form
-awt.214=This Color Model doesn't support this transferType
-awt.215=transferType is not one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE
-awt.216=The components array is not large enough to hold all the color and alpha components
-awt.217=The transfer type of this ComponentColorModel is not one of the following transfer types: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
-awt.218=The components array is not large enough to hold all the color and alpha components
-awt.219=This transferType is not supported by this color model
-awt.21A=This ComponentColorModel does not support this transferType
-awt.21B=The length of normComponents minus normOffset is less than numComponents
-awt.21C=The number of scale factors should not be zero
-awt.21D=Number of src bands ({0}) does not match number of dst bands ({1})
-awt.21E=Number of scaling constants is not equal to the number of bands
-awt.21F=Unable to transform source
-awt.220=Source should not have IndexColorModel
-awt.221=The imageType is TYPE_BYTE_BINARY and the color map has more than 16 entries
-awt.222=The imageType is not TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED
-awt.223=The imageType is not compatible with ColorModel
-awt.224=Unknown image type
-awt.225=Property name is null
-awt.226=Both tileX and tileY are not equal to 0
-awt.227=This image type can't have alpha
-awt.228=minX or minY of this raster not equal to zero
-awt.229=Number of components in the LUT does not match the number of bands
-awt.22A=Wrong type of pixels array
-awt.22B=Length of data should not be less than width*height
-awt.22C=Unknown data type {0}
-awt.22D=This transferType ( {0} ) is not supported by this color model
-awt.22E=w or h is less than or equal to zero
-awt.22F=The product of w and h is greater than Integer.MAX_VALUE
-awt.230=dataType is not one of the supported data types
-awt.231=Number of bands must be more then 0
-awt.232=Offset should be not less than zero
-awt.233=Number of components should be positive
-awt.234=Width or Height equals zero
-awt.235=Wrong Data Buffer type : {0}
-awt.236=The bits is less than 1 or greater than 32
-awt.237=Source and destinations rasters do not have the same number of bands
-awt.238=The number of arrays in the LookupTable does not meet the restrictions
-awt.239=The space is not a TYPE_RGB space
-awt.23A=The min/max normalized component values are not 0.0/1.0
-awt.23B=The mask of the {0} component is not contiguous
-awt.23C=The mask of the alpha component is not contiguous
-awt.23D=The mask of the red component is not contiguous
-awt.23E=The mask of the green component is not contiguous
-awt.23F=The mask of the blue component is not contiguous
-awt.240=The transferType not is one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT or DataBuffer.TYPE_INT
-awt.241=Any offset between bands is greater than the Scanline stride
-awt.242=Pixel stride is less than any offset between bands
-awt.243=Product of Pixel stride and w is greater than Scanline stride
-awt.244=Width or Height of child Raster is less than or equal to zero
-awt.245=parentX disposes outside Raster
-awt.246=parentY disposes outside Raster
-awt.247=parentX + w results in integer overflow
-awt.248=parentY + h results in integer overflow
-awt.249=childMinX + w results in integer overflow
-awt.24A=childMinY + h results in integer overflow
-awt.24B=Pixel stride must be >= 0
-awt.24C=Scanline stride must be >= 0
-awt.24D=Bank Indices length must be equal Bank Offsets length
-awt.24E=Index of {0} bank must be >= 0
-awt.24F=Unable to invert transform {0}
-awt.250=Unknown interpolation type: {0}
-awt.251=Transformed width ({0}) and height ({1}) should be greater than 0
-awt.252=Source can't be same as the destination
-awt.253=Different number of bands in source and destination
-awt.254=Number of bands in the source raster ({0}) is incompatible with the matrix [{1}x{2}]
-awt.255=Number of bands in the destination raster ({0}) is incompatible with the matrix [{1}x{2}]
-awt.256=Source raster is null
-awt.257=Source raster is equal to destination
-awt.258=Number of source bands ({0}) is not equal to number of destination bands ({1})
-awt.259=Source image is null
-awt.25A=Source equals to destination
-awt.25B=Null ColorSpace passed as a parameter
-awt.25C=Null profiles passed as a parameter
-awt.25D=Source or destination color space is not defined
-awt.25E=Incorrect number of source raster bands. Should be equal to the number of color components of source colorspace.
-awt.25F=Incorrect number of destination raster bands. Should be equal to the number of color components of destination colorspace.
-awt.260=Incompatible rasters - width or height differs
-awt.261=Destination color space is undefined
-awt.262=Destionation color space should be defined
-awt.263=Incompatible images - width or height differs
-awt.264=Size of the color map is less than 1
-awt.265=The raster argument is not compatible with this IndexColorModel
-awt.266=The number of bits in a pixel is greater than 16
-awt.267=The transferType is invalid
-awt.268=The pixel is not a primitive array of type transferType
-awt.269=The transferType is not one of DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT
-awt.26A=Incorrect ImageConsumer completion status
-awt.26B=The number of bits in the pixel values is less than 1
-awt.26C=bits is null
-awt.26D=The elements in bits is less than 0
-awt.26E=The sum of the number of bits in bits is less than 1
-awt.26F=The cspace is null
-awt.270=The transparency is not a valid value
-awt.271=The number of bits in bits is less than 1
-awt.272=The length of components minus offset is less than numComponents
-awt.273=The length of normComponents minus normOffset is less than numComponents
-awt.274=componentIdx is greater than the number of components or less than zero
-awt.275=This pixel representation is not suuported by tis Color Model
-awt.276=location.x + w or location.y + h results in integer overflow
-awt.277=bankIndices or bandOffsets is null
-awt.278=dataBuffer is null
-awt.279=bands is less than 1
-awt.27A=dataBuffer has more than one bank
-awt.27B=bandOffsets is null
-awt.27C=bandMasks is null
-awt.27D=bitsPerBand or bands is not greater than zero
-awt.27E=The product of bitsPerBand and bands is greater than the number of bits held by dataType
-awt.27F=SampleModel or DataBuffer is null
-awt.280=SampleModel is null
-awt.281=sampleModel, dataBuffer, aRegion or sampleModelTranslate is null
-awt.282=aRegion has width or height less than or equal to zero
-awt.283=Overflow X coordinate of Raster
-awt.284=Overflow Y coordinate of Raster
-awt.285=Width or Height of child Raster is less than or equal to zero
-awt.286=parentX disposes outside Raster
-awt.287=parentY disposes outside Raster
-awt.288=parentX + width results in integer overflow
-awt.289=parentY + height results in integer overflow
-awt.28A=childMinX + width results in integer overflow
-awt.28B=childMinY + height results in integer overflow
-awt.28C=Rect is null
-awt.28D=Length of dataArray[{0}] is less than size + offset[{1}]
-awt.28E=Length of dataArray is less than size + offset
-awt.28F=Source and destination rasters do not have the same width!
-awt.290=Source and destination rasters do not have the same height!
-awt.291=Source and destination images do not have the same width!
-awt.292=Source and destination images do not have the same height!
-awt.294=pixel is null
-awt.295=data is null
-awt.296=can't allocate memory on video card to create new display list
-awt.297=Invalid keyLocation
-awt.298=dataBuffer is too small
-
-awt.err.00=file dialog {0} error!
-awt.err.01=error: {0}
-awt.err.02=GDIPlus DrawDriverString error status = {0}
-awt.err.03=gdipDrawCompositeGlyphVector: GDIPlus DrawDriverString error status = {0}
-awt.err.04=gdipDrawCompositeGlyphVector: GDIPlus DrawDriverString error status = {0}
diff --git a/awt/resources/org/apache/harmony/beans/internals/nls/messages.properties b/awt/resources/org/apache/harmony/beans/internals/nls/messages.properties
deleted file mode 100644
index 72b1c8c..0000000
--- a/awt/resources/org/apache/harmony/beans/internals/nls/messages.properties
+++ /dev/null
@@ -1,103 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-# 
-
-# messages for EN locale
-beans.00=no getter for {0} property
-beans.01=no property for name {0} is found
-beans.02=in DefaultPersistenceDelegate.mutatesTo() {0} : {1}
-beans.03=Target Bean class is null
-beans.04=bad property name
-beans.05=Modifier for setter method should be public.
-beans.06=Number of parameters in setter method is not equal to 1.
-beans.07=Parameter type in setter method does not corresponds to predefined.
-beans.08=Number of parameters in getter method is not equal to 0.
-beans.09=Parameter type in getter method does not corresponds to predefined.
-beans.0A=Modifier for getter method should be public.
-beans.0B=Exception in command execution
-beans.0C=source is null
-beans.0D=Error in expression: {0}
-beans.0E=Changes are null
-beans.0F=The new BeanContext can not be set
-beans.10=no node is found for statement with target = {0}
-beans.11=no getter for property {0} found
-beans.12=cannot access property {0} getter
-beans.13=no setter for property {0} found
-beans.14=Exception while finding property descriptor
-beans.15=The listener is null
-beans.16=The provider is null
-beans.17=The child is null
-beans.18=The requestor is null
-beans.19=The service class is null
-beans.1A=The service selector is null
-beans.1B=The service is null
-beans.1C=The event is null
-beans.1D=bean is null
-beans.1E=Illegal class name: {0}
-beans.1F=Method not found: get{0}
-beans.20=Method not found: set{0}
-beans.21=Modifier for indexed getter method should be public.
-beans.22=Number of parameters in getter method is not equal to 1.
-beans.23=Parameter in indexed getter method is not of integer type.
-beans.24=Parameter type in indexed getter method does not correspond to predefined.
-beans.25=Modifier for indexed setter method should be public.
-beans.26=Number of parameters in indexed setter method is not equal to 2.
-beans.27=First parameter type in indexed setter method should be int.
-beans.28=Second parameter type in indexed setter method does not corresponds to predefined.
-beans.29=Membership listener is null
-beans.2A=Target child can not be null
-beans.2B=Resource name can not be null
-beans.2C=The child can not be null
-beans.2D=Invalid resource
-beans.2E=PropertyVetoException was thrown while removing a child: {0}; Original error message:{1}
-beans.2F=Target child is null
-beans.30=PropertyVetoException was thrown while adding a child: {0}; Original error message:{1}
-beans.31=No valid method {0} for {1} found.
-beans.32=Cannot acquire event type from {0} listener.
-beans.33={0} does not return <void>
-beans.34={0} should have a single input parameter
-beans.35=Single parameter does not match to {0} class
-beans.36=No input params are allowed for getListenerMethod
-beans.37=Return type of getListenerMethod is not an array of listeners
-beans.38=Add and remove methods are not available
-beans.39=Cannot generate event set descriptor for name {0}.
-beans.3A=Event type with name {0} is not found.
-beans.3B=skipping expression {0}...
-beans.3C=Unknown method name for array
-beans.3D=First parameter in array getter(setter) is not of Integer type
-beans.3E=Illegal number of arguments in array getter
-beans.3F=Illegal number of arguments in array setter
-beans.40=No constructor for class {0} found
-beans.41=No method with name {0} is found
-beans.42=target is not generated: classname {0} is not found
-beans.43=Cannot convert {0} to char
-beans.44=for property {0} no getter(setter) is found
-beans.45=method name is not generated: error in getMethodName()
-beans.46=Not a valid child
-beans.47=Unable to instantiate property editor
-beans.48=Property editor is not assignable from the PropertyEditor interface
-beans.49=Child cannot implement both BeanContextChild and BeanContextProxy
-beans.4A=newInstance is null
-beans.4B=type is null
-beans.4C=encoder is null
-beans.4D=Invalid method call
-beans.4E=stopClass is not ancestor of beanClass
-beans.4F=search path is null
-beans.50=not an indexed property
-beans.51=Listener method {0} should have parameter of type {1}
-beans.52=listenerMethodName(s) is null
-beans.53=eventSetName is null
-beans.54=listenerType is null
-beans.55=Method is null
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 8f3642c..a09666e 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -115,6 +115,8 @@
             "su", "root", "wpa_cli", "list_networks", NULL);
 
 #ifdef FWDUMP_bcm4329
+    run_command("DUMP WIFI STATUS", 20,
+            "su", "root", "dhdutil", "-i", "eth0", "dump", NULL);
     run_command("DUMP WIFI FIRMWARE LOG", 60,
             "su", "root", "dhdutil", "-i", "eth0", "upload", "/data/local/tmp/wlan_crash.dump", NULL);
 #endif
@@ -239,8 +241,18 @@
 
     /* switch to non-root user and group */
     gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT };
-    setgroups(sizeof(groups)/sizeof(groups[0]), groups);
-    setuid(AID_SHELL);
+    if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
+        LOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
+        return -1;
+    }
+    if (setgid(AID_SHELL) != 0) {
+        LOGE("Unable to setgid, aborting: %s\n", strerror(errno));
+        return -1;
+    }
+    if (setuid(AID_SHELL) != 0) {
+        LOGE("Unable to setuid, aborting: %s\n", strerror(errno));
+        return -1;
+    }
 
     char path[PATH_MAX], tmp_path[PATH_MAX];
     pid_t gzip_pid = -1;
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 9b8b0ac..040421a 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -233,7 +233,7 @@
             for (int i=0; i<rawList.length; i++) {
                 list.add(rawList[i]);
             }
-                    
+
 
             // Sort by name
             Collections.sort(list, new Comparator<FeatureInfo>() {
@@ -909,6 +909,9 @@
         System.err.println("The list instrumentation command prints all instrumentations,");
         System.err.println("or only those that target a specified package.  Options:");
         System.err.println("  -f: see their associated file.");
+        System.err.println("(Use this command to list all test packages, or use <TARGET-PACKAGE> ");
+        System.err.println(" to list the test packages for a particular application. The -f ");
+        System.err.println(" option lists the .apk file for the test package.)");
         System.err.println("");
         System.err.println("The list features command prints all features of the system.");
         System.err.println("");
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 5a87f4c..c424281 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -32,9 +32,15 @@
 
 using namespace android;
 
+static const int32_t kFramerate = 24;  // fps
+static const int32_t kIFramesIntervalSec = 1;
+static const int32_t kVideoBitRate = 512 * 1024;
+static const int32_t kAudioBitRate = 12200;
+static const int32_t kColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+static const int64_t kDurationUs = 10000000LL;  // 10 seconds
+
 #if 1
 class DummySource : public MediaSource {
-    static const int32_t kFramerate = 24;  // fps
 
 public:
     DummySource(int width, int height)
@@ -176,6 +182,12 @@
     enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
     enc_meta->setInt32(kKeyWidth, width);
     enc_meta->setInt32(kKeyHeight, height);
+    enc_meta->setInt32(kKeySampleRate, kFramerate);
+    enc_meta->setInt32(kKeyBitRate, kVideoBitRate);
+    enc_meta->setInt32(kKeyStride, width);
+    enc_meta->setInt32(kKeySliceHeight, height);
+    enc_meta->setInt32(kKeyIFramesInterval, kIFramesIntervalSec);
+    enc_meta->setInt32(kKeyColorFormat, kColorFormat);
 
     sp<MediaSource> encoder =
         OMXCodec::Create(
@@ -184,8 +196,10 @@
 #if 1
     sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
     writer->addSource(encoder);
+    writer->setMaxFileDuration(kDurationUs);
     writer->start();
     while (!writer->reachedEOS()) {
+        fprintf(stderr, ".");
         usleep(100000);
     }
     writer->stop();
@@ -194,6 +208,8 @@
 
     MediaBuffer *buffer;
     while (encoder->read(&buffer) == OK) {
+        printf(".");
+        fflush(stdout);
         int32_t isSync;
         if (!buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)) {
             isSync = false;
@@ -209,6 +225,7 @@
     encoder->stop();
 #endif
 
+    printf("$\n");
     client.disconnect();
 #endif
 
@@ -267,6 +284,7 @@
     encMeta->setInt32(kKeySampleRate, kSampleRate);
     encMeta->setInt32(kKeyChannelCount, kNumChannels);
     encMeta->setInt32(kKeyMaxInputSize, 8192);
+    encMeta->setInt32(kKeyBitRate, kAudioBitRate);
 
     sp<MediaSource> encoder =
         OMXCodec::Create(client.interface(), encMeta, true, audioSource);
diff --git a/core/java/android/animation/Animatable.java b/core/java/android/animation/Animatable.java
index d6cf7c0..3fdf200 100644
--- a/core/java/android/animation/Animatable.java
+++ b/core/java/android/animation/Animatable.java
@@ -16,6 +16,8 @@
 
 package android.animation;
 
+import android.view.animation.Interpolator;
+
 import java.util.ArrayList;
 
 /**
@@ -56,6 +58,46 @@
     public void end() {
     }
 
+    /**
+     * The amount of time, in milliseconds, to delay starting the animation after
+     * {@link #start()} is called.
+     *
+     * @return the number of milliseconds to delay running the animation
+     */
+    public abstract long getStartDelay();
+
+    /**
+     * The amount of time, in milliseconds, to delay starting the animation after
+     * {@link #start()} is called.
+
+     * @param startDelay The amount of the delay, in milliseconds
+     */
+    public abstract void setStartDelay(long startDelay);
+
+
+    /**
+     * Sets the length of the animation.
+     *
+     * @param duration The length of the animation, in milliseconds.
+     */
+    public abstract void setDuration(long duration);
+
+    /**
+     * Gets the length of the animation.
+     *
+     * @return The length of the animation, in milliseconds.
+     */
+    public abstract long getDuration();
+
+    /**
+     * The time interpolator used in calculating the elapsed fraction of this animation. The
+     * interpolator determines whether the animation runs with linear or non-linear motion,
+     * such as acceleration and deceleration. The default value is
+     * {@link android.view.animation.AccelerateDecelerateInterpolator}
+     *
+     * @param value the interpolator to be used by this animation
+     */
+    public abstract void setInterpolator(Interpolator value);
 
     /**
      * Returns whether this Animatable is currently running (having been started and not yet ended).
@@ -115,17 +157,56 @@
     }
 
     @Override
-    public Animatable clone() throws CloneNotSupportedException {
-        final Animatable anim = (Animatable) super.clone();
-        if (mListeners != null) {
-            ArrayList<AnimatableListener> oldListeners = mListeners;
-            anim.mListeners = new ArrayList<AnimatableListener>();
-            int numListeners = oldListeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                anim.mListeners.add(oldListeners.get(i));
+    public Animatable clone() {
+        try {
+            final Animatable anim = (Animatable) super.clone();
+            if (mListeners != null) {
+                ArrayList<AnimatableListener> oldListeners = mListeners;
+                anim.mListeners = new ArrayList<AnimatableListener>();
+                int numListeners = oldListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    anim.mListeners.add(oldListeners.get(i));
+                }
             }
+            return anim;
+        } catch (CloneNotSupportedException e) {
+           throw new AssertionError();
         }
-        return anim;
+    }
+
+    /**
+     * This method tells the object to use appropriate information to extract
+     * starting values for the animation. For example, a Sequencer object will pass
+     * this call to its child objects to tell them to set up the values. A
+     * PropertyAnimator object will use the information it has about its target object
+     * and PropertyValuesHolder objects to get the start values for its properties.
+     * An Animator object will ignore the request since it does not have enough
+     * information (such as a target object) to gather these values.
+     */
+    public void setupStartValues() {
+    }
+
+    /**
+     * This method tells the object to use appropriate information to extract
+     * ending values for the animation. For example, a Sequencer object will pass
+     * this call to its child objects to tell them to set up the values. A
+     * PropertyAnimator object will use the information it has about its target object
+     * and PropertyValuesHolder objects to get the start values for its properties.
+     * An Animator object will ignore the request since it does not have enough
+     * information (such as a target object) to gather these values.
+     */
+    public void setupEndValues() {
+    }
+
+    /**
+     * Sets the target object whose property will be animated by this animation. Not all subclasses
+     * operate on target objects (for example, {@link android.animation.Animator}, but this method
+     * is on the superclass for the convenience of dealing generically with those subclasses
+     * that do handle targets.
+     *
+     * @param target The object being animated
+     */
+    public void setTarget(Object target) {
     }
 
     /**
diff --git a/core/java/android/animation/AnimatableListenerAdapter.java b/core/java/android/animation/AnimatableListenerAdapter.java
index 25a842b..c169b28 100644
--- a/core/java/android/animation/AnimatableListenerAdapter.java
+++ b/core/java/android/animation/AnimatableListenerAdapter.java
@@ -26,28 +26,28 @@
 public abstract class AnimatableListenerAdapter implements AnimatableListener {
 
     /**
-     * @{inheritdoc}
+     * {@inheritdoc}
      */
     @Override
     public void onAnimationCancel(Animatable animation) {
     }
 
     /**
-     * @{inheritdoc}
+     * {@inheritdoc}
      */
     @Override
     public void onAnimationEnd(Animatable animation) {
     }
 
     /**
-     * @{inheritdoc}
+     * {@inheritdoc}
      */
     @Override
     public void onAnimationRepeat(Animatable animation) {
     }
 
     /**
-     * @{inheritdoc}
+     * {@inheritdoc}
      */
     @Override
     public void onAnimationStart(Animatable animation) {
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 8b74658..8e947ec 100755
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -145,10 +145,10 @@
     private static final ArrayList<Animator> sReadyAnims = new ArrayList<Animator>();
 
     /**
-     * Flag that denotes whether the animation is set up and ready to go. Used by seek() to
+     * Flag that denotes whether the animation is set up and ready to go. Used to
      * set up animation that has not yet been started.
      */
-    private boolean mInitialized = false;
+    boolean mInitialized = false;
 
     //
     // Backing variables
@@ -243,6 +243,14 @@
         }
     }
 
+    /**
+     * Sets the values, per property, being animated between. This function is called internally
+     * by the constructors of Animator that take a list of values. But an Animator can
+     * be constructed without values and this method can be called to set the values manually
+     * instead.
+     *
+     * @param values The set of values, per property, being animated between.
+     */
     public void setValues(PropertyValuesHolder... values) {
         int numValues = values.length;
         mValues = values;
@@ -254,6 +262,18 @@
     }
 
     /**
+     * Returns the values that this Animator animates between. These values are stored in
+     * PropertyValuesHolder objects, even if the Animator was created with a simple list
+     * of value objects instead.
+     *
+     * @return PropertyValuesHolder[] An array of PropertyValuesHolder objects which hold the
+     * values, per property, that define the animation.
+     */
+    public PropertyValuesHolder[] getValues() {
+        return mValues;
+    }
+
+    /**
      * Sets the values to animate between for this animation. If <code>values</code> is
      * a set of PropertyValuesHolder objects, these objects will become the set of properties
      * animated and the values that those properties are animated between. Otherwise, this method
@@ -286,12 +306,14 @@
      *  that internal mechanisms for the animation are set up correctly.</p>
      */
     void initAnimation() {
-        int numValues = mValues.length;
-        for (int i = 0; i < numValues; ++i) {
-            mValues[i].init();
+        if (!mInitialized) {
+            int numValues = mValues.length;
+            for (int i = 0; i < numValues; ++i) {
+                mValues[i].init();
+            }
+            mCurrentIteration = 0;
+            mInitialized = true;
         }
-        mCurrentIteration = 0;
-        mInitialized = true;
     }
 
 
@@ -324,9 +346,7 @@
      * @param playTime The time, in milliseconds, to which the animation is advanced or rewound.
      */
     public void setCurrentPlayTime(long playTime) {
-        if (!mInitialized) {
-            initAnimation();
-        }
+        initAnimation();
         long currentTime = AnimationUtils.currentAnimationTimeMillis();
         if (mPlayingState != RUNNING) {
             mSeekTime = playTime;
@@ -619,6 +639,7 @@
      *
      * @param value the interpolator to be used by this animation
      */
+    @Override
     public void setInterpolator(Interpolator value) {
         if (value != null) {
             mInterpolator = value;
@@ -783,6 +804,10 @@
      * should be added to the set of active animations.
      */
     private boolean delayedAnimationFrame(long currentTime) {
+        if (mPlayingState == CANCELED || mPlayingState == ENDED) {
+            // end the delay, process an animation frame to actually cancel it
+            return true;
+        }
         if (!mStartedDelay) {
             mStartedDelay = true;
             mDelayStartTime = currentTime;
@@ -898,7 +923,7 @@
     }
 
     @Override
-    public Animator clone() throws CloneNotSupportedException {
+    public Animator clone() {
         final Animator anim = (Animator) super.clone();
         if (mUpdateListeners != null) {
             ArrayList<AnimatorUpdateListener> oldListeners = mUpdateListeners;
@@ -919,7 +944,7 @@
             int numValues = oldValues.length;
             anim.mValues = new PropertyValuesHolder[numValues];
             for (int i = 0; i < numValues; ++i) {
-                anim.mValues[i] = oldValues[i];
+                anim.mValues[i] = oldValues[i].clone();
             }
             anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
             for (int i = 0; i < numValues; ++i) {
diff --git a/core/java/android/animation/Keyframe.java b/core/java/android/animation/Keyframe.java
index e2800b3..7d4d104 100644
--- a/core/java/android/animation/Keyframe.java
+++ b/core/java/android/animation/Keyframe.java
@@ -26,7 +26,7 @@
  * next keyframe. Each keyframe also holds an option {@link android.view.animation.Interpolator}
  * object, which defines the time interpolation over the intervalue preceding the keyframe.
  */
-public class Keyframe {
+public class Keyframe implements Cloneable {
     /**
      * The time at which mValue will hold true.
      */
@@ -81,7 +81,55 @@
      * this keyframe.
      */
     public Keyframe(float fraction, Object value) {
-        this(fraction, value, Object.class);
+        this(fraction, value, (value != null) ? value.getClass() : Object.class);
+    }
+
+    /**
+     * Constructs a Keyframe object with the given time and float value. The time defines the
+     * time, as a proportion of an overall animation's duration, at which the value will hold true
+     * for the animation. The value for the animation between keyframes will be calculated as
+     * an interpolation between the values at those keyframes.
+     *
+     * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
+     * of time elapsed of the overall animation duration.
+     * @param value The value that the object will animate to as the animation time approaches
+     * the time in this keyframe, and the the value animated from as the time passes the time in
+     * this keyframe.
+     */
+    public Keyframe(float fraction, Float value) {
+        this(fraction, value, Float.class);
+    }
+
+    /**
+     * Constructs a Keyframe object with the given time and integer value. The time defines the
+     * time, as a proportion of an overall animation's duration, at which the value will hold true
+     * for the animation. The value for the animation between keyframes will be calculated as
+     * an interpolation between the values at those keyframes.
+     *
+     * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
+     * of time elapsed of the overall animation duration.
+     * @param value The value that the object will animate to as the animation time approaches
+     * the time in this keyframe, and the the value animated from as the time passes the time in
+     * this keyframe.
+     */
+    public Keyframe(float fraction, Integer value) {
+        this(fraction, value, Integer.class);
+    }
+
+    /**
+     * Constructs a Keyframe object with the given time and double value. The time defines the
+     * time, as a proportion of an overall animation's duration, at which the value will hold true
+     * for the animation. The value for the animation between keyframes will be calculated as
+     * an interpolation between the values at those keyframes.
+     *
+     * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
+     * of time elapsed of the overall animation duration.
+     * @param value The value that the object will animate to as the animation time approaches
+     * the time in this keyframe, and the the value animated from as the time passes the time in
+     * this keyframe.
+     */
+    public Keyframe(float fraction, Double value) {
+        this(fraction, value, Double.class);
     }
 
     /**
@@ -200,4 +248,11 @@
     public Class getType() {
         return mValueType;
     }
+
+    @Override
+    public Keyframe clone() {
+        Keyframe kfClone = new Keyframe(mFraction, mValue, mValueType);
+        kfClone.setInterpolator(mInterpolator);
+        return kfClone;
+    }
 }
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
new file mode 100644
index 0000000..5dfdfbd
--- /dev/null
+++ b/core/java/android/animation/LayoutTransition.java
@@ -0,0 +1,778 @@
+/*
+ * 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 android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * This class enables automatic animations on layout changes in ViewGroup objects. To enable
+ * transitions for a layout container, create a LayoutTransition object and set it on any
+ * ViewGroup by calling {@link ViewGroup#setLayoutTransition(LayoutTransition)}. This will cause
+ * default animations to run whenever items are added to or removed from that container. To specify
+ * custom animations, use the {@link LayoutTransition#setAnimatable(int, Animatable)
+ * setAnimatable()} method.
+ *
+ * <p>One of the core concepts of these transition animations is that there are two core
+ * changes that cause the transition and four different animations that run because of
+ * those changes. The changes that trigger the transition are items being added to a container
+ * (referred to as an "appearing" transition) or removed from a container (also known as
+ * "disappearing"). The animations that run due to those events are one that animates
+ * items being added, one that animates items being removed, and two that animate the other
+ * items in the container that change due to the add/remove occurrence. Users of
+ * the transition may want different animations for the changing items depending on whether
+ * they are changing due to anappearing or disappearing event, so there is one animation for
+ * each of these variations of the changing event. Most of the API of this class is concerned
+ * with setting up the basic properties of the animations used in these four situations,
+ * or with setting up custom animations for any or all of the four.</p>
+ *
+ * <p>The animations specified for the transition, both the defaults and any custom animations
+ * set on the transition object, are templates only. That is, these animations exist to hold the
+ * basic animation properties, such as the duration, start delay, and properties being animated.
+ * But the actual target object, as well as the start and end values for those properties, are
+ * set automatically in the process of setting up the transition each time it runs. Each of the
+ * animations is cloned from the original copy and the clone is then populated with the dynamic
+ * values of the target being animated (such as one of the items in a layout container that is
+ * moving as a result of the layout event) as well as the values that are changing (such as the
+ * position and size of that object). The actual values that are pushed to each animation
+ * depends on what properties are specified for the animation. For example, the default
+ * CHANGE_APPEARING animation animates <code>left</code>, <code>top</code>, <code>right</code>,
+ * and <code>bottom</code>. Values for these properties are updated with the pre- and post-layout
+ * values when the transition begins. Custom animations will be similarly populated with
+ * the target and values being animated, assuming they use PropertyAnimator objects with
+ * property names that are known on the target object.</p>
+ */
+public class LayoutTransition {
+
+    /**
+     * A flag indicating the animation that runs on those items that are changing
+     * due to a new item appearing in the container.
+     */
+    public static final int CHANGE_APPEARING = 0;
+
+    /**
+     * A flag indicating the animation that runs on those items that are changing
+     * due to a new item disappearing from the container.
+     */
+    public static final int CHANGE_DISAPPEARING = 1;
+
+    /**
+     * A flag indicating the animation that runs on those items that are changing
+     * due to a new item appearing in the container.
+     */
+    public static final int APPEARING = 2;
+
+    /**
+     * A flag indicating the animation that runs on those items that are changing
+     * due to a new item appearing in the container.
+     */
+    public static final int DISAPPEARING = 3;
+
+    /**
+     * These variables hold the animations that are currently used to run the transition effects.
+     * These animations are set to defaults, but can be changed to custom animations by
+     * calls to setAnimatable().
+     */
+    private Animatable mDisappearingAnim = null;
+    private Animatable mAppearingAnim = null;
+    private Animatable mChangingAppearingAnim = null;
+    private Animatable mChangingDisappearingAnim = null;
+
+    /**
+     * These are the default animations, defined in the constructor, that will be used
+     * unless the user specifies custom animations.
+     */
+    private static PropertyAnimator defaultChangeIn;
+    private static PropertyAnimator defaultChangeOut;
+    private static PropertyAnimator defaultFadeIn;
+    private static PropertyAnimator defaultFadeOut;
+
+    /**
+     * The default duration used by all animations.
+     */
+    private static long DEFAULT_DURATION = 300;
+
+    /**
+     * The durations of the four different animations
+     */
+    private long mChangingAppearingDuration = DEFAULT_DURATION;
+    private long mChangingDisappearingDuration = DEFAULT_DURATION;
+    private long mAppearingDuration = DEFAULT_DURATION;
+    private long mDisappearingDuration = DEFAULT_DURATION;
+
+    /**
+     * The start delays of the four different animations. Note that the default behavior of
+     * the appearing item is the default duration, since it should wait for the items to move
+     * before fading it. Same for the changing animation when disappearing; it waits for the item
+     * to fade out before moving the other items.
+     */
+    private long mAppearingDelay = DEFAULT_DURATION;
+    private long mDisappearingDelay = 0;
+    private long mChangingAppearingDelay = 0;
+    private long mChangingDisappearingDelay = DEFAULT_DURATION;
+
+    /**
+     * The inter-animation delays used on the two changing animations
+     */
+    private long mChangingAppearingStagger = 0;
+    private long mChangingDisappearingStagger = 0;
+
+    /**
+     * The default interpolators used for the animations
+     */
+    private Interpolator mAppearingInterpolator = new AccelerateDecelerateInterpolator();
+    private Interpolator mDisappearingInterpolator = new AccelerateDecelerateInterpolator();
+    private Interpolator mChangingAppearingInterpolator = new DecelerateInterpolator();
+    private Interpolator mChangingDisappearingInterpolator = new DecelerateInterpolator();
+
+    /**
+     * This hashmap is used to store the animations that are currently running as part of
+     * the transition. The reason for this is that a further layout event should cause
+     * existing animations to stop where they are prior to starting new animations. So
+     * we cache all of the current animations in this map for possible cancellation on
+     * another layout event.
+     */
+    private HashMap<View, Animatable> currentAnimations = new HashMap<View, Animatable>();
+
+    /**
+     * This hashmap is used to track the listeners that have been added to the children of
+     * a container. When a layout change occurs, an animation is created for each View, so that
+     * the pre-layout values can be cached in that animation. Then a listener is added to the
+     * view to see whether the layout changes the bounds of that view. If so, the animation
+     * is set with the final values and then run. If not, the animation is not started. When
+     * the process of setting up and running all appropriate animations is done, we need to
+     * remove these listeners and clear out the map.
+     */
+    private HashMap<View, View.OnLayoutChangeListener> layoutChangeListenerMap =
+            new HashMap<View, View.OnLayoutChangeListener>();
+
+    /**
+     * Used to track the current delay being assigned to successive animations as they are
+     * started. This value is incremented for each new animation, then zeroed before the next
+     * transition begins.
+     */
+    private long staggerDelay;
+
+    /**
+     * The set of listeners that should be notified when APPEARING/DISAPPEARING transitions
+     * start and end.
+     */
+    private ArrayList<TransitionListener> mListeners;
+
+
+    /**
+     * Constructs a LayoutTransition object. By default, the object will listen to layout
+     * events on any ViewGroup that it is set on and will run default animations for each
+     * type of layout event.
+     */
+    public LayoutTransition() {
+        if (defaultChangeIn == null) {
+            // "left" is just a placeholder; we'll put real properties/values in when needed
+            PropertyValuesHolder<Integer> pvhLeft = new PropertyValuesHolder<Integer>("left", 0, 1);
+            PropertyValuesHolder<Integer> pvhTop = new PropertyValuesHolder<Integer>("top", 0, 1);
+            PropertyValuesHolder<Integer> pvhRight = new PropertyValuesHolder<Integer>("right", 0, 1);
+            PropertyValuesHolder<Integer> pvhBottom = new PropertyValuesHolder<Integer>("bottom", 0, 1);
+            defaultChangeIn = new PropertyAnimator<PropertyValuesHolder>(DEFAULT_DURATION, this,
+                    pvhLeft, pvhTop, pvhRight, pvhBottom);
+            defaultChangeIn.setStartDelay(mChangingAppearingDelay);
+            defaultChangeIn.setInterpolator(mChangingAppearingInterpolator);
+            defaultChangeOut = defaultChangeIn.clone();
+            defaultChangeOut.setStartDelay(mChangingDisappearingDelay);
+            defaultChangeOut.setInterpolator(mChangingDisappearingInterpolator);
+            defaultFadeIn =
+                    new PropertyAnimator<Float>(DEFAULT_DURATION, this, "alpha", 0f, 1f);
+            defaultFadeIn.setStartDelay(mAppearingDelay);
+            defaultFadeIn.setInterpolator(mAppearingInterpolator);
+            defaultFadeOut =
+                    new PropertyAnimator<Float>(DEFAULT_DURATION, this, "alpha", 1f, 0f);
+            defaultFadeOut.setStartDelay(mDisappearingDelay);
+            defaultFadeOut.setInterpolator(mDisappearingInterpolator);
+        }
+        mChangingAppearingAnim = defaultChangeIn;
+        mChangingDisappearingAnim = defaultChangeOut;
+        mAppearingAnim = defaultFadeIn;
+        mDisappearingAnim = defaultFadeOut;
+    }
+
+    /**
+     * Sets the duration to be used by all animations of this transition object. If you want to
+     * set the duration of just one of the animations in particular, use the
+     * {@link #setDuration(int, long)} method.
+     *
+     * @param duration The length of time, in milliseconds, that the transition animations
+     * should last.
+     */
+    public void setDuration(long duration) {
+        mChangingAppearingDuration = duration;
+        mChangingDisappearingDuration = duration;
+        mAppearingDuration = duration;
+        mDisappearingDuration = duration;
+    }
+
+    /**
+     * Sets the start delay on one of the animation objects used by this transition. The
+     * <code>transitionType</code> parameter determines the animation whose start delay
+     * is being set.
+     *
+     * @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
+     * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose start
+     * delay is being set.
+     * @param delay The length of time, in milliseconds, to delay before starting the animation.
+     * @see android.animation.Animatable#setStartDelay(long)
+     */
+    public void setStartDelay(int transitionType, long delay) {
+        switch (transitionType) {
+            case CHANGE_APPEARING:
+                mChangingAppearingDelay = delay;
+                break;
+            case CHANGE_DISAPPEARING:
+                mChangingDisappearingDelay = delay;
+                break;
+            case APPEARING:
+                mAppearingDelay = delay;
+                break;
+            case DISAPPEARING:
+                mDisappearingDelay = delay;
+                break;
+        }
+    }
+
+    /**
+     * Gets the start delay on one of the animation objects used by this transition. The
+     * <code>transitionType</code> parameter determines the animation whose start delay
+     * is returned.
+     *
+     * @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
+     * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose start
+     * delay is returned.
+     * @return long The start delay of the specified animation.
+     * @see android.animation.Animatable#getStartDelay()
+     */
+    public long getStartDelay(int transitionType) {
+        switch (transitionType) {
+            case CHANGE_APPEARING:
+                return mChangingAppearingDuration;
+            case CHANGE_DISAPPEARING:
+                return mChangingDisappearingDuration;
+            case APPEARING:
+                return mAppearingDuration;
+            case DISAPPEARING:
+                return mDisappearingDuration;
+        }
+        // shouldn't reach here
+        return 0;
+    }
+
+    /**
+     * Sets the duration on one of the animation objects used by this transition. The
+     * <code>transitionType</code> parameter determines the animation whose duration
+     * is being set.
+     *
+     * @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
+     * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
+     * duration is being set.
+     * @param duration The length of time, in milliseconds, that the specified animation should run.
+     * @see android.animation.Animatable#setDuration(long)
+     */
+    public void setDuration(int transitionType, long duration) {
+        switch (transitionType) {
+            case CHANGE_APPEARING:
+                mChangingAppearingDuration = duration;
+                break;
+            case CHANGE_DISAPPEARING:
+                mChangingDisappearingDuration = duration;
+                break;
+            case APPEARING:
+                mAppearingDuration = duration;
+                break;
+            case DISAPPEARING:
+                mDisappearingDuration = duration;
+                break;
+        }
+    }
+
+    /**
+     * Gets the duration on one of the animation objects used by this transition. The
+     * <code>transitionType</code> parameter determines the animation whose duration
+     * is returned.
+     *
+     * @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
+     * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
+     * duration is returned.
+     * @return long The duration of the specified animation.
+     * @see android.animation.Animatable#getDuration()
+     */
+    public long getDuration(int transitionType) {
+        switch (transitionType) {
+            case CHANGE_APPEARING:
+                return mChangingAppearingDuration;
+            case CHANGE_DISAPPEARING:
+                return mChangingDisappearingDuration;
+            case APPEARING:
+                return mAppearingDuration;
+            case DISAPPEARING:
+                return mDisappearingDuration;
+        }
+        // shouldn't reach here
+        return 0;
+    }
+
+    /**
+     * Sets the length of time to delay between starting each animation during one of the
+     * CHANGE animations.
+     *
+     * @param transitionType A value of {@link #CHANGE_APPEARING} or @link #CHANGE_DISAPPEARING}.
+     * @param duration The length of time, in milliseconds, to delay before launching the next
+     * animation in the sequence.
+     */
+    public void setStagger(int transitionType, long duration) {
+        switch (transitionType) {
+            case CHANGE_APPEARING:
+                mChangingAppearingStagger = duration;
+                break;
+            case CHANGE_DISAPPEARING:
+                mChangingDisappearingStagger = duration;
+                break;
+            // noop other cases
+        }
+    }
+
+    /**
+     * Tets the length of time to delay between starting each animation during one of the
+     * CHANGE animations.
+     *
+     * @param transitionType A value of {@link #CHANGE_APPEARING} or @link #CHANGE_DISAPPEARING}.
+     * @return long The length of time, in milliseconds, to delay before launching the next
+     * animation in the sequence.
+     */
+    public long getStagger(int transitionType) {
+        switch (transitionType) {
+            case CHANGE_APPEARING:
+                return mChangingAppearingStagger;
+            case CHANGE_DISAPPEARING:
+                return mChangingDisappearingStagger;
+        }
+        // shouldn't reach here
+        return 0;
+    }
+
+    /**
+     * Sets the interpolator on one of the animation objects used by this transition. The
+     * <code>transitionType</code> parameter determines the animation whose interpolator
+     * is being set.
+     *
+     * @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
+     * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
+     * duration is being set.
+     * @param interpolator The interpolator that the specified animation should use.
+     * @see android.animation.Animatable#setInterpolator(android.view.animation.Interpolator)
+     */
+    public void setInterpolator(int transitionType, Interpolator interpolator) {
+        switch (transitionType) {
+            case CHANGE_APPEARING:
+                mChangingAppearingInterpolator = interpolator;
+                break;
+            case CHANGE_DISAPPEARING:
+                mChangingDisappearingInterpolator = interpolator;
+                break;
+            case APPEARING:
+                mAppearingInterpolator = interpolator;
+                break;
+            case DISAPPEARING:
+                mDisappearingInterpolator = interpolator;
+                break;
+        }
+    }
+
+    /**
+     * Gets the interpolator on one of the animation objects used by this transition. The
+     * <code>transitionType</code> parameter determines the animation whose interpolator
+     * is returned.
+     *
+     * @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
+     * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
+     * duration is being set.
+     * @return Interpolator The interpolator that the specified animation uses.
+     * @see android.animation.Animatable#setInterpolator(android.view.animation.Interpolator)
+     */
+    public Interpolator getInterpolator(int transitionType) {
+        switch (transitionType) {
+            case CHANGE_APPEARING:
+                return mChangingAppearingInterpolator;
+            case CHANGE_DISAPPEARING:
+                return mChangingDisappearingInterpolator;
+            case APPEARING:
+                return mAppearingInterpolator;
+            case DISAPPEARING:
+                return mDisappearingInterpolator;
+        }
+        // shouldn't reach here
+        return null;
+    }
+
+    /**
+     * Sets the animation used during one of the transition types that may run. Any
+     * Animatable object can be used, but to be most useful in the context of layout
+     * transitions, the animation should either be a PropertyAnimator or a Sequencer
+     * of animations including PropertyAnimators. Also, these PropertyAnimator objects
+     * should be able to get and set values on their target objects automatically. For
+     * example, a PropertyAnimator that animates the property "left" is able to set and get the
+     * <code>left</code> property from the View objects being animated by the layout
+     * transition. The transition works by setting target objects and properties
+     * dynamically, according to the pre- and post-layoout values of those objects, so
+     * having animations that can handle those properties appropriately will work best
+     * for custom animation. The dynamic setting of values is only the case for the
+     * CHANGE animations; the APPEARING and DISAPPEARING animations are simply run with
+     * the values they have.
+     *
+     * <p>It is also worth noting that any and all animations (and their underlying
+     * PropertyValuesHolder objects) will have their start and end values set according
+     * to the pre- and post-layout values. So, for example, a custom animation on "alpha"
+     * as the CHANGE_APPEARING animation will inherit the real value of alpha on the target
+     * object (presumably 1) as its starting and ending value when the animation begins.
+     * Animations which need to use values at the beginning and end that may not match the
+     * values queried when the transition begins may need to use a different mechanism
+     * than a standard PropertyAnimator object.</p>
+     *
+     * @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
+     * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
+     * duration is being set.
+     * @param animatable The animation being assigned.
+     */
+    public void setAnimatable(int transitionType, Animatable animatable) {
+        switch (transitionType) {
+            case CHANGE_APPEARING:
+                mChangingAppearingAnim = (animatable != null) ? animatable : defaultChangeIn;
+                break;
+            case CHANGE_DISAPPEARING:
+                mChangingDisappearingAnim = (animatable != null) ? animatable : defaultChangeOut;
+                break;
+            case APPEARING:
+                mAppearingAnim = (animatable != null) ? animatable : defaultFadeIn;
+                break;
+            case DISAPPEARING:
+                mDisappearingAnim = (animatable != null) ? animatable : defaultFadeOut;
+                break;
+        }
+    }
+
+    /**
+     * Gets the animation used during one of the transition types that may run.
+     *
+     * @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
+     * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
+     * duration is being set.
+     * @return Animatable The animation being used for the given transition type.
+     * @see #setAnimatable(int, Animatable)
+     */
+    public Animatable getAnimatable(int transitionType) {
+        switch (transitionType) {
+            case CHANGE_APPEARING:
+                return mChangingAppearingAnim;
+            case CHANGE_DISAPPEARING:
+                return mChangingDisappearingAnim;
+            case APPEARING:
+                return mAppearingAnim;
+            case DISAPPEARING:
+                return mDisappearingAnim;
+        }
+        // shouldn't reach here
+        return null;
+    }
+
+    /**
+     * This function sets up runs animations on all of the views that change during layout.
+     * For every child in the parent, we create a change animation of the appropriate
+     * type (appearing or disappearing) and ask it to populate its start values from its
+     * target view. We add layout listeners to all child views and listen for changes. For
+     * those views that change, we populate the end values for those animations and start them.
+     * Animations are not run on unchanging views.
+     *
+     * @param parent The container which is undergoing an appearing or disappearing change.
+     * @param newView The view being added to or removed from the parent.
+     * @param changeReason A value of APPEARING or DISAPPEARING, indicating whether the
+     * transition is occuring because an item is being added to or removed from the parent.
+     */
+    private void runChangeTransition(final ViewGroup parent, View newView, final int changeReason) {
+        // reset the inter-animation delay, in case we use it later
+        staggerDelay = 0;
+
+        final ViewTreeObserver observer = parent.getViewTreeObserver(); // used for later cleanup
+        int numChildren = parent.getChildCount();
+
+        for (int i = 0; i < numChildren; ++i) {
+            final View child = parent.getChildAt(i);
+
+            // only animate the views not being added or removed
+            if (child != newView) {
+
+                // If there's an animation running on this view already, cancel it
+                Animatable currentAnimation = currentAnimations.get(child);
+                if (currentAnimation != null) {
+                    currentAnimation.cancel();
+                    currentAnimations.remove(child);
+                }
+
+                // Make a copy of the appropriate animation
+                final Animatable anim = (changeReason == APPEARING) ?
+                        mChangingAppearingAnim.clone() :
+                        mChangingDisappearingAnim.clone();
+
+                // Set the target object for the animation
+                anim.setTarget(child);
+
+                // A PropertyAnimator (or Sequencer of them) can extract start values from
+                // its target object
+                anim.setupStartValues();
+
+                // Add a listener to track layout changes on this view. If we don't get a callback,
+                // then there's nothing to animate.
+                View.OnLayoutChangeListener listener = new View.OnLayoutChangeListener() {
+                    public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                            int oldLeft, int oldTop, int oldRight, int oldBottom) {
+
+                        // Cache the animation in case we need to cancel it later
+                        currentAnimations.put(child, anim);
+
+                        // Tell the animation to extract end values from the changed object
+                        anim.setupEndValues();
+
+                        long startDelay;
+                        long duration;
+                        if (changeReason == APPEARING) {
+                            startDelay = mChangingAppearingDelay + staggerDelay;
+                            staggerDelay += mChangingAppearingStagger;
+                            duration = mChangingAppearingDuration;
+                        } else {
+                            startDelay = mChangingDisappearingDelay + staggerDelay;
+                            staggerDelay += mChangingDisappearingStagger;
+                            duration = mChangingDisappearingDuration;
+                        }
+                        anim.setStartDelay(startDelay);
+                        anim.setDuration(duration);
+
+                        // Remove the animation from the cache when it ends
+                        anim.addListener(new AnimatableListenerAdapter() {
+                            private boolean canceled = false;
+                            public void onAnimationCancel(Animatable animatable) {
+                                // we remove canceled animations immediately, not here
+                                canceled = true;
+                            }
+                            public void onAnimationEnd(Animatable animatable) {
+                                if (!canceled) {
+                                    currentAnimations.remove(child);
+                                }
+                            }
+                        });
+                        if (anim instanceof PropertyAnimator) {
+                            ((PropertyAnimator) anim).setCurrentPlayTime(0);
+                        }
+                        anim.start();
+
+                        // this only removes listeners whose views changed - must clear the
+                        // other listeners later
+                        child.removeOnLayoutChangeListener(this);
+                        layoutChangeListenerMap.remove(child);
+                    }
+                };
+                child.addOnLayoutChangeListener(listener);
+                // cache the listener for later removal
+                layoutChangeListenerMap.put(child, listener);
+            }
+        }
+        // This is the cleanup step. When we get this rendering event, we know that all of
+        // the appropriate animations have been set up and run. Now we can clear out the
+        // layout listeners.
+        observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            public boolean onPreDraw() {
+                observer.removeOnPreDrawListener(this);
+                int numChildren = parent.getChildCount();
+                for (int i = 0; i < numChildren; ++i) {
+                    final View child = parent.getChildAt(i);
+                    child.removeOnLayoutChangeListener(layoutChangeListenerMap.get(child));
+                }
+                layoutChangeListenerMap.clear();
+                return true;
+            }
+        });
+    }
+
+    /**
+     * This method runs the animation that makes an added item appear.
+     *
+     * @param parent The ViewGroup to which the View is being added.
+     * @param child The View being added to the ViewGroup.
+     */
+    private void runAppearingTransition(final ViewGroup parent, final View child) {
+        Animatable anim = mAppearingAnim.clone();
+        anim.setTarget(child);
+        anim.setStartDelay(mAppearingDelay);
+        anim.setDuration(mAppearingDuration);
+        if (anim instanceof PropertyAnimator) {
+            ((PropertyAnimator) anim).setCurrentPlayTime(0);
+        }
+        if (mListeners != null) {
+            anim.addListener(new AnimatableListenerAdapter() {
+                public void onAnimationEnd() {
+                    for (TransitionListener listener : mListeners) {
+                        listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
+                    }
+                }
+            });
+        }
+        anim.start();
+    }
+
+    /**
+     * This method runs the animation that makes a removed item disappear.
+     *
+     * @param parent The ViewGroup from which the View is being removed.
+     * @param child The View being removed from the ViewGroup.
+     */
+    private void runDisappearingTransition(final ViewGroup parent, final View child) {
+        Animatable anim = mDisappearingAnim.clone();
+        anim.setStartDelay(mDisappearingDelay);
+        anim.setDuration(mDisappearingDuration);
+        anim.setTarget(child);
+        if (mListeners != null) {
+            anim.addListener(new AnimatableListenerAdapter() {
+                public void onAnimationEnd() {
+                    for (TransitionListener listener : mListeners) {
+                        listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
+                    }
+                }
+            });
+        }
+        if (anim instanceof PropertyAnimator) {
+            ((PropertyAnimator) anim).setCurrentPlayTime(0);
+        }
+        anim.start();
+    }
+
+    /**
+     * This method is called by ViewGroup when a child view is about to be added to the
+     * container. This callback starts the process of a transition; we grab the starting
+     * values, listen for changes to all of the children of the container, and start appropriate
+     * animations.
+     *
+     * @param parent The ViewGroup to which the View is being added.
+     * @param child The View being added to the ViewGroup.
+     */
+    public void childAdd(ViewGroup parent, View child) {
+        if (mListeners != null) {
+            for (TransitionListener listener : mListeners) {
+                listener.startTransition(this, parent, child, APPEARING);
+            }
+        }
+        runChangeTransition(parent, child, APPEARING);
+        runAppearingTransition(parent, child);
+    }
+
+    /**
+     * This method is called by ViewGroup when a child view is about to be removed from the
+     * container. This callback starts the process of a transition; we grab the starting
+     * values, listen for changes to all of the children of the container, and start appropriate
+     * animations.
+     *
+     * @param parent The ViewGroup from which the View is being removed.
+     * @param child The View being removed from the ViewGroup.
+     */
+    public void childRemove(ViewGroup parent, View child) {
+        if (mListeners != null) {
+            for (TransitionListener listener : mListeners) {
+                listener.startTransition(this, parent, child, DISAPPEARING);
+            }
+        }
+        runChangeTransition(parent, child, DISAPPEARING);
+        runDisappearingTransition(parent, child);
+    }
+
+    /**
+     * Add a listener that will be called when the bounds of the view change due to
+     * layout processing.
+     *
+     * @param listener The listener that will be called when layout bounds change.
+     */
+    public void addTransitionListener(TransitionListener listener) {
+        if (mListeners == null) {
+            mListeners = new ArrayList<TransitionListener>();
+        }
+        mListeners.add(listener);
+    }
+
+    /**
+     * Remove a listener for layout changes.
+     *
+     * @param listener The listener for layout bounds change.
+     */
+    public void removeTransitionListener(TransitionListener listener) {
+        if (mListeners == null) {
+            return;
+        }
+        mListeners.remove(listener);
+    }
+
+    /**
+     * Gets the current list of listeners for layout changes.
+     * @return
+     */
+    public List<TransitionListener> getTransitionListeners() {
+        return mListeners;
+    }
+
+    /**
+     * This interface is used for listening to starting and ending events for transitions.
+     */
+    public interface TransitionListener {
+
+        /**
+         * This event is sent to listeners when an APPEARING or DISAPPEARING transition
+         * begins.
+         *
+         * @param transition The LayoutTransition sending out the event.
+         * @param container The ViewGroup on which the transition is playing.
+         * @param view The View object being added or removed from its parent.
+         * @param transitionType The type of transition that is beginning, either
+         * {@link android.animation.LayoutTransition#APPEARING} or
+         * {@link android.animation.LayoutTransition#DISAPPEARING}.
+         */
+        public void startTransition(LayoutTransition transition, ViewGroup container,
+                View view, int transitionType);
+
+        /**
+         * This event is sent to listeners when an APPEARING or DISAPPEARING transition ends.
+         *
+         * @param transition The LayoutTransition sending out the event.
+         * @param container The ViewGroup on which the transition is playing.
+         * @param view The View object being added or removed from its parent.
+         * @param transitionType The type of transition that is ending, either
+         * {@link android.animation.LayoutTransition#APPEARING} or
+         * {@link android.animation.LayoutTransition#DISAPPEARING}.
+         */
+        public void endTransition(LayoutTransition transition, ViewGroup container,
+                View view, int transitionType);
+    }
+
+}
\ No newline at end of file
diff --git a/core/java/android/animation/PropertyAnimator.java b/core/java/android/animation/PropertyAnimator.java
index 8a6edcc..e555cc6 100644
--- a/core/java/android/animation/PropertyAnimator.java
+++ b/core/java/android/animation/PropertyAnimator.java
@@ -168,10 +168,14 @@
      */
     @Override
     void initAnimation() {
-        super.initAnimation();
-        int numValues = mValues.length;
-        for (int i = 0; i < numValues; ++i) {
-            mValues[i].setupSetterAndGetter(mTarget);
+        if (!mInitialized) {
+            // mValueType may change due to setter/getter setup; do this before calling super.init(),
+            // which uses mValueType to set up the default type evaluator.
+            int numValues = mValues.length;
+            for (int i = 0; i < numValues; ++i) {
+                mValues[i].setupSetterAndGetter(mTarget);
+            }
+            super.initAnimation();
         }
     }
 
@@ -190,10 +194,29 @@
      *
      * @param target The object being animated
      */
+    @Override
     public void setTarget(Object target) {
         mTarget = target;
     }
 
+    @Override
+    public void setupStartValues() {
+        initAnimation();
+        int numValues = mValues.length;
+        for (int i = 0; i < numValues; ++i) {
+            mValues[i].setupStartValue(mTarget);
+        }
+    }
+
+    @Override
+    public void setupEndValues() {
+        initAnimation();
+        int numValues = mValues.length;
+        for (int i = 0; i < numValues; ++i) {
+            mValues[i].setupEndValue(mTarget);
+        }
+    }
+
     /**
      * This method is called with the elapsed fraction of the animation during every
      * animation frame. This function turns the elapsed fraction into an interpolated fraction
@@ -216,7 +239,7 @@
     }
 
     @Override
-    public PropertyAnimator clone() throws CloneNotSupportedException {
+    public PropertyAnimator clone() {
         final PropertyAnimator anim = (PropertyAnimator) super.clone();
         return anim;
     }
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index fc829b8..b6ff54e 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -25,8 +25,12 @@
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 /**
+ * This class holds information about a property and the values that that property
+ * should take on during an animation. PropertyValuesHolder objects can be used to create
+ * animations with Animator or PropertyAnimator that operate on several different properties
+ * in parallel.
  */
-public class PropertyValuesHolder<T> {
+public class PropertyValuesHolder<T> implements Cloneable {
 
     /**
      * The name of the property associated with the values. This need not be a real property,
@@ -192,7 +196,7 @@
             }
         } else {
             if (numKeyframes == 1) {
-                keyframes[0] = new Keyframe(0f, null);
+                keyframes[0] = new Keyframe(0f, (Object) null);
                 keyframes[1] = new Keyframe(1f, values[0]);
             } else {
                 keyframes[0] = new Keyframe(0f, values[0]);
@@ -256,6 +260,8 @@
                 args[0] = typeVariant;
                 try {
                     returnVal = targetClass.getMethod(methodName, args);
+                    // change the value type to suit
+                    mValueType = typeVariant;
                     return returnVal;
                 } catch (NoSuchMethodException e) {
                     // Swallow the error and keep trying other variants
@@ -356,6 +362,63 @@
     }
 
     /**
+     * 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.
+     *
+     * @param target The target object from which the current value should be extracted.
+     * @param kf The keyframe which holds the property name and value.
+     */
+    private void setupValue(Object target, Keyframe kf) {
+        try {
+            if (mGetter == null) {
+                Class targetClass = target.getClass();
+                setupGetter(targetClass);
+            }
+            kf.setValue((T) mGetter.invoke(target));
+        } catch (InvocationTargetException e) {
+            Log.e("PropertyValuesHolder", e.toString());
+        } catch (IllegalAccessException e) {
+            Log.e("PropertyValuesHolder", e.toString());
+        }
+    }
+
+    /**
+     * This function is called by PropertyAnimator when setting the start values for an animation.
+     * The start values are set according to the current values in the target object. The
+     * property whose value is extracted is whatever is specified by the propertyName of this
+     * PropertyValuesHolder object.
+     *
+     * @param target The object which holds the start values that should be set.
+     */
+    void setupStartValue(Object target) {
+        setupValue(target, mKeyframeSet.mKeyframes.get(0));
+    }
+
+    /**
+     * This function is called by PropertyAnimator when setting the end values for an animation.
+     * The end values are set according to the current values in the target object. The
+     * property whose value is extracted is whatever is specified by the propertyName of this
+     * PropertyValuesHolder object.
+     *
+     * @param target The object which holds the start values that should be set.
+     */
+    void setupEndValue(Object target) {
+        setupValue(target, mKeyframeSet.mKeyframes.get(mKeyframeSet.mKeyframes.size() - 1));
+    }
+
+    @Override
+    public PropertyValuesHolder clone() {
+        ArrayList<Keyframe> keyframes = mKeyframeSet.mKeyframes;
+        int numKeyframes = mKeyframeSet.mKeyframes.size();
+        Keyframe[] newKeyframes = new Keyframe[numKeyframes];
+        for (int i = 0; i < numKeyframes; ++i) {
+            newKeyframes[i] = keyframes.get(i).clone();
+        }
+        PropertyValuesHolder pvhClone = new PropertyValuesHolder(mPropertyName,
+                (Object[]) newKeyframes);
+        return pvhClone;
+    }
+    /**
      * 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 PropertyAnimator
      * to handle turning the value calculated by Animator into a value set on the object
@@ -381,8 +444,9 @@
      */
     void init() {
         if (mEvaluator == null) {
-            mEvaluator = (mValueType == int.class) ? sIntEvaluator :
-                (mValueType == double.class) ? sDoubleEvaluator : sFloatEvaluator;
+            mEvaluator = (mValueType == int.class || mValueType == Integer.class) ? sIntEvaluator :
+                (mValueType == double.class || mValueType == Double.class) ? sDoubleEvaluator :
+                        sFloatEvaluator;
         }
     }
 
diff --git a/core/java/android/animation/Sequencer.java b/core/java/android/animation/Sequencer.java
index 8779b3d..04bede0 100644
--- a/core/java/android/animation/Sequencer.java
+++ b/core/java/android/animation/Sequencer.java
@@ -20,6 +20,7 @@
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
 import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -96,6 +97,16 @@
      */
     boolean mCanceled = false;
 
+    // The amount of time in ms to delay starting the animation after start() is called
+    private long mStartDelay = 0;
+
+
+    // How long the child animations should last in ms. The default value is negative, which
+    // simply means that there is no duration set on the Sequencer. When a real duration is
+    // set, it is passed along to the child animations.
+    private long mDuration = -1;
+
+
     /**
      * Sets up this Sequencer to play all of the supplied animations at the same time.
      *
@@ -153,6 +164,7 @@
      *
      * @param target The object being animated
      */
+    @Override
     public void setTarget(Object target) {
         for (Node node : mNodes) {
             Animatable animation = node.animation;
@@ -165,6 +177,19 @@
     }
 
     /**
+     * Sets the Interpolator for all current {@link #getChildAnimations() child animations}
+     * of this Sequencer.
+     *
+     * @param interpolator the interpolator to be used by each child animation of this Sequencer
+     */
+    @Override
+    public void setInterpolator(Interpolator interpolator) {
+        for (Node node : mNodes) {
+            node.animation.setInterpolator(interpolator);
+        }
+    }
+
+    /**
      * This method creates a <code>Builder</code> object, which is used to
      * set up playing constraints. This initial <code>play()</code> method
      * tells the <code>Builder</code> the animation that is the dependency for
@@ -266,6 +291,62 @@
     }
 
     /**
+     * The amount of time, in milliseconds, to delay starting the animation after
+     * {@link #start()} is called.
+     *
+     * @return the number of milliseconds to delay running the animation
+     */
+    @Override
+    public long getStartDelay() {
+        return mStartDelay;
+    }
+
+    /**
+     * The amount of time, in milliseconds, to delay starting the animation after
+     * {@link #start()} is called.
+
+     * @param startDelay The amount of the delay, in milliseconds
+     */
+    @Override
+    public void setStartDelay(long startDelay) {
+        mStartDelay = startDelay;
+    }
+
+    /**
+     * Gets the length of each of the child animations of this Sequencer. This value may
+     * be less than 0, which indicates that no duration has been set on this Sequencer
+     * and each of the child animations will use their own duration.
+     *
+     * @return The length of the animation, in milliseconds, of each of the child
+     * animations of this Sequencer.
+     */
+    @Override
+    public long getDuration() {
+        return mDuration;
+    }
+
+    /**
+     * Sets the length of each of the current child animations of this Sequencer. By default,
+     * each child animation will use its own duration. If the duration is set on the Sequencer,
+     * then each child animation inherits this duration.
+     *
+     * @param duration The length of the animation, in milliseconds, of each of the child
+     * animations of this Sequencer.
+     */
+    @Override
+    public void setDuration(long duration) {
+        if (duration < 0) {
+            throw new IllegalArgumentException("duration must be a value of zero or greater");
+        }
+        for (Node node : mNodes) {
+            // TODO: don't set the duration of the timing-only nodes created by Sequencer to
+            // insert "play-after" delays
+            node.animation.setDuration(duration);
+        }
+        mDuration = duration;
+    }
+
+    /**
      * {@inheritDoc}
      *
      * <p>Starting this <code>Sequencer</code> will, in turn, start the animations for which
@@ -285,7 +366,7 @@
         // start the animations in the loop directly because we first need to set up
         // dependencies on all of the nodes. For example, we don't want to start an animation
         // when some other animation also wants to start when the first animation begins.
-        ArrayList<Node> nodesToStart = new ArrayList<Node>();
+        final ArrayList<Node> nodesToStart = new ArrayList<Node>();
         for (Node node : mSortedNodes) {
             if (mSequenceListener == null) {
                 mSequenceListener = new SequencerAnimatableListener(this);
@@ -302,9 +383,22 @@
             node.animation.addListener(mSequenceListener);
         }
         // Now that all dependencies are set up, start the animations that should be started.
-        for (Node node : nodesToStart) {
-            node.animation.start();
-            mPlayingSet.add(node.animation);
+        if (mStartDelay <= 0) {
+            for (Node node : nodesToStart) {
+                node.animation.start();
+                mPlayingSet.add(node.animation);
+            }
+        } else {
+            // TODO: Need to cancel out of the delay appropriately
+            Animator delayAnim = new Animator(mStartDelay, 0f, 1f);
+            delayAnim.addListener(new AnimatableListenerAdapter() {
+                public void onAnimationEnd(Animatable anim) {
+                    for (Node node : nodesToStart) {
+                        node.animation.start();
+                        mPlayingSet.add(node.animation);
+                    }
+                }
+            });
         }
         if (mListeners != null) {
             ArrayList<AnimatableListener> tmpListeners =
@@ -316,7 +410,7 @@
     }
 
     @Override
-    public Sequencer clone() throws CloneNotSupportedException {
+    public Sequencer clone() {
         final Sequencer anim = (Sequencer) super.clone();
         /*
          * The basic clone() operation copies all items. This doesn't work very well for
@@ -688,10 +782,14 @@
         }
 
         @Override
-        public Node clone() throws CloneNotSupportedException {
-            Node node = (Node) super.clone();
-            node.animation = (Animatable) animation.clone();
-            return node;
+        public Node clone() {
+            try {
+                Node node = (Node) super.clone();
+                node.animation = (Animatable) animation.clone();
+                return node;
+            } catch (CloneNotSupportedException e) {
+               throw new AssertionError();
+            }
         }
     }
 
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 3fe971f..068f821 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1751,6 +1751,9 @@
     }
 
     /**
+     * @deprecated This functionality will be removed in the future; please do
+     * not use.
+     *
      * Control whether this activity is required to be persistent.  By default
      * activities are not persistent; setting this to true will prevent the
      * system from stopping this activity or its process when running low on
@@ -1765,6 +1768,7 @@
      *                     persistent, true if so, false for the normal
      *                     behavior.
      */
+    @Deprecated
     public void setPersistent(boolean isPersistent) {
         if (mParent == null) {
             try {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d5741fc..4736404 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -755,14 +755,17 @@
         public String pkgList[];
         
         /**
-         * Constant for {@link #flags}: this is a heavy-weight process,
-         * meaning it will not be killed while in the background.
+         * Constant for {@link #flags}: this is an app that is unable to
+         * correctly save its state when going to the background,
+         * so it can not be killed while in the background.
+         * @hide
          */
-        public static final int FLAG_HEAVY_WEIGHT = 1<<0;
+        public static final int FLAG_CANT_SAVE_STATE = 1<<0;
         
         /**
          * Flags of information.  May be any of
-         * {@link #FLAG_HEAVY_WEIGHT}.
+         * {@link #FLAG_CANT_SAVE_STATE}.
+         * @hide
          */
         public int flags;
         
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4de0b0a..fe179d1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -850,10 +850,6 @@
     }
 
     private final class H extends Handler {
-        private H() {
-            SamplingProfiler.getInstance().setEventThread(mLooper.getThread());
-        }
-
         public static final int LAUNCH_ACTIVITY         = 100;
         public static final int PAUSE_ACTIVITY          = 101;
         public static final int PAUSE_ACTIVITY_FINISHING= 102;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 775c9f2a..18ecc24 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -124,7 +124,6 @@
 import java.util.WeakHashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 class ReceiverRestrictedContext extends ContextWrapper {
     ReceiverRestrictedContext(Context base) {
@@ -1870,6 +1869,21 @@
         }
 
         @Override
+        public ProviderInfo getProviderInfo(ComponentName className, int flags)
+            throws NameNotFoundException {
+            try {
+                ProviderInfo pi = mPM.getProviderInfo(className, flags);
+                if (pi != null) {
+                    return pi;
+                }
+            } catch (RemoteException e) {
+                throw new RuntimeException("Package manager has died", e);
+            }
+
+            throw new NameNotFoundException(className.toString());
+        }
+
+        @Override
         public String[] getSystemSharedLibraryNames() {
              try {
                  return mPM.getSystemSharedLibraryNames();
@@ -2852,8 +2866,6 @@
             private final Map<String, Object> mModified = Maps.newHashMap();
             private boolean mClear = false;
 
-            private AtomicBoolean mCommitInFlight = new AtomicBoolean(false);
-
             public Editor putString(String key, String value) {
                 synchronized (this) {
                     mModified.put(key, value);
@@ -2905,11 +2917,7 @@
                 }
             }
 
-            public void startCommit() {
-                if (!mCommitInFlight.compareAndSet(false, true)) {
-                    throw new IllegalStateException("can't call startCommit() twice");
-                }
-
+            public void apply() {
                 final MemoryCommitResult mcr = commitToMemory();
                 final Runnable awaitCommit = new Runnable() {
                         public void run() {
@@ -2925,7 +2933,6 @@
                 Runnable postWriteRunnable = new Runnable() {
                         public void run() {
                             awaitCommit.run();
-                            mCommitInFlight.set(false);
                             QueuedWork.remove(awaitCommit);
                         }
                     };
@@ -3049,13 +3056,13 @@
          * that they're enqueued.
          *
          * @param postWriteRunnable if non-null, we're being called
-         *   from startCommit() and this is the runnable to run after
+         *   from apply() and this is the runnable to run after
          *   the write proceeds.  if null (from a regular commit()),
          *   then we're allowed to do this disk write on the main
          *   thread (which in addition to reducing allocations and
          *   creating a background thread, this has the advantage that
          *   we catch them in userdebug StrictMode reports to convert
-         *   them where possible to startCommit...)
+         *   them where possible to apply() ...)
          */
         private void enqueueDiskWrite(final MemoryCommitResult mcr,
                                       final Runnable postWriteRunnable) {
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 952765d..9d0b3f2 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -173,9 +173,9 @@
         Log.d(TAG, msg);
     }
 
-    public void setBluetoothTethering(boolean value, String uuid, String bridge) {
+    public void setBluetoothTethering(boolean value) {
         try {
-            mService.setBluetoothTethering(value, uuid, bridge);
+            mService.setBluetoothTethering(value);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index f8f678b..c4a40cd 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -83,7 +83,7 @@
     int getInputDevicePriority(in BluetoothDevice device);
 
     boolean isTetheringOn();
-    void setBluetoothTethering(boolean value, String uuid, String bridge);
+    void setBluetoothTethering(boolean value);
     int getPanDeviceState(in BluetoothDevice device);
     BluetoothDevice[] getConnectedPanDevices();
     boolean connectPanDevice(in BluetoothDevice device);
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index 23ed62c..c0788f5 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -55,13 +55,13 @@
     /**
      * Interface used for modifying values in a {@link SharedPreferences}
      * object.  All changes you make in an editor are batched, and not copied
-     * back to the original {@link SharedPreferences} or persistent storage
-     * until you call {@link #commit}.
+     * back to the original {@link SharedPreferences} until you call {@link #commit}
+     * or {@link #apply}
      */
     public interface Editor {
         /**
          * Set a String value in the preferences editor, to be written back once
-         * {@link #commit} is called.
+         * {@link #commit} or {@link #apply} are called.
          * 
          * @param key The name of the preference to modify.
          * @param value The new value for the preference.
@@ -84,7 +84,7 @@
         
         /**
          * Set an int value in the preferences editor, to be written back once
-         * {@link #commit} is called.
+         * {@link #commit} or {@link #apply} are called.
          * 
          * @param key The name of the preference to modify.
          * @param value The new value for the preference.
@@ -96,7 +96,7 @@
         
         /**
          * Set a long value in the preferences editor, to be written back once
-         * {@link #commit} is called.
+         * {@link #commit} or {@link #apply} are called.
          * 
          * @param key The name of the preference to modify.
          * @param value The new value for the preference.
@@ -108,7 +108,7 @@
         
         /**
          * Set a float value in the preferences editor, to be written back once
-         * {@link #commit} is called.
+         * {@link #commit} or {@link #apply} are called.
          * 
          * @param key The name of the preference to modify.
          * @param value The new value for the preference.
@@ -120,7 +120,7 @@
         
         /**
          * Set a boolean value in the preferences editor, to be written back
-         * once {@link #commit} is called.
+         * once {@link #commit} or {@link #apply} are called.
          * 
          * @param key The name of the preference to modify.
          * @param value The new value for the preference.
@@ -171,7 +171,7 @@
          *
          * <p>If you don't care about the return value and you're
          * using this from your application's main thread, consider
-         * using {@link #startCommit} instead.
+         * using {@link #apply} instead.
          *
          * @return Returns true if the new values were successfully written
          * to persistent storage.
@@ -185,16 +185,16 @@
          * in the SharedPreferences.
          *
          * <p>Note that when two editors are modifying preferences at the same
-         * time, the last one to call commit wins.
+         * time, the last one to call apply wins.
          *
          * <p>Unlike {@link #commit}, which writes its preferences out
-         * to persistent storage synchronously, {@link #startCommit}
+         * to persistent storage synchronously, {@link #apply}
          * commits its changes to the in-memory
          * {@link SharedPreferences} immediately but starts an
          * asynchronous commit to disk and you won't be notified of
          * any failures.  If another editor on this
          * {@link SharedPreferences} does a regular {@link #commit}
-         * while a {@link #startCommit} is still outstanding, the
+         * while a {@link #apply} is still outstanding, the
          * {@link #commit} will block until all async commits are
          * completed as well as the commit itself.
          *
@@ -202,7 +202,7 @@
          * the base class will wait for any async commits to finish in
          * its {@link android.app.Activity#onPause}.</p>
          */
-        void startCommit();
+        void apply();
     }
 
     /**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 160a481..4cff3bb 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -68,6 +68,8 @@
 
     ServiceInfo getServiceInfo(in ComponentName className, int flags);
 
+    ProviderInfo getProviderInfo(in ComponentName className, int flags);
+
     int checkPermission(String permName, String pkgName);
     
     int checkUidPermission(String permName, int uid);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b14555a..8963d0c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -705,10 +705,11 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
-     * {@link #hasSystemFeature}: The device includes a magnetometer (compass).
+     * {@link #hasSystemFeature}: The device can communicate using Near-Field
+     * Communications (NFC).
      */
     @SdkConstant(SdkConstantType.FEATURE)
-    public static final String FEATURE_SENSOR_COMPASS = "android.hardware.sensor.compass";
+    public static final String FEATURE_NFC = "android.hardware.nfc";
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
@@ -719,6 +720,28 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device includes a barometer (air
+     * pressure sensor.)
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_SENSOR_BAROMETER = "android.hardware.sensor.barometer";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device includes a magnetometer (compass).
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_SENSOR_COMPASS = "android.hardware.sensor.compass";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device includes a gyroscope.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_SENSOR_GYROSCOPE = "android.hardware.sensor.gyroscope";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device includes a light sensor.
      */
     @SdkConstant(SdkConstantType.FEATURE)
@@ -752,7 +775,21 @@
      */
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
-    
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The SIP API is enabled on the device.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_SIP = "android.software.sip";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports SIP-based VOIP.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_SIP_VOIP = "android.software.sip.voip";
+
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device's display has a touch screen.
@@ -779,6 +816,15 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device's touch screen is capable of
+     * tracking a full hand of fingers fully independently -- that is, 5 or
+     * more simultaneous independent pointers.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND = "android.hardware.touchscreen.multitouch.jazzhand";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device supports live wallpapers.
      */
     @SdkConstant(SdkConstantType.FEATURE)
@@ -996,9 +1042,9 @@
      * <p>Throws {@link NameNotFoundException} if an activity with the given
      * class name can not be found on the system.
      *
-     * @param className The full name (i.e.
-     *                  com.google.apps.contacts.ContactsList) of an Activity
-     *                  class.
+     * @param component The full component name (i.e.
+     * com.google.apps.contacts/com.google.apps.contacts.ContactsList) of an Activity
+     * class.
      * @param flags Additional option flags. Use any combination of 
      * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
      * to modify the data (in ApplicationInfo) returned.
@@ -1009,7 +1055,7 @@
      * @see #GET_META_DATA
      * @see #GET_SHARED_LIBRARY_FILES
      */
-    public abstract ActivityInfo getActivityInfo(ComponentName className,
+    public abstract ActivityInfo getActivityInfo(ComponentName component,
             int flags) throws NameNotFoundException;
 
     /**
@@ -1019,9 +1065,9 @@
      * <p>Throws {@link NameNotFoundException} if a receiver with the given
      * class name can not be found on the system.
      *
-     * @param className The full name (i.e.
-     *                  com.google.apps.contacts.CalendarAlarm) of a Receiver
-     *                  class.
+     * @param component The full component name (i.e.
+     * com.google.apps.calendar/com.google.apps.calendar.CalendarAlarm) of a Receiver
+     * class.
      * @param flags Additional option flags.  Use any combination of 
      * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
      * to modify the data returned.
@@ -1032,7 +1078,7 @@
      * @see #GET_META_DATA
      * @see #GET_SHARED_LIBRARY_FILES
      */
-    public abstract ActivityInfo getReceiverInfo(ComponentName className,
+    public abstract ActivityInfo getReceiverInfo(ComponentName component,
             int flags) throws NameNotFoundException;
 
     /**
@@ -1042,9 +1088,9 @@
      * <p>Throws {@link NameNotFoundException} if a service with the given
      * class name can not be found on the system.
      *
-     * @param className The full name (i.e.
-     *                  com.google.apps.media.BackgroundPlayback) of a Service
-     *                  class.
+     * @param component The full component name (i.e.
+     * com.google.apps.media/com.google.apps.media.BackgroundPlayback) of a Service
+     * class.
      * @param flags Additional option flags.  Use any combination of 
      * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
      * to modify the data returned.
@@ -1054,7 +1100,29 @@
      * @see #GET_META_DATA
      * @see #GET_SHARED_LIBRARY_FILES
      */
-    public abstract ServiceInfo getServiceInfo(ComponentName className,
+    public abstract ServiceInfo getServiceInfo(ComponentName component,
+            int flags) throws NameNotFoundException;
+
+    /**
+     * Retrieve all of the information we know about a particular content
+     * provider class.
+     *
+     * <p>Throws {@link NameNotFoundException} if a provider with the given
+     * class name can not be found on the system.
+     *
+     * @param component The full component name (i.e.
+     * com.google.providers.media/com.google.providers.media.MediaProvider) of a
+     * ContentProvider class.
+     * @param flags Additional option flags.  Use any combination of
+     * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
+     * to modify the data returned.
+     *
+     * @return ProviderInfo containing information about the service.
+     *
+     * @see #GET_META_DATA
+     * @see #GET_SHARED_LIBRARY_FILES
+     */
+    public abstract ProviderInfo getProviderInfo(ComponentName component,
             int flags) throws NameNotFoundException;
 
     /**
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 38d6526..90bb0e2 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -769,8 +769,8 @@
      */
     public static void cursorStringToContentValuesIfPresent(Cursor cursor, ContentValues values,
             String column) {
-        final int index = cursor.getColumnIndexOrThrow(column);
-        if (!cursor.isNull(index)) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
             values.put(column, cursor.getString(index));
         }
     }
@@ -785,8 +785,8 @@
      */
     public static void cursorLongToContentValuesIfPresent(Cursor cursor, ContentValues values,
             String column) {
-        final int index = cursor.getColumnIndexOrThrow(column);
-        if (!cursor.isNull(index)) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
             values.put(column, cursor.getLong(index));
         }
     }
@@ -801,8 +801,8 @@
      */
     public static void cursorShortToContentValuesIfPresent(Cursor cursor, ContentValues values,
             String column) {
-        final int index = cursor.getColumnIndexOrThrow(column);
-        if (!cursor.isNull(index)) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
             values.put(column, cursor.getShort(index));
         }
     }
@@ -817,8 +817,8 @@
      */
     public static void cursorIntToContentValuesIfPresent(Cursor cursor, ContentValues values,
             String column) {
-        final int index = cursor.getColumnIndexOrThrow(column);
-        if (!cursor.isNull(index)) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
             values.put(column, cursor.getInt(index));
         }
     }
@@ -833,8 +833,8 @@
      */
     public static void cursorFloatToContentValuesIfPresent(Cursor cursor, ContentValues values,
             String column) {
-        final int index = cursor.getColumnIndexOrThrow(column);
-        if (!cursor.isNull(index)) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
             values.put(column, cursor.getFloat(index));
         }
     }
@@ -849,8 +849,8 @@
      */
     public static void cursorDoubleToContentValuesIfPresent(Cursor cursor, ContentValues values,
             String column) {
-        final int index = cursor.getColumnIndexOrThrow(column);
-        if (!cursor.isNull(index)) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
             values.put(column, cursor.getDouble(index));
         }
     }
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index b83d5ad..0137ea6 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -39,7 +39,6 @@
 import java.io.File;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -273,7 +272,7 @@
      * invoked.
      *
      * this cache has an upper limit of mMaxSqlCacheSize (settable by calling the method
-     * (@link setMaxSqlCacheSize(int)}).
+     * (@link #setMaxSqlCacheSize(int)}).
      */
     // default statement-cache size per database connection ( = instance of this class)
     private int mMaxSqlCacheSize = 25;
@@ -903,8 +902,7 @@
     public interface CursorFactory {
         /**
          * See
-         * {@link SQLiteCursor#SQLiteCursor(SQLiteDatabase, SQLiteCursorDriver,
-         * String, SQLiteQuery)}.
+         * {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
          */
         public Cursor newCursor(SQLiteDatabase db,
                 SQLiteCursorDriver masterQuery, String editTable,
@@ -2080,7 +2078,7 @@
                  */
                 if (++mCacheFullWarnings == MAX_WARNINGS_ON_CACHESIZE_CONDITION) {
                     Log.w(TAG, "Reached MAX size for compiled-sql statement cache for database " +
-                            getPath() + ". Consider increasing cachesize.");
+                            getPath() + ". Use setMaxSqlCacheSize() to increase cachesize. ");
                 }
             } 
             /* add the given SQLiteCompiledSql compiledStatement to cache.
@@ -2142,7 +2140,7 @@
      *
      * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE})
      * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE} or
-     * > the value set with previous setMaxSqlCacheSize() call.
+     * the value set with previous setMaxSqlCacheSize() call.
      */
     public synchronized void setMaxSqlCacheSize(int cacheSize) {
         if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
@@ -2342,10 +2340,12 @@
 
     /* package */ SQLiteDatabase getDbConnection(String sql) {
         verifyDbIsOpen();
-        // this method should always be called with main database connection handle
-        // NEVER with pooled database connection handle
+        // this method should always be called with main database connection handle.
+        // the only time when it is called with pooled database connection handle is
+        // corruption occurs while trying to open a pooled database connection handle.
+        // in that case, simply return 'this' handle
         if (isPooledConnection()) {
-            throw new IllegalStateException("incorrect database connection handle");
+            return this;
         }
 
         // use the current connection handle if
@@ -2504,12 +2504,18 @@
      */
     public boolean isDatabaseIntegrityOk() {
         verifyDbIsOpen();
-        ArrayList<Pair<String, String>> attachedDbs = getAttachedDbs();
-        if (attachedDbs == null) {
-            throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
-                    "be retrieved. probably because the database is closed");
+        ArrayList<Pair<String, String>> attachedDbs = null;
+        try {
+            attachedDbs = getAttachedDbs();
+            if (attachedDbs == null) {
+                throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
+                        "be retrieved. probably because the database is closed");
+            }
+        } catch (SQLiteException e) {
+            // can't get attachedDb list. do integrity check on the main database
+            attachedDbs = new ArrayList<Pair<String, String>>();
+            attachedDbs.add(new Pair<String, String>("main", this.mPath));
         }
-        boolean isDatabaseCorrupt = false;
         for (int i = 0; i < attachedDbs.size(); i++) {
             Pair<String, String> p = attachedDbs.get(i);
             SQLiteStatement prog = null;
@@ -2518,14 +2524,14 @@
                 String rslt = prog.simpleQueryForString();
                 if (!rslt.equalsIgnoreCase("ok")) {
                     // integrity_checker failed on main or attached databases
-                    isDatabaseCorrupt = true;
                     Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
+                    return false;
                 }
             } finally {
                 if (prog != null) prog.close();
             }
         }
-        return isDatabaseCorrupt;
+        return true;
     }
 
     /**
diff --git a/core/java/android/database/sqlite/SQLiteMisuseException.java b/core/java/android/database/sqlite/SQLiteMisuseException.java
index 685f3ea..546ec08 100644
--- a/core/java/android/database/sqlite/SQLiteMisuseException.java
+++ b/core/java/android/database/sqlite/SQLiteMisuseException.java
@@ -16,6 +16,18 @@
 
 package android.database.sqlite;
 
+/**
+ * This error can occur if the application creates a SQLiteStatement object and allows multiple
+ * threads in the application use it at the same time.
+ * Sqlite returns this error if bind and execute methods on this object occur at the same time
+ * from multiple threads, like so:
+ *     thread # 1: in execute() method of the SQLiteStatement object
+ *     while thread # 2: is in bind..() on the same object.
+ *</p>
+ * FIX this by NEVER sharing the same SQLiteStatement object between threads.
+ * Create a local instance of the SQLiteStatement whenever it is needed, use it and close it ASAP.
+ * NEVER make it globally available.
+ */
 public class SQLiteMisuseException extends SQLiteException {
     public SQLiteMisuseException() {}
 
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 21cb3a8..3cc89e5 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -993,7 +993,6 @@
         private static final String KEY_ZOOM_SUPPORTED = "zoom-supported";
         private static final String KEY_SMOOTH_ZOOM_SUPPORTED = "smooth-zoom-supported";
         private static final String KEY_FOCUS_DISTANCES = "focus-distances";
-        private static final String KEY_METERING_MODE = "metering-mode";
 
         // Parameter key suffix for supported values.
         private static final String SUPPORTED_VALUES_SUFFIX = "-values";
@@ -1203,24 +1202,6 @@
         public static final int FOCUS_DISTANCE_FAR_INDEX = 2;
 
         /**
-         * The camera determines the exposure by giving more weight to the
-         * central part of the scene.
-         */
-        public static final String METERING_MODE_CENTER_WEIGHTED = "center-weighted";
-
-        /**
-         * The camera determines the exposure by averaging the entire scene,
-         * giving no weighting to any particular area.
-         */
-        public static final String METERING_MODE_FRAME_AVERAGE = "frame-average";
-
-        /**
-         * The camera determines the exposure by a very small area of the scene,
-         * typically the center.
-         */
-        public static final String METERING_MODE_SPOT = "spot";
-
-        /**
          * The array index of minimum preview fps for use with {@link
          * #getPreviewFpsRange(int[])} or {@link
          * #getSupportedPreviewFpsRange()}.
@@ -2263,42 +2244,6 @@
             splitFloat(get(KEY_FOCUS_DISTANCES), output);
         }
 
-        /**
-         * Gets the supported metering modes.
-         *
-         * @return a list of supported metering modes. null if metering mode
-         *         setting is not supported.
-         * @see #getMeteringMode()
-         */
-        public List<String> getSupportedMeteringModes() {
-            String str = get(KEY_METERING_MODE + SUPPORTED_VALUES_SUFFIX);
-            return split(str);
-        }
-
-        /**
-         * Gets the current metering mode, which affects how camera determines
-         * exposure.
-         *
-         * @return current metering mode. If the camera does not support
-         *         metering setting, this should return null.
-         * @see #METERING_MODE_CENTER_WEIGHTED
-         * @see #METERING_MODE_FRAME_AVERAGE
-         * @see #METERING_MODE_SPOT
-         */
-        public String getMeteringMode() {
-            return get(KEY_METERING_MODE);
-        }
-
-        /**
-         * Sets the metering mode.
-         *
-         * @param value metering mode.
-         * @see #getMeteringMode()
-         */
-        public void setMeteringMode(String value) {
-            set(KEY_METERING_MODE, value);
-        }
-
         // Splits a comma delimited string to an ArrayList of String.
         // Return null if the passing string is null or the size is 0.
         private ArrayList<String> split(String str) {
diff --git a/core/java/android/hardware/Usb.java b/core/java/android/hardware/Usb.java
index 1028f9f..ebb8296 100644
--- a/core/java/android/hardware/Usb.java
+++ b/core/java/android/hardware/Usb.java
@@ -17,6 +17,10 @@
 
 package android.hardware;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
 /**
  * Class for accessing USB state information.
  * @hide
@@ -114,4 +118,30 @@
      * Used in extras for the {@link #ACTION_USB_CONNECTED} broadcast
      */
     public static final String USB_FUNCTION_DISABLED = "disabled";
+
+    private static File getFunctionEnableFile(String function) {
+        return new File("/sys/class/usb_composite/" + function + "/enable");
+    }
+
+    /**
+     * Returns true if the specified USB function is supported by the kernel.
+     * Note that a USB function maybe supported but disabled.
+     */
+    public static boolean isFunctionSupported(String function) {
+        return getFunctionEnableFile(function).exists();
+    }
+
+    /**
+     * Returns true if the specified USB function is currently enabled.
+     */
+    public static boolean isFunctionEnabled(String function) {
+        try {
+            FileInputStream stream = new FileInputStream(getFunctionEnableFile(function));
+            boolean enabled = (stream.read() == '1');
+            stream.close();
+            return enabled;
+        } catch (IOException e) {
+            return false;
+        }
+    }
 }
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index b7d53e2..22968b0 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -109,6 +109,7 @@
     /**
      * We are always considered to be an input method target.
      */
+    @Override
     public boolean isInputMethodTarget() {
         return true;
     }
@@ -125,7 +126,7 @@
      * highlight and cursor will be displayed.
      */
     @Override public boolean hasWindowFocus() {
-        return this.isEnabled() ? true : false;
+        return this.isEnabled();
     }
 
     /**
@@ -133,7 +134,7 @@
      * highlight and cursor will be displayed.
      */
     @Override public boolean isFocused() {
-        return this.isEnabled() ? true : false;
+        return this.isEnabled();
     }
 
     /**
@@ -141,6 +142,6 @@
      * highlight and cursor will be displayed.
      */
     @Override public boolean hasFocus() {
-        return this.isEnabled() ? true : false;
+        return this.isEnabled();
     }
 }
diff --git a/core/java/android/net/LinkProperties.aidl b/core/java/android/net/LinkProperties.aidl
new file mode 100644
index 0000000..73c7988
--- /dev/null
+++ b/core/java/android/net/LinkProperties.aidl
@@ -0,0 +1,22 @@
+/*
+**
+** Copyright (C) 2009 Qualcomm Innovation Center, Inc.  All Rights Reserved.
+** Copyright (C) 2009 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.net;
+
+parcelable LinkProperties;
+
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
new file mode 100644
index 0000000..24aebfc
--- /dev/null
+++ b/core/java/android/net/LinkProperties.java
@@ -0,0 +1,205 @@
+/*
+ * 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.net;
+
+import android.net.ProxyProperties;
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Describes the properties of a network link.
+ * TODO - consider adding optional fields like Apn and ApnType
+ * @hide
+ */
+public class LinkProperties implements Parcelable {
+
+    private NetworkInterface mIface;
+    private Collection<InetAddress> mAddresses;
+    private Collection<InetAddress> mDnses;
+    private InetAddress mGateway;
+    private ProxyProperties mHttpProxy;
+
+    public LinkProperties() {
+        clear();
+    }
+
+    // copy constructor instead of clone
+    public LinkProperties(LinkProperties source) {
+        if (source != null) {
+            mIface = source.getInterface();
+            mAddresses = source.getAddresses();
+            mDnses = source.getDnses();
+            mGateway = source.getGateway();
+            mHttpProxy = new ProxyProperties(source.getHttpProxy());
+        }
+    }
+
+    public void setInterface(NetworkInterface iface) {
+        mIface = iface;
+    }
+    public NetworkInterface getInterface() {
+        return mIface;
+    }
+    public String getInterfaceName() {
+        return (mIface == null ? null : mIface.getName());
+    }
+
+    public void addAddress(InetAddress address) {
+        mAddresses.add(address);
+    }
+    public Collection<InetAddress> getAddresses() {
+        return Collections.unmodifiableCollection(mAddresses);
+    }
+
+    public void addDns(InetAddress dns) {
+        mDnses.add(dns);
+    }
+    public Collection<InetAddress> getDnses() {
+        return Collections.unmodifiableCollection(mDnses);
+    }
+
+    public void setGateway(InetAddress gateway) {
+        mGateway = gateway;
+    }
+    public InetAddress getGateway() {
+        return mGateway;
+    }
+
+    public void setHttpProxy(ProxyProperties proxy) {
+        mHttpProxy = proxy;
+    }
+    public ProxyProperties getHttpProxy() {
+        return mHttpProxy;
+    }
+
+    public void clear() {
+        mIface = null;
+        mAddresses = new ArrayList<InetAddress>();
+        mDnses = new ArrayList<InetAddress>();
+        mGateway = null;
+        mHttpProxy = null;
+    }
+
+    /**
+     * Implement the Parcelable interface
+     * @hide
+     */
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        String ifaceName = (mIface == null ? "" : "InterfaceName: " + mIface.getName() + " ");
+
+        String ip = "IpAddresses: [";
+        for (InetAddress addr : mAddresses) ip +=  addr.getHostAddress() + ",";
+        ip += "] ";
+
+        String dns = "DnsAddresses: [";
+        for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ",";
+        dns += "] ";
+
+        String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " ");
+        String gateway = (mGateway == null ? "" : "Gateway: " + mGateway.getHostAddress() + " ");
+
+        return ifaceName + ip + gateway + dns + proxy;
+    }
+
+    /**
+     * Implement the Parcelable interface.
+     * @hide
+     */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(getInterfaceName());
+        dest.writeInt(mAddresses.size());
+        //TODO: explore an easy alternative to preserve hostname
+        // without doing a lookup
+        for(InetAddress a : mAddresses) {
+            dest.writeByteArray(a.getAddress());
+        }
+        dest.writeInt(mDnses.size());
+        for(InetAddress d : mDnses) {
+            dest.writeByteArray(d.getAddress());
+        }
+        if (mGateway != null) {
+            dest.writeByte((byte)1);
+            dest.writeByteArray(mGateway.getAddress());
+        } else {
+            dest.writeByte((byte)0);
+        }
+        if (mHttpProxy != null) {
+            dest.writeByte((byte)1);
+            dest.writeParcelable(mHttpProxy, flags);
+        } else {
+            dest.writeByte((byte)0);
+        }
+    }
+
+    /**
+     * Implement the Parcelable interface.
+     * @hide
+     */
+    public static final Creator<LinkProperties> CREATOR =
+        new Creator<LinkProperties>() {
+            public LinkProperties createFromParcel(Parcel in) {
+                LinkProperties netProp = new LinkProperties();
+                String iface = in.readString();
+                if (iface != null) {
+                    try {
+                        netProp.setInterface(NetworkInterface.getByName(iface));
+                    } catch (Exception e) {
+                        return null;
+                    }
+                }
+                int addressCount = in.readInt();
+                for (int i=0; i<addressCount; i++) {
+                    try {
+                        netProp.addAddress(InetAddress.getByAddress(in.createByteArray()));
+                    } catch (UnknownHostException e) { }
+                }
+                addressCount = in.readInt();
+                for (int i=0; i<addressCount; i++) {
+                    try {
+                        netProp.addDns(InetAddress.getByAddress(in.createByteArray()));
+                    } catch (UnknownHostException e) { }
+                }
+                if (in.readByte() == 1) {
+                    try {
+                        netProp.setGateway(InetAddress.getByAddress(in.createByteArray()));
+                    } catch (UnknownHostException e) {}
+                }
+                if (in.readByte() == 1) {
+                    netProp.setHttpProxy((ProxyProperties)in.readParcelable(null));
+                }
+                return netProp;
+            }
+
+            public LinkProperties[] newArray(int size) {
+                return new LinkProperties[size];
+            }
+        };
+}
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 6dfd3bc..63bdf8d 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -16,8 +16,6 @@
 
 package android.net;
 
-import java.net.InetAddress;
-
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -32,7 +30,7 @@
 import com.android.internal.telephony.TelephonyIntents;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkInfo;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 import android.text.TextUtils;
@@ -58,7 +56,7 @@
     private boolean mTeardownRequested = false;
     private Handler mTarget;
     private Context mContext;
-    private NetworkProperties mNetworkProperties;
+    private LinkProperties mLinkProperties;
     private boolean mPrivateDnsRouteSet = false;
     private int mDefaultGatewayAddr = 0;
     private boolean mDefaultRouteSet = false;
@@ -107,10 +105,9 @@
         mTarget = target;
         mContext = context;
 
-        IntentFilter filter =
-                new IntentFilter(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
-        filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
 
         mContext.registerReceiver(new MobileDataStateReceiver(), filter);
         mMobileDataState = Phone.DataState.DISCONNECTED;
@@ -162,7 +159,6 @@
             if (intent.getAction().equals(TelephonyIntents.
                     ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
                 String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY);
-
                 if (!TextUtils.equals(apnType, mApnType)) {
                     return;
                 }
@@ -171,9 +167,8 @@
                 String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY);
                 String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
 
-                boolean unavailable = intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY,
-                        false);
-                mNetworkInfo.setIsAvailable(!unavailable);
+                mNetworkInfo.setIsAvailable(!intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY,
+                        false));
 
                 if (DBG) Log.d(TAG, mApnType + " Received state= " + state + ", old= " +
                         mMobileDataState + ", reason= " +
@@ -196,7 +191,7 @@
                                     ConnectivityManager.TYPE_MOBILE);
                                 if (mConnectivityManager == null) {
                                     IBinder b = ServiceManager.getService(
-                                            mContext.CONNECTIVITY_SERVICE);
+                                            Context.CONNECTIVITY_SERVICE);
                                     mConnectivityManager = IConnectivityManager.Stub.asInterface(b);
                                 }
                                 try {
@@ -213,8 +208,8 @@
                                             + e);
                                 }
                             }
-                            if (doReset && mNetworkProperties != null) {
-                                String iface = mNetworkProperties.getInterfaceName();
+                            if (doReset && mLinkProperties != null) {
+                                String iface = mLinkProperties.getInterfaceName();
                                 if (iface != null) NetworkUtils.resetConnections(iface);
                             }
                             // TODO - check this
@@ -233,11 +228,11 @@
                             setDetailedState(DetailedState.SUSPENDED, reason, apnName);
                             break;
                         case CONNECTED:
-                            mNetworkProperties = intent.getParcelableExtra(
-                                    Phone.DATA_NETWORK_PROPERTIES_KEY);
-                            if (mNetworkProperties == null) {
+                            mLinkProperties = intent.getParcelableExtra(
+                                    Phone.DATA_LINK_PROPERTIES_KEY);
+                            if (mLinkProperties == null) {
                                 Log.d(TAG,
-                                        "CONNECTED event did not supply network properties.");
+                                        "CONNECTED event did not supply link properties.");
                             }
                             setDetailedState(DetailedState.CONNECTED, reason, apnName);
                             break;
@@ -255,7 +250,6 @@
                         " broadcast" + reason == null ? "" : "(" + reason + ")");
                 setDetailedState(DetailedState.FAILED, reason, apnName);
             }
-            TelephonyManager tm = TelephonyManager.getDefault();
         }
     }
 
@@ -269,33 +263,7 @@
      * Report whether data connectivity is possible.
      */
     public boolean isAvailable() {
-        getPhoneService(false);
-
-        /*
-         * If the phone process has crashed in the past, we'll get a
-         * RemoteException and need to re-reference the service.
-         */
-        for (int retry = 0; retry < 2; retry++) {
-            if (mPhoneService == null) break;
-
-            try {
-                return mPhoneService.isDataConnectivityPossible();
-            } catch (RemoteException e) {
-                // First-time failed, get the phone service again
-                if (retry == 0) getPhoneService(true);
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     * The mobile data network subtype indicates what generation network technology is in effect,
-     * e.g., GPRS, EDGE, UMTS, etc.
-     */
-    public int getNetworkSubtype() {
-        return TelephonyManager.getDefault().getNetworkType();
+        return mNetworkInfo.isAvailable();
     }
 
     /**
@@ -359,16 +327,6 @@
      * change from the previous state, send a notification to
      * any listeners.
      * @param state the new @{code DetailedState}
-     */
-    private void setDetailedState(NetworkInfo.DetailedState state) {
-        setDetailedState(state, null, null);
-    }
-
-    /**
-     * Record the detailed state of a network, and if it is a
-     * change from the previous state, send a notification to
-     * any listeners.
-     * @param state the new @{code DetailedState}
      * @param reason a {@code String} indicating a reason for the state change,
      * if one was supplied. May be {@code null}.
      * @param extraInfo optional {@code String} providing extra information about the state change
@@ -393,10 +351,6 @@
         }
     }
 
-    private void setDetailedStateInternal(NetworkInfo.DetailedState state) {
-        mNetworkInfo.setDetailedState(state, null, null);
-    }
-
     public void setTeardownRequested(boolean isRequested) {
         mTeardownRequested = isRequested;
     }
@@ -563,7 +517,7 @@
         }
     }
 
-    public NetworkProperties getNetworkProperties() {
-        return mNetworkProperties;
+    public LinkProperties getLinkProperties() {
+        return new LinkProperties(mLinkProperties);
     }
 }
diff --git a/core/java/android/net/NetworkProperties.aidl b/core/java/android/net/NetworkProperties.aidl
deleted file mode 100644
index 07aac6e..0000000
--- a/core/java/android/net/NetworkProperties.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-**
-** Copyright (C) 2009 Qualcomm Innovation Center, Inc.  All Rights Reserved.
-** Copyright (C) 2009 The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.net;
-
-parcelable NetworkProperties;
-
diff --git a/core/java/android/net/NetworkProperties.java b/core/java/android/net/NetworkProperties.java
deleted file mode 100644
index 03c0a2e..0000000
--- a/core/java/android/net/NetworkProperties.java
+++ /dev/null
@@ -1,193 +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.net;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-import android.util.Log;
-
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Describes the properties of a network interface or single address
- * of an interface.
- * TODO - consider adding optional fields like Apn and ApnType
- * @hide
- */
-public class NetworkProperties implements Parcelable {
-
-    private NetworkInterface mIface;
-    private Collection<InetAddress> mAddresses;
-    private Collection<InetAddress> mDnses;
-    private InetAddress mGateway;
-    private ProxyProperties mHttpProxy;
-
-    public NetworkProperties() {
-        clear();
-    }
-
-    public synchronized void setInterface(NetworkInterface iface) {
-        mIface = iface;
-    }
-    public synchronized NetworkInterface getInterface() {
-        return mIface;
-    }
-    public synchronized String getInterfaceName() {
-        return (mIface == null ? null : mIface.getName());
-    }
-
-    public synchronized void addAddress(InetAddress address) {
-        mAddresses.add(address);
-    }
-    public synchronized Collection<InetAddress> getAddresses() {
-        return mAddresses;
-    }
-
-    public synchronized void addDns(InetAddress dns) {
-        mDnses.add(dns);
-    }
-    public synchronized Collection<InetAddress> getDnses() {
-        return mDnses;
-    }
-
-    public synchronized void setGateway(InetAddress gateway) {
-        mGateway = gateway;
-    }
-    public synchronized InetAddress getGateway() {
-        return mGateway;
-    }
-
-    public synchronized void setHttpProxy(ProxyProperties proxy) {
-        mHttpProxy = proxy;
-    }
-    public synchronized ProxyProperties getHttpProxy() {
-        return mHttpProxy;
-    }
-
-    public synchronized void clear() {
-        mIface = null;
-        mAddresses = new ArrayList<InetAddress>();
-        mDnses = new ArrayList<InetAddress>();
-        mGateway = null;
-        mHttpProxy = null;
-    }
-
-    /**
-     * Implement the Parcelable interface
-     * @hide
-     */
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public synchronized String toString() {
-        String ifaceName = (mIface == null ? "" : "InterfaceName: " + mIface.getName() + " ");
-
-        String ip = "IpAddresses: [";
-        for (InetAddress addr : mAddresses) ip +=  addr.getHostAddress() + ",";
-        ip += "] ";
-
-        String dns = "DnsAddresses: [";
-        for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ",";
-        dns += "] ";
-
-        String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " ");
-        String gateway = (mGateway == null ? "" : "Gateway: " + mGateway.getHostAddress() + " ");
-
-        return ifaceName + ip + gateway + dns + proxy;
-    }
-
-    /**
-     * Implement the Parcelable interface.
-     * @hide
-     */
-    public synchronized void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(getInterfaceName());
-        dest.writeInt(mAddresses.size());
-        //TODO: explore an easy alternative to preserve hostname
-        // without doing a lookup
-        for(InetAddress a : mAddresses) {
-            dest.writeByteArray(a.getAddress());
-        }
-        dest.writeInt(mDnses.size());
-        for(InetAddress d : mDnses) {
-            dest.writeByteArray(d.getAddress());
-        }
-        if (mGateway != null) {
-            dest.writeByte((byte)1);
-            dest.writeByteArray(mGateway.getAddress());
-        } else {
-            dest.writeByte((byte)0);
-        }
-        if (mHttpProxy != null) {
-            dest.writeByte((byte)1);
-            dest.writeParcelable(mHttpProxy, flags);
-        } else {
-            dest.writeByte((byte)0);
-        }
-    }
-
-    /**
-     * Implement the Parcelable interface.
-     * @hide
-     */
-    public static final Creator<NetworkProperties> CREATOR =
-        new Creator<NetworkProperties>() {
-            public NetworkProperties createFromParcel(Parcel in) {
-                NetworkProperties netProp = new NetworkProperties();
-                String iface = in.readString();
-                if (iface != null) {
-                    try {
-                        netProp.setInterface(NetworkInterface.getByName(iface));
-                    } catch (Exception e) {
-                        return null;
-                    }
-                }
-                int addressCount = in.readInt();
-                for (int i=0; i<addressCount; i++) {
-                    try {
-                        netProp.addAddress(InetAddress.getByAddress(in.createByteArray()));
-                    } catch (UnknownHostException e) { }
-                }
-                addressCount = in.readInt();
-                for (int i=0; i<addressCount; i++) {
-                    try {
-                        netProp.addDns(InetAddress.getByAddress(in.createByteArray()));
-                    } catch (UnknownHostException e) { }
-                }
-                if (in.readByte() == 1) {
-                    try {
-                        netProp.setGateway(InetAddress.getByAddress(in.createByteArray()));
-                    } catch (UnknownHostException e) {}
-                }
-                if (in.readByte() == 1) {
-                    netProp.setHttpProxy((ProxyProperties)in.readParcelable(null));
-                }
-                return netProp;
-            }
-
-            public NetworkProperties[] newArray(int size) {
-                return new NetworkProperties[size];
-            }
-        };
-}
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 0048a2e..420992b 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -91,9 +91,9 @@
     public NetworkInfo getNetworkInfo();
 
     /**
-     * Fetch NetworkProperties for the network
+     * Fetch LinkProperties for the network
      */
-    public NetworkProperties getNetworkProperties();
+    public LinkProperties getLinkProperties();
 
     /**
      * Return the system properties name associated with the tcp buffer sizes
diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java
index 207fb51..bce7ec0 100644
--- a/core/java/android/net/ProxyProperties.java
+++ b/core/java/android/net/ProxyProperties.java
@@ -36,32 +36,51 @@
     public ProxyProperties() {
     }
 
-    public synchronized InetAddress getAddress() {
+    // copy constructor instead of clone
+    public ProxyProperties(ProxyProperties source) {
+        if (source != null) {
+            mProxy = source.getAddress();
+            mPort = source.getPort();
+            String exclusionList = source.getExclusionList();
+            if (exclusionList != null) {
+                mExclusionList = new String(exclusionList);
+            }
+        }
+    }
+
+    public InetAddress getAddress() {
         return mProxy;
     }
-    public synchronized void setAddress(InetAddress proxy) {
+
+    public void setAddress(InetAddress proxy) {
         mProxy = proxy;
     }
 
-    public synchronized int getPort() {
+    public int getPort() {
         return mPort;
     }
-    public synchronized void setPort(int port) {
+
+    public void setPort(int port) {
         mPort = port;
     }
 
-    public synchronized String getExclusionList() {
+    public String getExclusionList() {
         return mExclusionList;
     }
-    public synchronized void setExclusionList(String exclusionList) {
+
+    public void setExclusionList(String exclusionList) {
         mExclusionList = exclusionList;
     }
 
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append(mProxy.getHostAddress()).append(":").append(mPort)
-          .append(" xl=").append(mExclusionList);
+        if (mProxy != null) {
+            sb.append(mProxy.getHostAddress()).append(":").append(mPort);
+            if (mExclusionList != null) {
+                    sb.append(" xl=").append(mExclusionList);
+            }
+        }
         return sb.toString();
     }
 
@@ -77,7 +96,7 @@
      * Implement the Parcelable interface.
      * @hide
      */
-    public synchronized void writeToParcel(Parcel dest, int flags) {
+    public void writeToParcel(Parcel dest, int flags) {
         if (mProxy != null) {
             dest.writeByte((byte)1);
             dest.writeString(mProxy.getHostName());
@@ -112,5 +131,4 @@
                 return new ProxyProperties[size];
             }
         };
-
-};
+}
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 418fe10..17b2e82 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -1242,7 +1242,7 @@
 
     private void tryCommit(SharedPreferences.Editor editor) {
         if (mPreferenceManager.shouldCommit()) {
-            editor.startCommit();
+            editor.apply();
         }
     }
     
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 4889c19..c28ccd3 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -22,6 +22,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.app.Fragment;
+import android.app.FragmentTransaction;
 import android.app.ListActivity;
 import android.content.Context;
 import android.content.Intent;
@@ -34,12 +35,11 @@
 import android.os.Message;
 import android.text.TextUtils;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.util.Xml;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.View.OnClickListener;
+import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.FrameLayout;
@@ -730,11 +730,26 @@
                 com.android.internal.R.id.prefs, f).commit();
     }
 
+    /**
+     * Start a new fragment.
+     *
+     * @param fragment The fragment to start
+     * @param push If true, the current fragment will be pushed onto the back stack.  If false,
+     * the current fragment will be replaced.
+     */
+    public void startPreferenceFragment(Fragment fragment, boolean push) {
+        FragmentTransaction transaction = getFragmentManager().openTransaction();
+        transaction.replace(com.android.internal.R.id.prefs, fragment);
+        if (push) {
+            transaction.addToBackStack(BACK_STACK_PREFS);
+        }
+        transaction.commit();
+    }
+
     @Override
     public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
         Fragment f = Fragment.instantiate(this, pref.getFragment(), pref.getExtras());
-        getFragmentManager().openTransaction().replace(com.android.internal.R.id.prefs, f)
-                .addToBackStack(BACK_STACK_PREFS).commit();
+        startPreferenceFragment(f, true);
         return true;
     }
 
diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java
index 2b20946..fa83897 100644
--- a/core/java/android/preference/PreferenceManager.java
+++ b/core/java/android/preference/PreferenceManager.java
@@ -443,7 +443,7 @@
             pm.setSharedPreferencesMode(sharedPreferencesMode);
             pm.inflateFromResource(context, resId, null);
 
-            defaultValueSp.edit().putBoolean(KEY_HAS_SET_DEFAULT_VALUES, true).commit();
+            defaultValueSp.edit().putBoolean(KEY_HAS_SET_DEFAULT_VALUES, true).apply();
         }
     }
     
@@ -481,7 +481,7 @@
     
     private void setNoCommit(boolean noCommit) {
         if (!noCommit && mEditor != null) {
-            mEditor.commit();
+            mEditor.apply();
         }
         
         mNoCommit = noCommit;
diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java
index fd9d699..cb6e18f 100644
--- a/core/java/android/provider/Browser.java
+++ b/core/java/android/provider/Browser.java
@@ -27,6 +27,7 @@
 import android.net.Uri;
 import android.provider.BrowserContract.Bookmarks;
 import android.provider.BrowserContract.History;
+import android.provider.BrowserContract.Searches;
 import android.util.Log;
 import android.webkit.WebIconDatabase;
 
@@ -209,7 +210,10 @@
         send.putExtra(Intent.EXTRA_TEXT, stringToSend);
 
         try {
-            c.startActivity(Intent.createChooser(send, chooserDialogTitle));
+            Intent i = Intent.createChooser(send, chooserDialogTitle);
+            // In case this is called from outside an Activity
+            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            c.startActivity(i);
         } catch(android.content.ActivityNotFoundException ex) {
             // if no app handles it, do nothing
         }
@@ -522,29 +526,11 @@
      * @param search    The string to add to the searches database.
      */
     public static final void addSearchUrl(ContentResolver cr, String search) {
-        long now = System.currentTimeMillis();
-        Cursor c = null;
-        try {
-            c = cr.query(
-                SEARCHES_URI,
-                SEARCHES_PROJECTION,
-                SEARCHES_WHERE_CLAUSE,
-                new String [] { search },
-                null);
-            ContentValues map = new ContentValues();
-            map.put(SearchColumns.SEARCH, search);
-            map.put(SearchColumns.DATE, now);
-            /* We should only get one answer that is exactly the same. */
-            if (c.moveToFirst()) {
-                cr.update(SEARCHES_URI, map, "_id = " + c.getInt(0), null);
-            } else {
-                cr.insert(SEARCHES_URI, map);
-            }
-        } catch (IllegalStateException e) {
-            Log.e(LOGTAG, "addSearchUrl", e);
-        } finally {
-            if (c != null) c.close();
-        }
+        // The content provider will take care of updating existing searches instead of duplicating
+        ContentValues values = new ContentValues();
+        values.put(Searches.SEARCH, search);
+        values.put(Searches.DATE, System.currentTimeMillis());
+        cr.insert(Searches.CONTENT_URI, values);
     }
 
     /**
@@ -556,7 +542,7 @@
         // FIXME: Should this clear the urls to which these searches lead?
         // (i.e. remove google.com/query= blah blah blah)
         try {
-            cr.delete(SEARCHES_URI, null, null);
+            cr.delete(Searches.CONTENT_URI, null, null);
         } catch (IllegalStateException e) {
             Log.e(LOGTAG, "clearSearches", e);
         }
@@ -575,8 +561,7 @@
      */
     public static final void requestAllIcons(ContentResolver cr, String where,
             WebIconDatabase.IconListener listener) {
-        WebIconDatabase.getInstance()
-                .bulkRequestIconForPageUrl(cr, where, listener);
+        WebIconDatabase.getInstance().bulkRequestIconForPageUrl(cr, where, listener);
     }
 
     /**
@@ -648,8 +633,7 @@
      */
     public static class SearchColumns implements BaseColumns {
         /**
-         * Not used.
-         * @deprecated
+         * @deprecated Not used.
          */
         @Deprecated
         public static final String URL = "url";
diff --git a/core/java/android/provider/BrowserContract.java b/core/java/android/provider/BrowserContract.java
index 22bbe68..f8a2a13 100644
--- a/core/java/android/provider/BrowserContract.java
+++ b/core/java/android/provider/BrowserContract.java
@@ -77,11 +77,11 @@
         public static final String FOLDER_NAME_BOOKMARKS = "google_chrome_bookmarks";
         public static final String FOLDER_NAME_BOOKMARKS_BAR = "bookmark_bar";
         public static final String FOLDER_NAME_OTHER_BOOKMARKS = "other_bookmarks";
-        
+
         /** The client unique ID for an item */
         public static final String CLIENT_UNIQUE = BaseSyncColumns.SYNC4;
     }
-    
+
     /**
      * Columns that appear when each row of a table belongs to a specific
      * account, including sync information that an account may need.
@@ -120,6 +120,20 @@
          * <P>Type: INTEGER (boolean)</P>
          */
         public static final String DIRTY = "dirty";
+
+        /**
+         * The time that this row was created on its originating client (msecs
+         * since the epoch).
+         * <P>Type: INTEGER</P>
+         */
+        public static final String DATE_CREATED = "created";
+
+        /**
+         * The time that this row was last modified by a client (msecs since the epoch).
+         * <P>Type: INTEGER</P>
+         */
+        public static final String DATE_MODIFIED = "modified";
+
     }
 
     interface BookmarkColumns {
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index d52632b..bf051f5 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -88,6 +88,17 @@
         public static final String NUMBER = "number";
 
         /**
+         * The ISO 3166-1 two letters country code of the country where the
+         * user received or made the call.
+         * <P>
+         * Type: TEXT
+         * </P>
+         *
+         * @hide
+         */
+        public static final String COUNTRY_ISO = "countryiso";
+
+        /**
          * The date the call occured, in milliseconds since the epoch
          * <P>Type: INTEGER (long)</P>
          */
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index b87e0ec..ecd9fe9 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -139,6 +139,12 @@
     public static final String DIRECTORY_PARAM_KEY = "directory";
 
     /**
+     * A query parameter that limits the number of results returned. The
+     * parameter value should be an integer.
+     */
+    public static final String LIMIT_PARAM_KEY = "limit";
+
+    /**
      * @hide
      */
     public static final class Preferences {
@@ -1261,10 +1267,10 @@
         }
 
         /**
-         * Mark a contact as having been contacted.  This updates the
-         * {@link #TIMES_CONTACTED} and {@link #LAST_TIME_CONTACTED} for the
-         * contact, plus the corresponding values of any associated raw
-         * contacts.
+         * Mark a contact as having been contacted. Updates two fields:
+         * {@link #TIMES_CONTACTED} and {@link #LAST_TIME_CONTACTED}. The
+         * TIMES_CONTACTED field is incremented by 1 and the LAST_TIME_CONTACTED
+         * field is populated with the current system time.
          *
          * @param resolver the ContentResolver to use
          * @param contactId the person who was contacted
@@ -1326,7 +1332,8 @@
 
         /**
          * A sub-directory of a single contact that contains all of the constituent raw contact
-         * {@link ContactsContract.Data} rows.
+         * {@link ContactsContract.Data} rows.  This directory can be used either
+         * with a {@link #CONTENT_URI} or {@link #CONTENT_LOOKUP_URI}.
          */
         public static final class Data implements BaseColumns, DataColumns {
             /**
@@ -1417,9 +1424,13 @@
          * </pre>
          *
          * </p>
+         * <p>
+         * This directory can be used either with a {@link #CONTENT_URI} or
+         * {@link #CONTENT_LOOKUP_URI}.
+         * </p>
          */
-        // TODO: add ContactOptionsColumns, ContactStatusColumns
-        public static final class AggregationSuggestions implements BaseColumns, ContactsColumns {
+        public static final class AggregationSuggestions implements BaseColumns, ContactsColumns,
+                ContactOptionsColumns, ContactStatusColumns {
             /**
              * No public constructor since this is a utility class
              */
@@ -1566,9 +1577,12 @@
          * <p>You should also consider using the convenience method
          * {@link ContactsContract.Contacts#openContactPhotoInputStream(ContentResolver, Uri)}
          * </p>
+         * <p>
+         * This directory can be used either with a {@link #CONTENT_URI} or
+         * {@link #CONTENT_LOOKUP_URI}.
+         * </p>
          */
-        // TODO: change DataColumns to DataColumnsWithJoins
-        public static final class Photo implements BaseColumns, DataColumns {
+        public static final class Photo implements BaseColumns, DataColumnsWithJoins {
             /**
              * no public constructor since this is a utility class
              */
@@ -1592,7 +1606,10 @@
          * Opens an InputStream for the contacts's default photo and returns the
          * photo as a byte stream. If there is not photo null will be returned.
          *
-         * @param contactUri the contact whose photo should be used
+         * @param contactUri the contact whose photo should be used. This can be used with
+         * either a {@link #CONTENT_URI} or a {@link #CONTENT_LOOKUP_URI} URI.
+         * </p>
+
          * @return an InputStream of the photo, or null if no photo is present
          */
         public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri contactUri) {
@@ -2072,10 +2089,10 @@
         public static final int AGGREGATION_MODE_DEFAULT = 0;
 
         /**
-         * Do not use.
-         *
-         * TODO: deprecate in favor of {@link #AGGREGATION_MODE_DEFAULT}
+         * Aggregation mode: aggregate at the time the raw contact is inserted/updated.
+         * @deprecated Aggregation is synchronous, this historic value is a no-op
          */
+        @Deprecated
         public static final int AGGREGATION_MODE_IMMEDIATE = 1;
 
         /**
@@ -2143,9 +2160,7 @@
         /**
          * A sub-directory of a single raw contact that contains all of its
          * {@link ContactsContract.Data} rows. To access this directory
-         * append {@link Data#CONTENT_DIRECTORY} to the contact URI.
-         *
-         * TODO: deprecate in favor of {@link RawContacts.Entity}.
+         * append {@link Data#CONTENT_DIRECTORY} to the raw contact URI.
          */
         public static final class Data implements BaseColumns, DataColumns {
             /**
@@ -2164,7 +2179,7 @@
          * <p>
          * A sub-directory of a single raw contact that contains all of its
          * {@link ContactsContract.Data} rows. To access this directory append
-         * {@link #CONTENT_DIRECTORY} to the contact URI. See
+         * {@link RawContacts.Entity#CONTENT_DIRECTORY} to the raw contact URI. See
          * {@link RawContactsEntity} for a stand-alone table containing the same
          * data.
          * </p>
@@ -2176,10 +2191,10 @@
          * null.
          * </p>
          * <p>
-         * Entity reads all
-         * data for a raw contact in one transaction, to guarantee
-         * consistency.
-         * </p>
+         * Using Entity should be preferred to using two separate queries:
+         * RawContacts followed by Data. The reason is that Entity reads all
+         * data for a raw contact in one transaction, so there is no possibility
+         * of the data changing between the two queries.
          */
         public static final class Entity implements BaseColumns, DataColumns {
             /**
@@ -3301,6 +3316,14 @@
          * <P>Type: TEXT</P>
          */
         public static final String LABEL = "label";
+
+        /**
+         * The phone number's E164 representation.
+         * <P>Type: TEXT</P>
+         *
+         * @hide
+         */
+        public static final String NORMALIZED_NUMBER = "normalized_number";
     }
 
     /**
@@ -4153,6 +4176,14 @@
             public static final String NUMBER = DATA;
 
             /**
+             * The phone number's E164 representation.
+             * <P>Type: TEXT</P>
+             *
+             * @hide
+             */
+            public static final String NORMALIZED_NUMBER = DATA4;
+
+            /**
              * @deprecated use {@link #getTypeLabel(Resources, int, CharSequence)} instead.
              * @hide
              */
@@ -4234,7 +4265,7 @@
          * </tr>
          * <tr>
          * <td>String</td>
-         * <td>{@link #DATA}</td>
+         * <td>{@link #ADDRESS}</td>
          * <td>{@link #DATA1}</td>
          * <td>Email address itself.</td>
          * </tr>
diff --git a/core/java/android/provider/DrmStore.java b/core/java/android/provider/DrmStore.java
index c438ac4..34f2f0d 100644
--- a/core/java/android/provider/DrmStore.java
+++ b/core/java/android/provider/DrmStore.java
@@ -131,7 +131,7 @@
      * Utility function for inserting a file stream into the DRM content provider.
      *
      * @param cr The content resolver to use
-     * @param fileStream The FileInputStream to insert
+     * @param fis The FileInputStream to insert
      * @param title The title for the content (or null)
      * @return uri to the DRM record or null
      */
@@ -143,11 +143,11 @@
             DrmRawContent content = new DrmRawContent(fis, (int) fis.available(),
                     DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING);
             String mimeType = content.getContentType();
+            long size = fis.getChannel().size();
 
             DrmRightsManager manager = manager = DrmRightsManager.getInstance();
             DrmRights rights = manager.queryRights(content);
             InputStream stream = content.getContentInputStream(rights);
-            long size = stream.available();
 
             Uri contentUri = null;
             if (mimeType.startsWith("audio/")) {
diff --git a/core/java/android/provider/Mtp.java b/core/java/android/provider/Mtp.java
index 0eb53d1..e25dbad 100644
--- a/core/java/android/provider/Mtp.java
+++ b/core/java/android/provider/Mtp.java
@@ -34,6 +34,14 @@
     private static final String CONTENT_AUTHORITY_SLASH = "content://" + AUTHORITY + "/";
     private static final String CONTENT_AUTHORITY_DEVICE_SLASH = "content://" + AUTHORITY + "/device/";
 
+
+   /**
+     * Broadcast Action:  A broadcast to indicate the end of an MTP session with the host.
+     * This broadcast is only sent if MTP activity has modified the media database during the
+     * most recent MTP session
+     */
+    public static final String ACTION_MTP_SESSION_END = "android.provider.action.MTP_SESSION_END";
+
     /**
      * Contains list of all MTP/PTP devices
      */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6d3ca276..dcd1d94 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1686,6 +1686,47 @@
         public static final String UNLOCK_SOUND = "unlock_sound";
 
         /**
+         * True if we should appear as a PTP device instead of MTP.
+         * @hide
+         */
+        public static final String USE_PTP_INTERFACE = "use_ptp_interface";
+
+        /**
+         * Receive incoming SIP calls?
+         * 0 = no
+         * 1 = yes
+         * @hide
+         */
+        public static final String SIP_RECEIVE_CALLS = "sip_receive_calls";
+
+        /**
+         * Call Preference String.
+         * "SIP_ALWAYS" : Always use SIP with network access
+         * "SIP_ADDRESS_ONLY" : Only if destination is a SIP address
+         * "SIP_ASK_ME_EACH_TIME" : Always ask me each time
+         * @hide
+         */
+        public static final String SIP_CALL_OPTIONS = "sip_call_options";
+
+        /**
+         * One of the sip call options: Always use SIP with network access.
+         * @hide
+         */
+        public static final String SIP_ALWAYS = "SIP_ALWAYS";
+
+        /**
+         * One of the sip call options: Only if destination is a SIP address.
+         * @hide
+         */
+        public static final String SIP_ADDRESS_ONLY = "SIP_ADDRESS_ONLY";
+
+        /**
+         * One of the sip call options: Always ask me each time.
+         * @hide
+         */
+        public static final String SIP_ASK_ME_EACH_TIME = "SIP_ASK_ME_EACH_TIME";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          * @hide
@@ -1745,7 +1786,10 @@
             DOCK_SOUNDS_ENABLED,
             LOCKSCREEN_SOUNDS_ENABLED,
             SHOW_WEB_SUGGESTIONS,
-            NOTIFICATION_LIGHT_PULSE
+            NOTIFICATION_LIGHT_PULSE,
+            USE_PTP_INTERFACE,
+            SIP_CALL_OPTIONS,
+            SIP_RECEIVE_CALLS
         };
 
         // Settings moved to Settings.Secure
@@ -2341,6 +2385,12 @@
         public static final String SET_GLOBAL_HTTP_PROXY = "set_global_http_proxy";
 
         /**
+         * Setting for default DNS in case nobody suggests one
+         * @hide
+         */
+        public static final String DEFAULT_DNS_SERVER = "default_dns_server";
+
+        /**
          * Whether the package installer should allow installation of apps downloaded from
          * sources other than the Android Market (vending machine).
          *
@@ -2371,6 +2421,14 @@
             "lock_pattern_tactile_feedback_enabled";
 
         /**
+         * This preference allows the device to be locked given time after screen goes off,
+         * subject to current DeviceAdmin policy limits.
+         * @hide
+         */
+        public static final String LOCK_SCREEN_LOCK_AFTER_TIMEOUT = "lock_screen_lock_after_timeout";
+
+
+        /**
          * Whether assisted GPS should be enabled or not.
          * @hide
          */
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 3861ef5..48a2b72 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -644,7 +644,8 @@
              } else {
                  Log.i(TAG, "Rejecting incoming HID connection from " + address);
              }
-        } else if (BluetoothUuid.isBnep(uuid) || BluetoothUuid.isNap(uuid)){
+        } else if (BluetoothUuid.isBnep(uuid) || BluetoothUuid.isNap(uuid) &&
+                mBluetoothService.isTetheringOn()){
             authorized = true;
         } else {
             Log.i(TAG, "Rejecting incoming " + deviceUuid + " connection from " + address);
@@ -760,6 +761,16 @@
         }
     }
 
+    private void onNetworkDeviceDisconnected(String address) {
+        BluetoothDevice device = mAdapter.getRemoteDevice(address);
+        mBluetoothService.handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTED);
+    }
+
+    private void onNetworkDeviceConnected(String address, int destUuid) {
+        BluetoothDevice device = mAdapter.getRemoteDevice(address);
+        mBluetoothService.handlePanDeviceStateChange(device, BluetoothPan.STATE_CONNECTED);
+    }
+
     private void onRestartRequired() {
         if (mBluetoothService.isEnabled()) {
             Log.e(TAG, "*** A serious error occured (did bluetoothd crash?) - " +
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index b732675..7252736 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -352,7 +352,7 @@
         }
         setBluetoothState(BluetoothAdapter.STATE_TURNING_OFF);
         mHandler.removeMessages(MESSAGE_REGISTER_SDP_RECORDS);
-        setBluetoothTethering(false, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
+        setBluetoothTetheringNative(false, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
 
         // Allow 3 seconds for profiles to gracefully disconnect
         // TODO: Introduce a callback mechanism so that each profile can notify
@@ -576,8 +576,12 @@
                 mBondState.readAutoPairingData();
                 mBondState.loadBondState();
                 initProfileState();
+
+                //Register SDP records.
                 mHandler.sendMessageDelayed(
                         mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 1, -1), 3000);
+                setBluetoothTetheringNative(true, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
+
 
                 // Log bluetooth on to battery stats.
                 long ident = Binder.clearCallingIdentity();
@@ -1258,14 +1262,12 @@
 
     private BroadcastReceiver mTetheringReceiver = null;
 
-    public synchronized void setBluetoothTethering(boolean value, 
-            final String uuid, final String bridge) {
-        mTetheringOn = value;
+    public synchronized void setBluetoothTethering(boolean value) {
         if (!value) {
             disconnectPan();
         }
 
-        if (getBluetoothState() != BluetoothAdapter.STATE_ON && mTetheringOn) {
+        if (getBluetoothState() != BluetoothAdapter.STATE_ON && value) {
             IntentFilter filter = new IntentFilter();
             filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
             mTetheringReceiver = new BroadcastReceiver() {
@@ -1273,14 +1275,14 @@
                 public synchronized void onReceive(Context context, Intent intent) {
                     if (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF)
                             == BluetoothAdapter.STATE_ON) {
-                        setBluetoothTethering(true, uuid, bridge);
+                        mTetheringOn = true;
                         mContext.unregisterReceiver(mTetheringReceiver);
                     }
                 }
             };
             mContext.registerReceiver(mTetheringReceiver, filter);
         } else {
-            setBluetoothTetheringNative(value, uuid, bridge);
+            mTetheringOn = value;
         }
     }
 
@@ -2138,7 +2140,7 @@
                         mContext.getSharedPreferences(SHARED_PREFERENCES_NAME,
                                 mContext.MODE_PRIVATE).edit();
                     editor.putBoolean(SHARED_PREFERENCE_DOCK_ADDRESS + mDockAddress, true);
-                    editor.startCommit();
+                    editor.apply();
                 }
             }
         }
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index b058685..11a5d69 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -55,7 +55,9 @@
     private final Rect mClipBounds = new Rect();
 
     private DrawFilter mFilter;
-    
+
+    private boolean mContextLocked;
+
     ///////////////////////////////////////////////////////////////////////////
     // JNI
     ///////////////////////////////////////////////////////////////////////////
@@ -149,6 +151,27 @@
     
     private native void nPrepare(int renderer);
 
+    @Override
+    public boolean acquireContext() {
+        if (!mContextLocked) {
+            nAcquireContext(mRenderer);
+            mContextLocked = true;
+        }
+        return mContextLocked;
+    }
+
+    private native void nAcquireContext(int renderer);
+
+    @Override
+    public void releaseContext() {
+        if (mContextLocked) {
+            nReleaseContext(mRenderer);
+            mContextLocked = false;
+        }
+    }
+
+    private native void nReleaseContext(int renderer);
+
     ///////////////////////////////////////////////////////////////////////////
     // Clipping
     ///////////////////////////////////////////////////////////////////////////
@@ -297,7 +320,7 @@
 
     @Override
     public int save() {
-        return nSave(mRenderer, 0);
+        return nSave(mRenderer, Canvas.CLIP_SAVE_FLAG | Canvas.MATRIX_SAVE_FLAG);
     }
     
     @Override
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index e86e3bf..d4dd05c 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -29,6 +29,7 @@
 import android.view.InputEvent;
 import android.view.MotionEvent;
 import android.view.InputChannel;
+import android.view.InputDevice;
 
 /**
  * System private interface to the window manager.
@@ -125,6 +126,10 @@
     // Report whether the hardware supports the given keys; returns true if successful
     boolean hasKeys(in int[] keycodes, inout boolean[] keyExists);
     
+    // Get input device information.
+    InputDevice getInputDevice(int deviceId);
+    int[] getInputDeviceIds();
+    
     // For testing
     void setInTouchMode(boolean showFocus);
     
diff --git a/core/java/android/view/InputDevice.aidl b/core/java/android/view/InputDevice.aidl
new file mode 100644
index 0000000..dbc40c1
--- /dev/null
+++ b/core/java/android/view/InputDevice.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android.view.InputDevice.aidl
+**
+** Copyright 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.view;
+
+parcelable InputDevice;
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index d5b2121..7468579 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -16,6 +16,11 @@
 
 package android.view;
 
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
 /**
  * Describes the capabilities of a particular input device.
  * <p>
@@ -32,12 +37,14 @@
  * the appropriate interpretation.
  * </p>
  */
-public final class InputDevice {
+public final class InputDevice implements Parcelable {
     private int mId;
     private String mName;
     private int mSources;
     private int mKeyboardType;
     
+    private MotionRange[] mMotionRanges;
+    
     /**
      * A mask for input source classes.
      * 
@@ -52,7 +59,7 @@
      * 
      * A {@link KeyEvent} should be interpreted as a button or key press.
      * 
-     * Use {@link #hasKey} to query whether the device supports a particular button or key.
+     * Use {@link #getKeyCharacterMap} to query the device's button and key mappings.
      */
     public static final int SOURCE_CLASS_BUTTON = 0x00000001;
     
@@ -246,6 +253,8 @@
      */
     public static final int MOTION_RANGE_ORIENTATION = 8;
     
+    private static final int MOTION_RANGE_LAST = MOTION_RANGE_ORIENTATION;
+    
     /**
      * There is no keyboard.
      */
@@ -261,6 +270,11 @@
      * The keyboard supports a complement of alphabetic keys.
      */
     public static final int KEYBOARD_TYPE_ALPHABETIC = 2;
+    
+    // Called by native code.
+    private InputDevice() {
+        mMotionRanges = new MotionRange[MOTION_RANGE_LAST + 1];
+    }
 
     /**
      * Gets information about the input device with the specified id.
@@ -268,8 +282,35 @@
      * @return The input device or null if not found.
      */
     public static InputDevice getDevice(int id) {
-        // TODO
-        return null;
+        IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+        try {
+            return wm.getInputDevice(id);
+        } catch (RemoteException ex) {
+            throw new RuntimeException(
+                    "Could not get input device information from Window Manager.", ex);
+        }
+    }
+    
+    /**
+     * Gets the ids of all input devices in the system.
+     * @return The input device ids.
+     */
+    public static int[] getDeviceIds() {
+        IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+        try {
+            return wm.getInputDeviceIds();
+        } catch (RemoteException ex) {
+            throw new RuntimeException(
+                    "Could not get input device ids from Window Manager.", ex);
+        }
+    }
+    
+    /**
+     * Gets the input device id.
+     * @return The input device id.
+     */
+    public int getId() {
+        return mId;
     }
     
     /**
@@ -307,23 +348,23 @@
     /**
      * Gets information about the range of values for a particular {@link MotionEvent}
      * coordinate.
-     * @param range The motion range constant.
+     * @param rangeType The motion range constant.
      * @return The range of values, or null if the requested coordinate is not
      * supported by the device.
      */
-    public MotionRange getMotionRange(int range) {
-        // TODO
-        return null;
+    public MotionRange getMotionRange(int rangeType) {
+        if (rangeType < 0 || rangeType > MOTION_RANGE_LAST) {
+            throw new IllegalArgumentException("Requested range is out of bounds.");
+        }
+        
+        return mMotionRanges[rangeType];
     }
     
-    /**
-     * Returns true if the device supports a particular button or key.
-     * @param keyCode The key code.
-     * @return True if the device supports the key.
-     */
-    public boolean hasKey(int keyCode) {
-        // TODO
-        return false;
+    private void addMotionRange(int rangeType, float min, float max, float flat, float fuzz) {
+        if (rangeType >= 0 && rangeType <= MOTION_RANGE_LAST) {
+            MotionRange range = new MotionRange(min, max, flat, fuzz);
+            mMotionRanges[rangeType] = range;
+        }
     }
     
     /**
@@ -331,13 +372,24 @@
      * coordinate.
      */
     public static final class MotionRange {
+        private float mMin;
+        private float mMax;
+        private float mFlat;
+        private float mFuzz;
+        
+        private MotionRange(float min, float max, float flat, float fuzz) {
+            mMin = min;
+            mMax = max;
+            mFlat = flat;
+            mFuzz = fuzz;
+        }
+        
         /**
          * Gets the minimum value for the coordinate.
          * @return The minimum value.
          */
         public float getMin() {
-            // TODO
-            return 0;
+            return mMin;
         }
         
         /**
@@ -345,8 +397,7 @@
          * @return The minimum value.
          */
         public float getMax() {
-            // TODO
-            return 0;
+            return mMax;
         }
         
         /**
@@ -354,8 +405,7 @@
          * @return The range of values.
          */
         public float getRange() {
-            // TODO
-            return 0;
+            return mMax - mMin;
         }
         
         /**
@@ -365,8 +415,7 @@
          * @return The extent of the center flat position.
          */
         public float getFlat() {
-            // TODO
-            return 0;
+            return mFlat;
         }
         
         /**
@@ -376,8 +425,127 @@
          * @return The error tolerance.
          */
         public float getFuzz() {
-            // TODO
-            return 0;
+            return mFuzz;
+        }
+    }
+    
+    public static final Parcelable.Creator<InputDevice> CREATOR
+            = new Parcelable.Creator<InputDevice>() {
+        public InputDevice createFromParcel(Parcel in) {
+            InputDevice result = new InputDevice();
+            result.readFromParcel(in);
+            return result;
+        }
+        
+        public InputDevice[] newArray(int size) {
+            return new InputDevice[size];
+        }
+    };
+    
+    private void readFromParcel(Parcel in) {
+        mId = in.readInt();
+        mName = in.readString();
+        mSources = in.readInt();
+        mKeyboardType = in.readInt();
+        
+        for (;;) {
+            int rangeType = in.readInt();
+            if (rangeType < 0) {
+                break;
+            }
+            
+            addMotionRange(rangeType,
+                    in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
+        }
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mId);
+        out.writeString(mName);
+        out.writeInt(mSources);
+        out.writeInt(mKeyboardType);
+        
+        for (int i = 0; i <= MOTION_RANGE_LAST; i++) {
+            MotionRange range = mMotionRanges[i];
+            if (range != null) {
+                out.writeInt(i);
+                out.writeFloat(range.mMin);
+                out.writeFloat(range.mMax);
+                out.writeFloat(range.mFlat);
+                out.writeFloat(range.mFuzz);
+            }
+        }
+        out.writeInt(-1);
+    }
+    
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+    
+    @Override
+    public String toString() {
+        StringBuilder description = new StringBuilder();
+        description.append("Input Device ").append(mId).append(": ").append(mName).append("\n");
+        
+        description.append("  Keyboard Type: ");
+        switch (mKeyboardType) {
+            case KEYBOARD_TYPE_NONE:
+                description.append("none");
+                break;
+            case KEYBOARD_TYPE_NON_ALPHABETIC:
+                description.append("non-alphabetic");
+                break;
+            case KEYBOARD_TYPE_ALPHABETIC:
+                description.append("alphabetic");
+                break;
+        }
+        description.append("\n");
+        
+        description.append("  Sources:");
+        appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
+        appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
+        appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad");
+        appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
+        appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse");
+        appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball");
+        appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad");
+        appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK_LEFT, "joystick_left");
+        appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK_RIGHT, "joystick_right");
+        description.append("\n");
+        
+        appendRangeDescriptionIfApplicable(description, MOTION_RANGE_X, "x");
+        appendRangeDescriptionIfApplicable(description, MOTION_RANGE_Y, "y");
+        appendRangeDescriptionIfApplicable(description, MOTION_RANGE_PRESSURE, "pressure");
+        appendRangeDescriptionIfApplicable(description, MOTION_RANGE_SIZE, "size");
+        appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOUCH_MAJOR, "touchMajor");
+        appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOUCH_MINOR, "touchMinor");
+        appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOOL_MAJOR, "toolMajor");
+        appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOOL_MINOR, "toolMinor");
+        appendRangeDescriptionIfApplicable(description, MOTION_RANGE_ORIENTATION, "orientation");
+        
+        return description.toString();
+    }
+    
+    private void appendSourceDescriptionIfApplicable(StringBuilder description, int source,
+            String sourceName) {
+        if ((mSources & source) == source) {
+            description.append(" ");
+            description.append(sourceName);
+        }
+    }
+    
+    private void appendRangeDescriptionIfApplicable(StringBuilder description,
+            int rangeType, String rangeName) {
+        MotionRange range = mMotionRanges[rangeType];
+        if (range != null) {
+            description.append("  Range[").append(rangeName);
+            description.append("]: min=").append(range.mMin);
+            description.append(" max=").append(range.mMax);
+            description.append(" flat=").append(range.mFlat);
+            description.append(" fuzz=").append(range.mFuzz);
+            description.append("\n");
         }
     }
 }
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 0999598..17b5dd7 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -25,7 +25,7 @@
  * using the supplied {@link MotionEvent}s. The {@link OnScaleGestureListener}
  * callback will notify users when a particular gesture event has occurred.
  * This class should only be used with {@link MotionEvent}s reported via touch.
- * 
+ *
  * To use this class:
  * <ul>
  *  <li>Create an instance of the {@code ScaleGestureDetector} for your
@@ -41,7 +41,7 @@
      * If you want to listen for all the different gestures then implement
      * this interface. If you only want to listen for a subset it might
      * be easier to extend {@link SimpleOnScaleGestureListener}.
-     * 
+     *
      * An application will receive events in the following order:
      * <ul>
      *  <li>One {@link OnScaleGestureListener#onScaleBegin(ScaleGestureDetector)}
@@ -53,7 +53,7 @@
         /**
          * Responds to scaling events for a gesture in progress.
          * Reported by pointer motion.
-         * 
+         *
          * @param detector The detector reporting the event - use this to
          *          retrieve extended info about event state.
          * @return Whether or not the detector should consider this event
@@ -68,7 +68,7 @@
         /**
          * Responds to the beginning of a scaling gesture. Reported by
          * new pointers going down.
-         * 
+         *
          * @param detector The detector reporting the event - use this to
          *          retrieve extended info about event state.
          * @return Whether or not the detector should continue recognizing
@@ -82,17 +82,17 @@
         /**
          * Responds to the end of a scale gesture. Reported by existing
          * pointers going up.
-         * 
+         *
          * Once a scale has ended, {@link ScaleGestureDetector#getFocusX()}
          * and {@link ScaleGestureDetector#getFocusY()} will return the location
          * of the pointer remaining on the screen.
-         * 
+         *
          * @param detector The detector reporting the event - use this to
          *          retrieve extended info about event state.
          */
         public void onScaleEnd(ScaleGestureDetector detector);
     }
-    
+
     /**
      * A convenience class to extend when you only want to listen for a subset
      * of scaling-related events. This implements all methods in
@@ -101,7 +101,7 @@
      * {@code false} so that a subclass can retrieve the accumulated scale
      * factor in an overridden onScaleEnd.
      * {@link OnScaleGestureListener#onScaleBegin(ScaleGestureDetector)} returns
-     * {@code true}. 
+     * {@code true}.
      */
     public static class SimpleOnScaleGestureListener implements OnScaleGestureListener {
 
@@ -148,7 +148,7 @@
     private float mCurrPressure;
     private float mPrevPressure;
     private long mTimeDelta;
-    
+
     private final float mEdgeSlop;
     private float mRightSlopEdge;
     private float mBottomSlopEdge;
@@ -217,7 +217,7 @@
                 }
             }
             break;
-            
+
             case MotionEvent.ACTION_MOVE:
                 if (mSloppyGesture) {
                     // Initiate sloppy gestures if we've moved outside of the slop area.
@@ -249,7 +249,7 @@
                     }
                 }
                 break;
-                
+
             case MotionEvent.ACTION_POINTER_UP:
                 if (mSloppyGesture) {
                     // Set focus point to the remaining finger
@@ -307,17 +307,17 @@
         }
         return handled;
     }
-    
+
     /**
-     * MotionEvent has no getRawX(int) method; simulate it pending future API approval. 
+     * MotionEvent has no getRawX(int) method; simulate it pending future API approval.
      */
     private static float getRawX(MotionEvent event, int pointerIndex) {
         float offset = event.getRawX() - event.getX();
         return event.getX(pointerIndex) + offset;
     }
-    
+
     /**
-     * MotionEvent has no getRawY(int) method; simulate it pending future API approval. 
+     * MotionEvent has no getRawY(int) method; simulate it pending future API approval.
      */
     private static float getRawY(MotionEvent event, int pointerIndex) {
         float offset = event.getRawY() - event.getY();
@@ -390,7 +390,7 @@
      * remaining pointer on the screen.
      * If {@link #isInProgress()} would return false, the result of this
      * function is undefined.
-     * 
+     *
      * @return X coordinate of the focal point in pixels.
      */
     public float getFocusX() {
@@ -405,7 +405,7 @@
      * remaining pointer on the screen.
      * If {@link #isInProgress()} would return false, the result of this
      * function is undefined.
-     * 
+     *
      * @return Y coordinate of the focal point in pixels.
      */
     public float getFocusY() {
@@ -415,7 +415,7 @@
     /**
      * Return the current distance between the two pointers forming the
      * gesture in progress.
-     * 
+     *
      * @return Distance between pointers in pixels.
      */
     public float getCurrentSpan() {
@@ -428,9 +428,29 @@
     }
 
     /**
+     * Return the current x distance between the two pointers forming the
+     * gesture in progress.
+     *
+     * @return Distance between pointers in pixels.
+     */
+    public float getCurrentSpanX() {
+        return mCurrFingerDiffX;
+    }
+
+    /**
+     * Return the current y distance between the two pointers forming the
+     * gesture in progress.
+     *
+     * @return Distance between pointers in pixels.
+     */
+    public float getCurrentSpanY() {
+        return mCurrFingerDiffY;
+    }
+
+    /**
      * Return the previous distance between the two pointers forming the
      * gesture in progress.
-     * 
+     *
      * @return Previous distance between pointers in pixels.
      */
     public float getPreviousSpan() {
@@ -443,10 +463,30 @@
     }
 
     /**
+     * Return the previous x distance between the two pointers forming the
+     * gesture in progress.
+     *
+     * @return Previous distance between pointers in pixels.
+     */
+    public float getPreviousSpanX() {
+        return mPrevFingerDiffX;
+    }
+
+    /**
+     * Return the previous y distance between the two pointers forming the
+     * gesture in progress.
+     *
+     * @return Previous distance between pointers in pixels.
+     */
+    public float getPreviousSpanY() {
+        return mPrevFingerDiffY;
+    }
+
+    /**
      * Return the scaling factor from the previous scale event to the current
      * event. This value is defined as
      * ({@link #getCurrentSpan()} / {@link #getPreviousSpan()}).
-     * 
+     *
      * @return The current scaling factor.
      */
     public float getScaleFactor() {
@@ -455,20 +495,20 @@
         }
         return mScaleFactor;
     }
-    
+
     /**
      * Return the time difference in milliseconds between the previous
      * accepted scaling event and the current scaling event.
-     * 
+     *
      * @return Time difference since the last scaling event in milliseconds.
      */
     public long getTimeDelta() {
         return mTimeDelta;
     }
-    
+
     /**
      * Return the event time of the current event being processed.
-     * 
+     *
      * @return Current event time in milliseconds.
      */
     public long getEventTime() {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 616128d..47dae03 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -58,7 +58,6 @@
 import android.util.Pools;
 import android.util.SparseArray;
 import android.view.ContextMenu.ContextMenuInfo;
-import android.view.View.MeasureSpec;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityEventSource;
 import android.view.accessibility.AccessibilityManager;
@@ -73,6 +72,7 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.WeakHashMap;
 
 /**
@@ -1838,6 +1838,11 @@
     protected OnFocusChangeListener mOnFocusChangeListener;
 
     /**
+     * Listeners for layout change events.
+     */
+    private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;
+
+    /**
      * Listener used to dispatch click events.
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
@@ -2496,6 +2501,39 @@
     }
 
     /**
+     * Add a listener that will be called when the bounds of the view change due to
+     * layout processing.
+     *
+     * @param listener The listener that will be called when layout bounds change.
+     */
+    public void addOnLayoutChangeListener(OnLayoutChangeListener listener) {
+        if (mOnLayoutChangeListeners == null) {
+            mOnLayoutChangeListeners = new ArrayList<OnLayoutChangeListener>();
+        }
+        mOnLayoutChangeListeners.add(listener);
+    }
+
+    /**
+     * Remove a listener for layout changes.
+     *
+     * @param listener The listener for layout bounds change.
+     */
+    public void removeOnLayoutChangeListener(OnLayoutChangeListener listener) {
+        if (mOnLayoutChangeListeners == null) {
+            return;
+        }
+        mOnLayoutChangeListeners.remove(listener);
+    }
+
+    /**
+     * Gets the current list of listeners for layout changes.
+     * @return
+     */
+    public List<OnLayoutChangeListener> getOnLayoutChangeListeners() {
+        return mOnLayoutChangeListeners;
+    }
+
+    /**
      * Returns the focus-change callback registered for this view.
      *
      * @return The callback, or null if one is not registered.
@@ -4806,6 +4844,28 @@
     }
 
     /**
+     * Interface definition for a callback to be invoked when the layout bounds of a view
+     * changes due to layout processing.
+     */
+    public interface OnLayoutChangeListener {
+        /**
+         * Called when the focus state of a view has changed.
+         *
+         * @param v The view whose state has 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.
+         * @param bottom The new value of the view's bottom property.
+         * @param oldLeft The previous value of the view's left property.
+         * @param oldTop The previous value of the view's top property.
+         * @param oldRight The previous value of the view's right property.
+         * @param oldBottom The previous value of the view's bottom property.
+         */
+        void onLayoutChange(View v, int left, int top, int right, int bottom,
+            int oldLeft, int oldTop, int oldRight, int oldBottom);
+    }
+
+    /**
      * This is called during layout when the size of this view has changed. If
      * you were just added to the view hierarchy, you're called with the old
      * values of 0.
@@ -5251,6 +5311,7 @@
      */
     public void setAlpha(float alpha) {
         mAlpha = alpha;
+        onSetAlpha((int) (alpha * 255));
         invalidate();
     }
 
@@ -5265,6 +5326,45 @@
     }
 
     /**
+     * Sets the top position of this view relative to its parent. This method is meant to be called
+     * by the layout system and should not generally be called otherwise, because the property
+     * may be changed at any time by the layout.
+     *
+     * @param top The top of this view, in pixels.
+     */
+    public final void setTop(int top) {
+        if (top != mTop) {
+            if (hasIdentityMatrix()) {
+                final ViewParent p = mParent;
+                if (p != null && mAttachInfo != null) {
+                    final Rect r = mAttachInfo.mTmpInvalRect;
+                    int minTop;
+                    int yLoc;
+                    if (top < mTop) {
+                        minTop = top;
+                        yLoc = top - mTop;
+                    } else {
+                        minTop = mTop;
+                        yLoc = 0;
+                    }
+                    r.set(0, yLoc, mRight - mLeft, mBottom - minTop);
+                    p.invalidateChild(this, r);
+                }
+            } else {
+                // Double-invalidation is necessary to capture view's old and new areas
+                invalidate();
+            }
+
+            mTop = top;
+
+            if (!mMatrixIsIdentity) {
+                mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
+                invalidate();
+            }
+        }
+    }
+
+    /**
      * Bottom position of this view relative to its parent.
      *
      * @return The bottom of this view, in pixels.
@@ -5275,6 +5375,42 @@
     }
 
     /**
+     * Sets the bottom position of this view relative to its parent. This method is meant to be
+     * called by the layout system and should not generally be called otherwise, because the
+     * property may be changed at any time by the layout.
+     *
+     * @param bottom The bottom of this view, in pixels.
+     */
+    public final void setBottom(int bottom) {
+        if (bottom != mBottom) {
+            if (hasIdentityMatrix()) {
+                final ViewParent p = mParent;
+                if (p != null && mAttachInfo != null) {
+                    final Rect r = mAttachInfo.mTmpInvalRect;
+                    int maxBottom;
+                    if (bottom < mBottom) {
+                        maxBottom = mBottom;
+                    } else {
+                        maxBottom = bottom;
+                    }
+                    r.set(0, 0, mRight - mLeft, maxBottom - mTop);
+                    p.invalidateChild(this, r);
+                }
+            } else {
+                // Double-invalidation is necessary to capture view's old and new areas
+                invalidate();
+            }
+
+            mBottom = bottom;
+
+            if (!mMatrixIsIdentity) {
+                mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
+                invalidate();
+            }
+        }
+    }
+
+    /**
      * Left position of this view relative to its parent.
      *
      * @return The left edge of this view, in pixels.
@@ -5285,6 +5421,46 @@
     }
 
     /**
+     * Sets the left position of this view relative to its parent. This method is meant to be called
+     * by the layout system and should not generally be called otherwise, because the property
+     * may be changed at any time by the layout.
+     *
+     * @param left The bottom of this view, in pixels.
+     */
+    public final void setLeft(int left) {
+        if (left != mLeft) {
+            System.out.println("view " + this + " left = " + left);
+            if (hasIdentityMatrix()) {
+                final ViewParent p = mParent;
+                if (p != null && mAttachInfo != null) {
+                    final Rect r = mAttachInfo.mTmpInvalRect;
+                    int minLeft;
+                    int xLoc;
+                    if (left < mLeft) {
+                        minLeft = left;
+                        xLoc = left - mLeft;
+                    } else {
+                        minLeft = mLeft;
+                        xLoc = 0;
+                    }
+                    r.set(xLoc, 0, mRight - minLeft, mBottom - mTop);
+                    p.invalidateChild(this, r);
+                }
+            } else {
+                // Double-invalidation is necessary to capture view's old and new areas
+                invalidate();
+            }
+
+            mLeft = left;
+
+            if (!mMatrixIsIdentity) {
+                mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
+                invalidate();
+            }
+        }
+    }
+
+    /**
      * Right position of this view relative to its parent.
      *
      * @return The right edge of this view, in pixels.
@@ -5295,6 +5471,42 @@
     }
 
     /**
+     * Sets the right position of this view relative to its parent. This method is meant to be called
+     * by the layout system and should not generally be called otherwise, because the property
+     * may be changed at any time by the layout.
+     *
+     * @param right The bottom of this view, in pixels.
+     */
+    public final void setRight(int right) {
+        if (right != mRight) {
+            if (hasIdentityMatrix()) {
+                final ViewParent p = mParent;
+                if (p != null && mAttachInfo != null) {
+                    final Rect r = mAttachInfo.mTmpInvalRect;
+                    int maxRight;
+                    if (right < mRight) {
+                        maxRight = mRight;
+                    } else {
+                        maxRight = right;
+                    }
+                    r.set(0, 0, maxRight - mLeft, mBottom - mTop);
+                    p.invalidateChild(this, r);
+                }
+            } else {
+                // Double-invalidation is necessary to capture view's old and new areas
+                invalidate();
+            }
+
+            mRight = right;
+
+            if (!mMatrixIsIdentity) {
+                mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
+                invalidate();
+            }
+        }
+    }
+
+    /**
      * The visual x position of this view, in pixels. This is equivalent to the
      * {@link #setTranslationX(float) translationX} property plus the current
      * {@link #getLeft() left} property. 
@@ -5536,15 +5748,12 @@
                     final Rect r = mAttachInfo.mTmpInvalRect;
                     int minLeft;
                     int maxRight;
-                    int xLoc;
                     if (offset < 0) {
                         minLeft = mLeft + offset;
                         maxRight = mRight;
-                        xLoc = offset;
                     } else {
                         minLeft = mLeft;
                         maxRight = mRight + offset;
-                        xLoc = 0;
                     }
                     r.set(0, 0, maxRight - minLeft, mBottom - mTop);
                     p.invalidateChild(this, r);
@@ -7744,7 +7953,7 @@
      *
      * Derived classes with children should override
      * onLayout. In that method, they should
-     * call layout on each of their their children.
+     * call layout on each of their children.
      *
      * @param l Left position, relative to parent
      * @param t Top position, relative to parent
@@ -7752,6 +7961,10 @@
      * @param b Bottom position, relative to parent
      */
     public final void layout(int l, int t, int r, int b) {
+        int oldL = mLeft;
+        int oldT = mTop;
+        int oldB = mBottom;
+        int oldR = mRight;
         boolean changed = setFrame(l, t, r, b);
         if (changed || (mPrivateFlags & LAYOUT_REQUIRED) == LAYOUT_REQUIRED) {
             if (ViewDebug.TRACE_HIERARCHY) {
@@ -7760,6 +7973,15 @@
 
             onLayout(changed, l, t, r, b);
             mPrivateFlags &= ~LAYOUT_REQUIRED;
+
+            if (mOnLayoutChangeListeners != null) {
+                ArrayList<OnLayoutChangeListener> listenersCopy =
+                        (ArrayList<OnLayoutChangeListener>) mOnLayoutChangeListeners.clone();
+                int numListeners = listenersCopy.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    listenersCopy.get(i).onLayoutChange(this, l, r, t, b, oldL, oldT, oldR, oldB);
+                }
+            }
         }
         mPrivateFlags &= ~FORCE_LAYOUT;
     }
@@ -7770,7 +7992,7 @@
      *
      * Derived classes with children should override
      * this method and call layout on each of
-     * their their children.
+     * their children.
      * @param changed This is a new size or position for this view
      * @param left Left position, relative to parent
      * @param top Top position, relative to parent
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9770313..649f3e7 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.animation.LayoutTransition;
 import com.android.internal.R;
 
 import android.content.Context;
@@ -35,7 +36,6 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.SparseArray;
-import android.view.ViewGroup.LayoutParams;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -43,7 +43,6 @@
 import android.view.animation.Transformation;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 
 /**
  * <p>
@@ -68,6 +67,7 @@
  * @attr ref android.R.styleable#ViewGroup_descendantFocusability
  */
 public abstract class ViewGroup extends View implements ViewParent, ViewManager {
+
     private static final boolean DBG = false;
 
     /**
@@ -300,6 +300,14 @@
     // Used to draw cached views
     private final Paint mCachePaint = new Paint();
 
+    // Used to animate add/remove changes in layout
+    private LayoutTransition mTransition;
+
+    // The set of views that are currently being transitioned. This list is used to track views
+    // being removed that should not actually be removed from the parent yet because they are
+    // being animated.
+    private ArrayList<View> mTransitioningViews;
+
     public ViewGroup(Context context) {
         super(context);
         initViewGroup();
@@ -1970,6 +1978,7 @@
             }
         } else if ((child.mPrivateFlags & ALPHA_SET) == ALPHA_SET) {
             child.onSetAlpha(255);
+            child.mPrivateFlags &= ~ALPHA_SET;
         }
 
         if ((flags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) {
@@ -2328,6 +2337,10 @@
                     "You must call removeView() on the child's parent first.");
         }
 
+        if (mTransition != null) {
+            mTransition.childAdd(this, child);
+        }
+
         if (!checkLayoutParams(params)) {
             params = generateLayoutParams(params);
         }
@@ -2405,7 +2418,9 @@
     // This method also sets the child's mParent to null
     private void removeFromArray(int index) {
         final View[] children = mChildren;
-        children[index].mParent = null;
+        if (!(mTransitioningViews != null && mTransitioningViews.contains(children[index]))) {
+            children[index].mParent = null;
+        }
         final int count = mChildrenCount;
         if (index == count - 1) {
             children[--mChildrenCount] = null;
@@ -2540,13 +2555,19 @@
     }
 
     private void removeViewInternal(int index, View view) {
+
+        if (mTransition != null) {
+            mTransition.childRemove(this, view);
+        }
+
         boolean clearChildFocus = false;
         if (view == mFocused) {
             view.clearFocusForRemoval();
             clearChildFocus = true;
         }
 
-        if (view.getAnimation() != null) {
+        if (view.getAnimation() != null ||
+                (mTransitioningViews != null && mTransitioningViews.contains(view))) {
             addDisappearingView(view);
         } else if (view.mAttachInfo != null) {
            view.dispatchDetachedFromWindow();
@@ -2565,6 +2586,20 @@
         }
     }
 
+    /**
+     * Sets the LayoutTransition object for this ViewGroup. If the LayoutTransition object is
+     * not null, changes in layout which occur because of children being added to or removed from
+     * the ViewGroup will be animated according to the animations defined in that LayoutTransition
+     * object. By default, the transition object is null (so layout changes are not animated).
+     *
+     * @param transition The LayoutTransition object that will animated changes in layout. A value
+     * of <code>null</code> means no transition will run on layout changes.
+     */
+    public void setLayoutTransition(LayoutTransition transition) {
+        mTransition = transition;
+        mTransition.addTransitionListener(mLayoutTransitionListener);
+    }
+
     private void removeViewsInternal(int start, int count) {
         final OnHierarchyChangeListener onHierarchyChangeListener = mOnHierarchyChangeListener;
         final boolean notifyListener = onHierarchyChangeListener != null;
@@ -2578,12 +2613,17 @@
         for (int i = start; i < end; i++) {
             final View view = children[i];
 
+            if (mTransition != null) {
+                mTransition.childRemove(this, view);
+            }
+
             if (view == focused) {
                 view.clearFocusForRemoval();
                 clearChildFocus = view;
             }
 
-            if (view.getAnimation() != null) {
+            if (view.getAnimation() != null ||
+                (mTransitioningViews != null && mTransitioningViews.contains(view))) {
                 addDisappearingView(view);
             } else if (detach) {
                view.dispatchDetachedFromWindow();
@@ -2642,12 +2682,17 @@
         for (int i = count - 1; i >= 0; i--) {
             final View view = children[i];
 
+            if (mTransition != null) {
+                mTransition.childRemove(this, view);
+            }
+
             if (view == focused) {
                 view.clearFocusForRemoval();
                 clearChildFocus = view;
             }
 
-            if (view.getAnimation() != null) {
+            if (view.getAnimation() != null ||
+                    (mTransitioningViews != null && mTransitioningViews.contains(view))) {
                 addDisappearingView(view);
             } else if (detach) {
                view.dispatchDetachedFromWindow();
@@ -2680,11 +2725,16 @@
      * @see #detachViewFromParent(int)
      */
     protected void removeDetachedView(View child, boolean animate) {
+        if (mTransition != null) {
+            mTransition.childRemove(this, child);
+        }
+
         if (child == mFocused) {
             child.clearFocus();
         }
 
-        if (animate && child.getAnimation() != null) {
+        if ((animate && child.getAnimation() != null) ||
+                (mTransitioningViews != null && mTransitioningViews.contains(child))) {
             addDisappearingView(child);
         } else if (child.mAttachInfo != null) {
             child.dispatchDetachedFromWindow();
@@ -3659,6 +3709,41 @@
         }
     }
 
+    private LayoutTransition.TransitionListener mLayoutTransitionListener =
+            new LayoutTransition.TransitionListener() {
+        @Override
+        public void startTransition(LayoutTransition transition, ViewGroup container,
+                View view, int transitionType) {
+            // We only care about disappearing items, since we need special logic to keep
+            // those items visible after they've been 'removed'
+            if (transitionType == LayoutTransition.DISAPPEARING) {
+                if (mTransitioningViews == null) {
+                    mTransitioningViews = new ArrayList<View>();
+                }
+                mTransitioningViews.add(view);
+            }
+        }
+
+        @Override
+        public void endTransition(LayoutTransition transition, ViewGroup container,
+                View view, int transitionType) {
+            if (transitionType == LayoutTransition.DISAPPEARING && mTransitioningViews != null) {
+                mTransitioningViews.remove(view);
+                final ArrayList<View> disappearingChildren = mDisappearingChildren;
+                if (disappearingChildren != null && disappearingChildren.contains(view)) {
+                    disappearingChildren.remove(view);
+                    if (view.mAttachInfo != null) {
+                        view.dispatchDetachedFromWindow();
+                    }
+                    if (view.mParent != null) {
+                        view.mParent = null;
+                    }
+                    mGroupFlags |= FLAG_INVALIDATE_REQUIRED;
+                }
+            }
+        }
+    };
+
     /**
      * {@inheritDoc}
      */
@@ -4190,18 +4275,10 @@
             return mTargets.get(id);
         }
 
-        public int indexOfId(int id) {
-            return mTargets.indexOfKey(id);
-        }
-
         public int indexOfTarget(View target) {
             return mTargets.indexOfValue(target);
         }
 
-        public int idAt(int index) {
-            return mTargets.keyAt(index);
-        }
-
         public View targetAt(int index) {
             return mTargets.valueAt(index);
         }
@@ -4224,17 +4301,6 @@
             return null;
         }
 
-        public boolean hasTarget(View target) {
-            final TargetInfo[] unique = mUniqueTargets;
-            final int uniqueCount = mUniqueTargetCount;
-            for (int i = 0; i < uniqueCount; i++) {
-                if (unique[i].view == target) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
         public boolean isEmpty() {
             return mUniqueTargetCount == 0;
         }
@@ -4384,11 +4450,10 @@
                         (newActionIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
             }
 
-            MotionEvent result = MotionEvent.obtain(downTime, ev.getEventTime(),
+            return MotionEvent.obtain(downTime, ev.getEventTime(),
                     action, pointerCount, mPointerIds, mPointerCoords, ev.getMetaState(),
                     ev.getXPrecision(), ev.getYPrecision(), ev.getDeviceId(), ev.getEdgeFlags(),
                     ev.getSource());
-            return result;
         }
 
         static class TargetInfo {
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index d5058b0..52a117d 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -284,7 +284,7 @@
     // only called from WebCore Thread
     // make sure to call startCacheTransaction/endCacheTransaction in pair
     /**
-     * @deprecated
+     * @deprecated Not used
      */
     @Deprecated
     public static boolean startCacheTransaction() {
@@ -294,7 +294,7 @@
     // only called from WebCore Thread
     // make sure to call startCacheTransaction/endCacheTransaction in pair
     /**
-     * @deprecated
+     * @deprecated Not used
      */
     @Deprecated
     public static boolean endCacheTransaction() {
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
new file mode 100644
index 0000000..2299d4a
--- /dev/null
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -0,0 +1,224 @@
+/*
+ * 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.webkit;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.TextWatcher;
+import android.webkit.WebView;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.view.ActionMode;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+
+class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
+        View.OnLongClickListener {
+    private View mCustomView;
+    private EditText mEditText;
+    private TextView mMatches;
+    private WebView mWebView;
+    private InputMethodManager mInput;
+    private Resources mResources;
+    private boolean mMatchesFound;
+    private int mNumberOfMatches;
+    private View mTitleBar;
+
+    FindActionModeCallback(Context context) {
+        mCustomView = LayoutInflater.from(context).inflate(
+                com.android.internal.R.layout.webview_find, null);
+        mEditText = (EditText) mCustomView.findViewById(
+                com.android.internal.R.id.edit);
+        // Override long click so that select ActionMode is not opened, which
+        // would exit find ActionMode.
+        mEditText.setOnLongClickListener(this);
+        setText("");
+        mMatches = (TextView) mCustomView.findViewById(
+                com.android.internal.R.id.matches);
+        mInput = (InputMethodManager)
+                context.getSystemService(Context.INPUT_METHOD_SERVICE);
+        mResources = context.getResources();
+    }
+
+    void setTitleBar(View v) { mTitleBar = v; }
+
+    /*
+     * Place text in the text field so it can be searched for.  Need to press
+     * the find next or find previous button to find all of the matches.
+     */
+    void setText(String text) {
+        mEditText.setText(text);
+        Spannable span = (Spannable) mEditText.getText();
+        int length = span.length();
+        // Ideally, we would like to set the selection to the whole field,
+        // but this brings up the Text selection CAB, which dismisses this
+        // one.
+        Selection.setSelection(span, length, length);
+        // Necessary each time we set the text, so that this will watch
+        // changes to it.
+        span.setSpan(this, 0, length, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+        mMatchesFound = false;
+    }
+
+    /*
+     * Set the WebView to search.  Must be non null, and set before calling
+     * startActionMode.
+     */
+    void setWebView(WebView webView) {
+        if (null == webView) {
+            throw new AssertionError("WebView supplied to "
+                    + "FindActionModeCallback cannot be null");
+        }
+        mWebView = webView;
+    }
+
+    /*
+     * Move the highlight to the next match.
+     * @param next If true, find the next match further down in the document.
+     *             If false, find the previous match, up in the document.
+     */
+    private void findNext(boolean next) {
+        if (mWebView == null) {
+            throw new AssertionError(
+                    "No WebView for FindActionModeCallback::findNext");
+        }
+        mWebView.findNext(next);
+    }
+
+    /*
+     * Highlight all the instances of the string from mEditText in mWebView.
+     */
+    void findAll() {
+        if (mWebView == null) {
+            throw new AssertionError(
+                    "No WebView for FindActionModeCallback::findAll");
+        }
+        CharSequence find = mEditText.getText();
+        if (0 == find.length()) {
+            mWebView.clearMatches();
+            mMatches.setVisibility(View.GONE);
+            mMatchesFound = false;
+        } else {
+            mMatchesFound = true;
+            mMatches.setVisibility(View.VISIBLE);
+            mNumberOfMatches = mWebView.findAll(find.toString());
+            if (0 == mNumberOfMatches) {
+                mMatches.setText(mResources.getString(
+                        com.android.internal.R.string.no_matches));
+            } else {
+                updateMatchesString();
+            }
+        }
+    }
+
+    /*
+     * Update the string which tells the user how many matches were found, and
+     * which match is currently highlighted.
+     */
+    private void updateMatchesString() {
+        String template = mResources.getQuantityString(
+                com.android.internal.R.plurals.matches_found, mNumberOfMatches,
+                mWebView.findIndex() + 1, mNumberOfMatches);
+
+        mMatches.setText(template);
+    }
+
+    // OnLongClickListener implementation
+
+    @Override
+    public boolean onLongClick(View v) { return true; }
+
+    // ActionMode.Callback implementation
+
+    @Override
+    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+        mode.setCustomView(mCustomView);
+        mode.getMenuInflater().inflate(com.android.internal.R.menu.webview_find,
+                menu);
+        Editable edit = mEditText.getText();
+        Selection.setSelection(edit, edit.length());
+        mMatches.setVisibility(View.GONE);
+        mMatchesFound = false;
+        mMatches.setText("0");
+        mEditText.requestFocus();
+        mInput.showSoftInput(mEditText, 0);
+        return true;
+    }
+
+    @Override
+    public void onDestroyActionMode(ActionMode mode) {
+        if (mTitleBar != null) mWebView.setEmbeddedTitleBar(mTitleBar);
+        mWebView.notifyFindDialogDismissed();
+        mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
+    }
+
+    @Override
+    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+        return false;
+    }
+
+    @Override
+    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+        if (!mMatchesFound) {
+            findAll();
+            return true;
+        }
+        switch(item.getItemId()) {
+            case com.android.internal.R.id.find_prev:
+                findNext(false);
+                break;
+            case com.android.internal.R.id.find_next:
+                findNext(true);
+                break;
+            default:
+                return false;
+        }
+        updateMatchesString();
+        return true;
+    }
+
+    // TextWatcher implementation
+
+    @Override
+    public void beforeTextChanged(CharSequence s,
+                                  int start,
+                                  int count,
+                                  int after) {
+        // Does nothing.  Needed to implement TextWatcher.
+    }
+
+    @Override
+    public void onTextChanged(CharSequence s,
+                              int start,
+                              int before,
+                              int count) {
+        findAll();
+    }
+
+    @Override
+    public void afterTextChanged(Editable s) {
+        // Does nothing.  Needed to implement TextWatcher.
+    }
+
+}
diff --git a/core/java/android/webkit/SelectActionModeCallback.java b/core/java/android/webkit/SelectActionModeCallback.java
new file mode 100644
index 0000000..cf91902
--- /dev/null
+++ b/core/java/android/webkit/SelectActionModeCallback.java
@@ -0,0 +1,92 @@
+/*
+ * 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.webkit;
+
+import android.provider.Browser;
+import android.webkit.WebView;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+class SelectActionModeCallback implements ActionMode.Callback {
+    private WebView mWebView;
+    private View mTitleBar;
+    private ActionMode mActionMode;
+
+    void setWebView(WebView webView) {
+        mWebView = webView;
+    }
+
+    void setTitleBar(View v) { mTitleBar = v; }
+
+    void finish() {
+        mActionMode.finish();
+    }
+
+    // ActionMode.Callback implementation
+
+    @Override
+    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+        mode.getMenuInflater().inflate(com.android.internal.R.menu.webview_copy,
+                menu);
+        mode.setTitle(com.android.internal.R.string.textSelectionCABTitle);
+        mActionMode = mode;
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+        return true;
+    }
+
+    @Override
+    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+        switch(item.getItemId()) {
+            case android.R.id.copy:
+                mWebView.copySelection();
+                mode.finish();
+                break;
+
+            case com.android.internal.R.id.share:
+                String selection = mWebView.getSelection();
+                Browser.sendString(mWebView.getContext(), selection);
+                mode.finish();
+                break;
+
+            case com.android.internal.R.id.select_all:
+                mWebView.selectAll();
+                break;
+
+            case com.android.internal.R.id.find:
+                String sel= mWebView.getSelection();
+                mode.finish();
+                mWebView.showFindDialog(sel);
+                break;
+
+            default:
+                return false;
+        }
+        return true;
+    }
+
+    @Override
+    public void onDestroyActionMode(ActionMode mode) {
+        if (mTitleBar != null) mWebView.setEmbeddedTitleBar(mTitleBar);
+        mWebView.selectionDone();
+    }
+}
diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java
index 7c5f2b0..c1319e5 100644
--- a/core/java/android/webkit/URLUtil.java
+++ b/core/java/android/webkit/URLUtil.java
@@ -47,7 +47,7 @@
         String retVal = inUrl;
         WebAddress webAddress;
 
-        Log.v(LOGTAG, "guessURL before queueRequest: " + inUrl);
+        if (DebugFlags.URL_UTIL) Log.v(LOGTAG, "guessURL before queueRequest: " + inUrl);
 
         if (inUrl.length() == 0) return inUrl;
         if (inUrl.startsWith("about:")) return inUrl;
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index e83bef0..b2ba7e23 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -324,23 +324,6 @@
     }
 
     /**
-     * Tell the client that the selection has been initiated.
-     * @hide
-     */
-    public void onSelectionStart(WebView view) {
-        // By default we cancel the selection again, thus disabling
-        // text selection unless the chrome client supports it.
-        view.notifySelectDialogDismissed();
-    }
-
-    /**
-     * Tell the client that the selection has been copied or canceled.
-     * @hide
-     */
-    public void onSelectionDone(WebView view) {
-    }
-
-    /**
      * Tell the client that the page being viewed is web app capable,
      * i.e. has specified the fullscreen-web-app-capable meta tag.
      * @hide
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index abd1e5d..0ed5fc5 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -182,6 +182,7 @@
     private boolean         mShrinksStandaloneImagesToFit = false;
     private long            mMaximumDecodedImageSize = 0; // 0 means default
     private boolean         mPrivateBrowsingEnabled = false;
+    private boolean         mSyntheticLinksEnabled = true;
     // HTML5 API flags
     private boolean         mAppCacheEnabled = false;
     private boolean         mDatabaseEnabled = false;
@@ -1101,8 +1102,13 @@
     }
 
     /**
-     * TODO: need to add @Deprecated
+     * Set a custom path to plugins used by the WebView. This method is
+     * obsolete since each plugin is now loaded from its own package.
+     * @param pluginsPath String path to the directory containing plugins.
+     * @deprecated This method is no longer used as plugins are loaded from
+     * their own APK via the system's package manager.
      */
+    @Deprecated
     public synchronized void setPluginsPath(String pluginsPath) {
     }
 
@@ -1285,8 +1291,13 @@
     }
 
     /**
-     * TODO: need to add @Deprecated
+     * Returns the directory that contains the plugin libraries. This method is
+     * obsolete since each plugin is now loaded from its own package.
+     * @return An empty string.
+     * @deprecated This method is no longer used as plugins are loaded from
+     * their own APK via the system's package manager.
      */
+    @Deprecated
     public synchronized String getPluginsPath() {
         return "";
     }
@@ -1501,6 +1512,13 @@
         }
     }
 
+    synchronized void setSyntheticLinksEnabled(boolean flag) {
+        if (mSyntheticLinksEnabled != flag) {
+            mSyntheticLinksEnabled = flag;
+            postSync();
+        }
+    }
+
     int getDoubleTapToastCount() {
         return mDoubleTapToastCount;
     }
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 48c065a..6c11a7f 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -110,6 +110,11 @@
     // FIXME: This can be replaced with TextView.NO_FILTERS if that
     // is made public/protected.
     private static final InputFilter[] NO_FILTERS = new InputFilter[0];
+    // For keeping track of the fact that the delete key was pressed, so
+    // we can simply pass a delete key instead of calling deleteSelection.
+    private boolean mGotDelete;
+    private int mDelSelStart;
+    private int mDelSelEnd;
 
     /**
      * Create a new WebTextView.
@@ -153,13 +158,22 @@
             return true;
         }
         Spannable text = (Spannable) getText();
-        int oldLength = text.length();
+        int oldStart = Selection.getSelectionStart(text);
+        int oldEnd = Selection.getSelectionEnd(text);
         // Normally the delete key's dom events are sent via onTextChanged.
-        // However, if the length is zero, the text did not change, so we
-        // go ahead and pass the key down immediately.
-        if (KeyEvent.KEYCODE_DEL == keyCode && 0 == oldLength) {
-            sendDomEvent(event);
-            return true;
+        // However, if the cursor is at the beginning of the field, which
+        // includes the case where it has zero length, then the text is not
+        // changed, so send the events immediately.
+        if (KeyEvent.KEYCODE_DEL == keyCode) {
+            if (oldStart == 0 && oldEnd == 0) {
+                sendDomEvent(event);
+                return true;
+            }
+            if (down) {
+                mGotDelete = true;
+                mDelSelStart = oldStart;
+                mDelSelEnd = oldEnd;
+            }
         }
 
         if ((mSingle && KeyEvent.KEYCODE_ENTER == keyCode)) {
@@ -197,9 +211,8 @@
         if (getLayout() == null) {
             measure(mWidthSpec, mHeightSpec);
         }
-        int oldStart = Selection.getSelectionStart(text);
-        int oldEnd = Selection.getSelectionEnd(text);
 
+        int oldLength = text.length();
         boolean maxedOut = mMaxLength != -1 && oldLength == mMaxLength;
         // If we are at max length, and there is a selection rather than a
         // cursor, we need to store the text to compare later, since the key
@@ -411,17 +424,38 @@
         mPreChange = postChange;
         if (0 == count) {
             if (before > 0) {
+                // For this and all changes to the text, update our cache
+                updateCachedTextfield();
+                if (mGotDelete) {
+                    mGotDelete = false;
+                    int oldEnd = start + before;
+                    if (mDelSelEnd == oldEnd
+                            && (mDelSelStart == start
+                            || (mDelSelStart == oldEnd && before == 1))) {
+                        // If the selection is set up properly before the
+                        // delete, send the DOM events.
+                        sendDomEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
+                                KeyEvent.KEYCODE_DEL));
+                        sendDomEvent(new KeyEvent(KeyEvent.ACTION_UP,
+                                KeyEvent.KEYCODE_DEL));
+                        return;
+                    }
+                }
                 // This was simply a delete or a cut, so just delete the
                 // selection.
                 mWebView.deleteSelection(start, start + before);
-                // For this and all changes to the text, update our cache
-                updateCachedTextfield();
             }
+            mGotDelete = false;
             // before should never be negative, so whether it was a cut
             // (handled above), or before is 0, in which case nothing has
             // changed, we should return.
             return;
         }
+        // Ensure that this flag gets cleared, since with autocorrect on, a
+        // delete key press may have a more complex result than deleting one
+        // character or the existing selection, so it will not get cleared
+        // above.
+        mGotDelete = false;
         // Find the last character being replaced.  If it can be represented by
         // events, we will pass them to native (after replacing the beginning
         // of the changed text), so we can see javascript events.
@@ -593,8 +627,10 @@
      */
     /* package */ void remove() {
         // hide the soft keyboard when the edit text is out of focus
-        InputMethodManager.getInstance(mContext).hideSoftInputFromWindow(
-                getWindowToken(), 0);
+        InputMethodManager imm = InputMethodManager.getInstance(mContext);
+        if (imm.isActive(this)) {
+            imm.hideSoftInputFromWindow(getWindowToken(), 0);
+        }
         mWebView.removeView(this);
         mWebView.requestFocus();
     }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9597d8c..b83edc7 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -938,7 +938,7 @@
                         return;
                     }
 
-                    if (sGoogleApps.contains(packageName)) {
+                    if (sGoogleApps.contains(packageName) && mWebViewCore != null) {
                         if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
                             mWebViewCore.sendMessage(EventHub.ADD_PACKAGE_NAME, packageName);
                         } else {
@@ -975,7 +975,9 @@
             // Executes on the UI thread
             @Override
             protected void onPostExecute(Set<String> installedPackages) {
-                mWebViewCore.sendMessage(EventHub.ADD_PACKAGE_NAMES, installedPackages);
+                if (mWebViewCore != null) {
+                    mWebViewCore.sendMessage(EventHub.ADD_PACKAGE_NAMES, installedPackages);
+                }
             }
         };
         task.execute();
@@ -1796,11 +1798,11 @@
     /**
      * Returns true if private browsing is enabled in this WebView.
      */
-    public boolean isPrivateBrowsingEnabled () {
+    public boolean isPrivateBrowsingEnabled() {
         return getSettings().isPrivateBrowsingEnabled();
     }
 
-    private void startPrivateBrowsing () {
+    private void startPrivateBrowsing() {
         boolean wasPrivateBrowsingEnabled = isPrivateBrowsingEnabled();
 
         getSettings().setPrivateBrowsingEnabled(true);
@@ -1810,6 +1812,23 @@
         }
     }
 
+    /**
+     * Deletes any files that were created as a part of the last private
+     * browsing session and clears any internal state associated with that
+     * session. The consequences of calling this method while a private
+     * browsing session is active are unspecified.
+     * @param context The same context which was used to create the private
+     *                browsing WebView.
+     * @return True if the private browsing files were successfully deleted,
+     *         false otherwise.
+     * @hide pending API council approval.
+     */
+    public static boolean cleanupPrivateBrowsingFiles(Context context) {
+        return nativeCleanupPrivateBrowsingFiles(context.getFilesDir().getParent());
+    }
+
+    private static native boolean nativeCleanupPrivateBrowsingFiles(String dataDirectory);
+
     private boolean extendScroll(int y) {
         int finalY = mScroller.getFinalY();
         int newY = pinLocY(finalY + y);
@@ -2112,6 +2131,15 @@
      * @hide
      */
     public void setEmbeddedTitleBar(View v) {
+        if (null == v) {
+            // If one of our callbacks is holding onto the titlebar to replace
+            // it when its ActionMode ends, remove it.
+            if (mSelectCallback != null) {
+                mSelectCallback.setTitleBar(null);
+            } else if (mFindCallback != null) {
+                mFindCallback.setTitleBar(null);
+            }
+        }
         if (mTitleBar == v) return;
         if (mTitleBar != null) {
             removeView(mTitleBar);
@@ -2677,18 +2705,49 @@
     }
 
     /**
-     * @hide
+     * Start an ActionMode for finding text in this WebView.
+     * @param text If non-null, will be the initial text to search for.
+     *             Otherwise, the last String searched for in this WebView will
+     *             be used to start.
      */
-    public void setFindIsUp(boolean isUp) {
+    public void showFindDialog(String text) {
+        mFindCallback = new FindActionModeCallback(mContext);
+        setFindIsUp(true);
+        mFindCallback.setWebView(this);
+        View titleBar = mTitleBar;
+        // We do not want to show the embedded title bar during find or
+        // select, but keep track of it so that it can be replaced when the
+        // mode is exited.
+        setEmbeddedTitleBar(null);
+        mFindCallback.setTitleBar(titleBar);
+        startActionMode(mFindCallback);
+        if (text == null) {
+            text = mLastFind;
+        }
+        if (text != null) {
+            mFindCallback.setText(text);
+        }
+    }
+
+    /**
+     * Keep track of the find callback so that we can remove its titlebar if
+     * necessary.
+     */
+    private FindActionModeCallback mFindCallback;
+
+    /**
+     * Toggle whether the find dialog is showing, for both native and Java.
+     */
+    private void setFindIsUp(boolean isUp) {
         mFindIsUp = isUp;
         if (0 == mNativeClass) return; // client isn't initialized
         nativeSetFindIsUp(isUp);
     }
 
     /**
-     * @hide
+     * Return the index of the currently highlighted match.
      */
-    public int findIndex() {
+    int findIndex() {
         if (0 == mNativeClass) return -1;
         return nativeFindIndex();
     }
@@ -2697,8 +2756,8 @@
     // or not we draw the highlights for matches.
     private boolean mFindIsUp;
 
-    // Keep track of the last string sent, so we can search again after an
-    // orientation change or the dismissal of the soft keyboard.
+    // Keep track of the last string sent, so we can search again when find is
+    // reopened.
     private String mLastFind;
 
     /**
@@ -2755,7 +2814,6 @@
      * Clear the highlighting surrounding text matches created by findAll.
      */
     public void clearMatches() {
-        mLastFind = "";
         if (mNativeClass == 0)
             return;
         nativeSetFindIsEmpty();
@@ -2763,9 +2821,10 @@
     }
 
     /**
-     * @hide
+     * Called when the find ActionMode ends.
      */
-    public void notifyFindDialogDismissed() {
+    void notifyFindDialogDismissed() {
+        mFindCallback = null;
         if (mWebViewCore == null) {
             return;
         }
@@ -3357,14 +3416,18 @@
         setUpSelect();
         if (mNativeClass != 0 && nativeWordSelection(x, y)) {
             nativeSetExtendSelection();
-            WebChromeClient client = getWebChromeClient();
-            if (client != null) client.onSelectionStart(this);
             return true;
         }
-        notifySelectDialogDismissed();
+        selectionDone();
         return false;
     }
 
+    /**
+     * Keep track of the Callback so we can end its ActionMode or remove its
+     * titlebar.
+     */
+    private SelectActionModeCallback mSelectCallback;
+
     private boolean didUpdateTextViewBounds(boolean allowIntersect) {
         Rect contentBounds = nativeFocusCandidateNodeBounds();
         Rect vBox = contentToViewRect(contentBounds);
@@ -3638,8 +3701,10 @@
     private void hideSoftKeyboard() {
         InputMethodManager imm = (InputMethodManager)
                 getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-
-        imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
+        if (imm.isActive(this)
+                || (inEditingMode() && imm.isActive(mWebTextView))) {
+            imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
+        }
     }
 
     /*
@@ -4111,10 +4176,7 @@
         return false;
     }
 
-    /**
-     * @hide pending API council approval.
-     */
-    public void setUpSelect() {
+    private void setUpSelect() {
         if (0 == mNativeClass) return; // client isn't initialized
         if (inFullScreenMode()) return;
         if (mSelectingText) return;
@@ -4135,6 +4197,15 @@
             mSelectY = mScrollY + getViewHeightWithTitle() / 2;
         }
         nativeHideCursor();
+        mSelectCallback = new SelectActionModeCallback();
+        mSelectCallback.setWebView(this);
+        View titleBar = mTitleBar;
+        // We do not want to show the embedded title bar during find or
+        // select, but keep track of it so that it can be replaced when the
+        // mode is exited.
+        setEmbeddedTitleBar(null);
+        mSelectCallback.setTitleBar(titleBar);
+        startActionMode(mSelectCallback);
     }
 
     /**
@@ -4146,9 +4217,9 @@
     }
 
     /**
-     * @hide pending API council approval.
+     * Select all of the text in this WebView.
      */
-    public void selectAll() {
+    void selectAll() {
         if (0 == mNativeClass) return; // client isn't initialized
         if (inFullScreenMode()) return;
         if (!mSelectingText) setUpSelect();
@@ -4159,36 +4230,24 @@
     }
 
     /**
-     * @hide pending API council approval.
+     * Called when the selection has been removed.
      */
-    public boolean selectDialogIsUp() {
-        return mSelectingText;
-    }
-
-    /**
-     * @hide pending API council approval.
-     */
-    public void notifySelectDialogDismissed() {
-        mSelectingText = false;
-        WebViewCore.resumeUpdatePicture(mWebViewCore);
-    }
-
-    /**
-     * @hide pending API council approval.
-     */
-    public void selectionDone() {
+    void selectionDone() {
         if (mSelectingText) {
-            WebChromeClient client = getWebChromeClient();
-            if (client != null) client.onSelectionDone(this);
+            mSelectingText = false;
+            // finish is idempotent, so this is fine even if selectionDone was
+            // called by mSelectCallback.onDestroyActionMode
+            mSelectCallback.finish();
+            mSelectCallback = null;
+            WebViewCore.resumeUpdatePicture(mWebViewCore);
             invalidate(); // redraw without selection
-            notifySelectDialogDismissed();
         }
     }
 
     /**
-     * @hide pending API council approval.
+     * Copy the selection to the clipboard
      */
-    public boolean copySelection() {
+    boolean copySelection() {
         boolean copiedSomething = false;
         String selection = getSelection();
         if (selection != "") {
@@ -4208,9 +4267,9 @@
     }
 
     /**
-     * @hide pending API council approval.
+     * Returns the currently highlighted text as a string.
      */
-    public String getSelection() {
+    String getSelection() {
         if (mNativeClass == 0) return "";
         return nativeGetSelection();
     }
@@ -6565,8 +6624,8 @@
 
                 case FIND_AGAIN:
                     // Ignore if find has been dismissed.
-                    if (mFindIsUp) {
-                        findAll(mLastFind);
+                    if (mFindIsUp && mFindCallback != null) {
+                        mFindCallback.findAll();
                     }
                     break;
 
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 02c7210..1f8eeba 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -89,6 +89,7 @@
      * @deprecated This method is no longer called. When the WebView encounters
      *             a redirect loop, it will cancel the load.
      */
+    @Deprecated
     public void onTooManyRedirects(WebView view, Message cancelMsg,
             Message continueMsg) {
         cancelMsg.sendToTarget();
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 197ad9ee..d87f55f 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -16,12 +16,11 @@
 
 package android.widget;
 
-import com.android.internal.R;
-
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.TransitionDrawable;
@@ -57,6 +56,8 @@
 import android.view.inputmethod.InputConnectionWrapper;
 import android.view.inputmethod.InputMethodManager;
 
+import com.android.internal.R;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -4235,7 +4236,11 @@
 
     /**
      * When set to a non-zero value, the cache color hint indicates that this list is always drawn
-     * on top of a solid, single-color, opaque background
+     * on top of a solid, single-color, opaque background.
+     *
+     * Zero means that what's behind this object is translucent (non solid) or is not made of a
+     * single color. This hint will not affect any existing background drawable set on this view (
+     * typically set via {@link #setBackgroundDrawable(Drawable)}).
      *
      * @param color The background color
      */
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index e20fee5..ab75420 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -808,7 +808,6 @@
             mNextSelectedPosition = INVALID_POSITION;
             mNextSelectedRowId = INVALID_ROW_ID;
             mNeedSync = false;
-            checkSelectionChanged();
 
             checkFocus();
             requestLayout();
@@ -819,13 +818,21 @@
         }
     }
 
-    private class SelectionNotifier extends Handler implements Runnable {
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        removeCallbacks(mSelectionNotifier);
+    }
+
+    private class SelectionNotifier implements Runnable {
         public void run() {
             if (mDataChanged) {
                 // Data has changed between when this SelectionNotifier
                 // was posted and now. We need to wait until the AdapterView
                 // has been synched to the new data.
-                post(this);
+                if (getAdapter() != null) {
+                    post(this);
+                }
             } else {
                 fireOnSelected();
             }
@@ -842,7 +849,7 @@
                 if (mSelectionNotifier == null) {
                     mSelectionNotifier = new SelectionNotifier();
                 }
-                mSelectionNotifier.post(mSelectionNotifier);
+                post(mSelectionNotifier);
             } else {
                 fireOnSelected();
             }
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 12ff292..b464fef 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -706,7 +706,8 @@
             if (mItemClickListener != null) {
                 final DropDownListView list = mDropDownList;
                 final View child = list.getChildAt(position - list.getFirstVisiblePosition());
-                mItemClickListener.onItemClick(list, child, position, child.getId());
+                final ListAdapter adapter = list.getAdapter();
+                mItemClickListener.onItemClick(list, child, position, adapter.getItemId(position));
             }
             return true;
         }
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 58c2613..c0cbb19 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -53,25 +53,93 @@
      */
     public static final int MODE_DROPDOWN = 1;
     
+    /**
+     * Use the theme-supplied value to select the dropdown mode.
+     */
+    private static final int MODE_THEME = -1;
+    
     private SpinnerPopup mPopup;
     private DropDownAdapter mTempAdapter;
-    
+
+    /**
+     * Construct a new spinner with the given context's theme.
+     *
+     * @param context The Context the view is running in, through which it can
+     *        access the current theme, resources, etc.
+     */
     public Spinner(Context context) {
         this(context, null);
     }
 
+    /**
+     * Construct a new spinner with the given context's theme and the supplied
+     * mode of displaying choices. <code>mode</code> may be one of
+     * {@link #MODE_DIALOG} or {@link #MODE_DROPDOWN}.
+     *
+     * @param context The Context the view is running in, through which it can
+     *        access the current theme, resources, etc.
+     * @param mode Constant describing how the user will select choices from the spinner.
+     * 
+     * @see #MODE_DIALOG
+     * @see #MODE_DROPDOWN
+     */
+    public Spinner(Context context, int mode) {
+        this(context, null, com.android.internal.R.attr.spinnerStyle, mode);
+    }
+
+    /**
+     * Construct a new spinner with the given context's theme and the supplied attribute set.
+     *
+     * @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.
+     */
     public Spinner(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.spinnerStyle);
     }
 
+    /**
+     * Construct a new spinner with the given context's theme, the supplied attribute set,
+     * and default style.
+     *
+     * @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.
+     */
     public Spinner(Context context, AttributeSet attrs, int defStyle) {
+        this(context, attrs, defStyle, MODE_THEME);
+    }
+
+    /**
+     * 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 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 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);
 
         TypedArray a = context.obtainStyledAttributes(attrs,
                 com.android.internal.R.styleable.Spinner, defStyle, 0);
-        
-        final int mode = a.getInt(com.android.internal.R.styleable.Spinner_spinnerMode,
-                MODE_DIALOG);
+
+        if (mode == MODE_THEME) {
+            mode = a.getInt(com.android.internal.R.styleable.Spinner_spinnerMode, MODE_DIALOG);
+        }
         
         switch (mode) {
         case MODE_DIALOG: {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 961c782..9961438 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -715,10 +715,8 @@
 
         BufferType bufferType = BufferType.EDITABLE;
 
-        if ((inputType&(EditorInfo.TYPE_MASK_CLASS
-                |EditorInfo.TYPE_MASK_VARIATION))
-                == (EditorInfo.TYPE_CLASS_TEXT
-                        |EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)) {
+        if ((inputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION))
+                == (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)) {
             password = true;
         }
 
@@ -806,6 +804,9 @@
         } else if (editable) {
             mInput = TextKeyListener.getInstance();
             mInputType = EditorInfo.TYPE_CLASS_TEXT;
+            if (!singleLine) {
+                mInputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
+            }
         } else {
             mInput = null;
 
@@ -2991,8 +2992,7 @@
         final int cls = type & EditorInfo.TYPE_MASK_CLASS;
         KeyListener input;
         if (cls == EditorInfo.TYPE_CLASS_TEXT) {
-            boolean autotext = (type & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT)
-                    != 0;
+            boolean autotext = (type & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) != 0;
             TextKeyListener.Capitalize cap;
             if ((type & EditorInfo.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0) {
                 cap = TextKeyListener.Capitalize.CHARACTERS;
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
new file mode 100644
index 0000000..5c2d692
--- /dev/null
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -0,0 +1,207 @@
+/*
+ * 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.internal.app;
+
+import android.app.Activity;
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.app.ListFragment;
+import android.app.backup.BackupManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import com.android.internal.R;
+
+import java.text.Collator;
+import java.util.Arrays;
+import java.util.Locale;
+
+public class LocalePicker extends ListFragment {
+    private static final String TAG = "LocalePicker";
+    private static final boolean DEBUG = false;
+
+    public static interface LocaleSelectionListener {
+        // You can add any argument if you really need it...
+        public void onLocaleSelected();
+    }
+
+    Loc[] mLocales;
+    String[] mSpecialLocaleCodes;
+    String[] mSpecialLocaleNames;
+
+
+    LocaleSelectionListener mListener;  // default to null
+
+    private static class Loc implements Comparable<Loc> {
+        static Collator sCollator = Collator.getInstance();
+
+        String label;
+        Locale locale;
+
+        public Loc(String label, Locale locale) {
+            this.label = label;
+            this.locale = locale;
+        }
+
+        @Override
+        public String toString() {
+            return this.label;
+        }
+
+        @Override
+        public int compareTo(Loc another) {
+            return sCollator.compare(this.label, another.label);
+        }
+    }
+
+    private void setUpLocaleList() {
+        final Activity activity = getActivity();
+        final Resources resources = activity.getResources();
+        mSpecialLocaleCodes = resources.getStringArray(R.array.special_locale_codes);
+        mSpecialLocaleNames = resources.getStringArray(R.array.special_locale_names);
+
+        final String[] locales = activity.getAssets().getLocales();
+        Arrays.sort(locales);
+        final int origSize = locales.length;
+        Loc[] preprocess = new Loc[origSize];
+        int finalSize = 0;
+        for (int i = 0 ; i < origSize; i++ ) {
+            String s = locales[i];
+            int len = s.length();
+            if (len == 5) {
+                String language = s.substring(0, 2);
+                String country = s.substring(3, 5);
+                Locale l = new Locale(language, country);
+
+                if (finalSize == 0) {
+                    if (DEBUG) {
+                        Log.v(TAG, "adding initial "+ toTitleCase(l.getDisplayLanguage(l)));
+                    }
+                    preprocess[finalSize++] =
+                            new Loc(toTitleCase(l.getDisplayLanguage(l)), l);
+                } else {
+                    // check previous entry:
+                    //  same lang and a country -> upgrade to full name and
+                    //    insert ours with full name
+                    //  diff lang -> insert ours with lang-only name
+                    if (preprocess[finalSize-1].locale.getLanguage().equals(
+                            language)) {
+                        if (DEBUG) {
+                            Log.v(TAG, "backing up and fixing "+
+                                    preprocess[finalSize-1].label+" to "+
+                                    getDisplayName(preprocess[finalSize-1].locale));
+                        }
+                        preprocess[finalSize-1].label = toTitleCase(
+                                getDisplayName(preprocess[finalSize-1].locale));
+                        if (DEBUG) {
+                            Log.v(TAG, "  and adding "+ toTitleCase(getDisplayName(l)));
+                        }
+                        preprocess[finalSize++] =
+                                new Loc(toTitleCase(getDisplayName(l)), l);
+                    } else {
+                        String displayName;
+                        if (s.equals("zz_ZZ")) {
+                            displayName = "Pseudo...";
+                        } else {
+                            displayName = toTitleCase(l.getDisplayLanguage(l));
+                        }
+                        if (DEBUG) {
+                            Log.v(TAG, "adding "+displayName);
+                        }
+                        preprocess[finalSize++] = new Loc(displayName, l);
+                    }
+                }
+            }
+        }
+        mLocales = new Loc[finalSize];
+        for (int i = 0; i < finalSize ; i++) {
+            mLocales[i] = preprocess[i];
+        }
+        Arrays.sort(mLocales);
+        final int layoutId = R.layout.locale_picker_item;
+        final int fieldId = R.id.locale;
+        final ArrayAdapter<Loc> adapter =
+                new ArrayAdapter<Loc>(activity, layoutId, fieldId, mLocales);
+        setListAdapter(adapter);
+    }
+
+    @Override
+    public void onActivityCreated(final Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        setUpLocaleList();
+    }
+
+    public void setLocaleSelectionListener(LocaleSelectionListener listener) {
+        mListener = listener;
+    }
+
+    private static String toTitleCase(String s) {
+        if (s.length() == 0) {
+            return s;
+        }
+
+        return Character.toUpperCase(s.charAt(0)) + s.substring(1);
+    }
+
+    private String getDisplayName(Locale l) {
+        String code = l.toString();
+
+        for (int i = 0; i < mSpecialLocaleCodes.length; i++) {
+            if (mSpecialLocaleCodes[i].equals(code)) {
+                return mSpecialLocaleNames[i];
+            }
+        }
+
+        return l.getDisplayName(l);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        getListView().requestFocus();
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+        try {
+            IActivityManager am = ActivityManagerNative.getDefault();
+            Configuration config = am.getConfiguration();
+
+            Loc loc = mLocales[position];
+            config.locale = loc.locale;
+
+            // indicate this isn't some passing default - the user wants this remembered
+            config.userSetLocale = true;
+
+            am.updateConfiguration(config);
+            // Trigger the dirty bit for the Settings Provider.
+            BackupManager.dataChanged("com.android.providers.settings");
+        } catch (RemoteException e) {
+            // Intentionally left blank
+        }
+
+        if (mListener != null) {
+            mListener.onLocaleSelected();
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/os/SamplingProfilerIntegration.java b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
index 38362c1..b87ac90 100644
--- a/core/java/com/android/internal/os/SamplingProfilerIntegration.java
+++ b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
@@ -16,16 +16,19 @@
 
 package com.android.internal.os;
 
-import android.content.pm.PackageInfo;
 import dalvik.system.SamplingProfiler;
 
+import java.io.BufferedOutputStream;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.PrintStream;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import android.content.pm.PackageInfo;
 import android.util.Log;
 import android.os.*;
 
@@ -41,7 +44,7 @@
     private static final boolean enabled;
     private static final Executor snapshotWriter;
     private static final int samplingProfilerHz;
-    
+
     /** Whether or not we've created the snapshots dir. */
     private static boolean dirMade = false;
 
@@ -61,6 +64,8 @@
         }
     }
 
+    private static SamplingProfiler INSTANCE;
+
     /**
      * Is profiling enabled?
      */
@@ -72,15 +77,22 @@
      * Starts the profiler if profiling is enabled.
      */
     public static void start() {
-        if (!enabled) return;
-        SamplingProfiler.getInstance().start(samplingProfilerHz);
+        if (!enabled) {
+            return;
+        }
+        ThreadGroup group = Thread.currentThread().getThreadGroup();
+        SamplingProfiler.ThreadSet threadSet = SamplingProfiler.newThreadGroupTheadSet(group);
+        INSTANCE = new SamplingProfiler(4, threadSet);
+        INSTANCE.start(samplingProfilerHz);
     }
 
     /**
      * Writes a snapshot if profiling is enabled.
      */
     public static void writeSnapshot(final String processName, final PackageInfo packageInfo) {
-        if (!enabled) return;
+        if (!enabled) {
+            return;
+        }
 
         /*
          * If we're already writing a snapshot, don't bother enqueueing another
@@ -122,18 +134,22 @@
      * Writes the zygote's snapshot to internal storage if profiling is enabled.
      */
     public static void writeZygoteSnapshot() {
-        if (!enabled) return;
+        if (!enabled) {
+            return;
+        }
         writeSnapshot("zygote", null);
+        INSTANCE.shutdown();
+        INSTANCE = null;
     }
 
     /**
      * pass in PackageInfo to retrieve various values for snapshot header
      */
     private static void writeSnapshot(String dir, String processName, PackageInfo packageInfo) {
-        byte[] snapshot = SamplingProfiler.getInstance().snapshot();
-        if (snapshot == null) {
+        if (!enabled) {
             return;
         }
+        INSTANCE.stop();
 
         /*
          * We use the current time as a unique ID. We can't use a counter
@@ -143,21 +159,22 @@
         long start = System.currentTimeMillis();
         String name = processName.replaceAll(":", ".");
         String path = dir + "/" + name + "-" +System.currentTimeMillis() + ".snapshot";
-        FileOutputStream out = null;
+        PrintStream out = null;
         try {
-            out = new FileOutputStream(path);
-            generateSnapshotHeader(name, packageInfo, out);
-            out.write(snapshot);
+            out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path)));
         } catch (IOException e) {
-            Log.e(TAG, "Error writing snapshot.", e);
+            Log.e(TAG, "Could not open " + path + ":" + e);
+            return;
+        }
+        try {
+            generateSnapshotHeader(name, packageInfo, out);
+            INSTANCE.writeHprofData(out);
         } finally {
-            try {
-                if(out != null) {
-                    out.close();
-                }
-            } catch (IOException ex) {
-                // let it go.
-            }
+            out.close();
+        }
+        if (out.checkError()) {
+            Log.e(TAG, "Error writing snapshot.");
+            return;
         }
         // set file readable to the world so that SamplingProfilerService
         // can put it to dropbox
@@ -179,16 +196,16 @@
      * <the actual snapshot content begins here...>
      */
     private static void generateSnapshotHeader(String processName, PackageInfo packageInfo,
-            FileOutputStream out) throws IOException {
+            PrintStream out) {
         // profiler version
-        out.write("Version: 1\n".getBytes());
-        out.write(("Process: " + processName + "\n").getBytes());
-        if(packageInfo != null) {
-            out.write(("Package: " + packageInfo.packageName + "\n").getBytes());
-            out.write(("Package-Version: " + packageInfo.versionCode + "\n").getBytes());
+        out.println("Version: 2");
+        out.println("Process: " + processName);
+        if (packageInfo != null) {
+            out.println("Package: " + packageInfo.packageName);
+            out.println("Package-Version: " + packageInfo.versionCode);
         }
-        out.write(("Build: " + Build.FINGERPRINT + "\n").getBytes());
+        out.println("Build: " + Build.FINGERPRINT);
         // single blank line means the end of snapshot header.
-        out.write("\n".getBytes());
+        out.println();
     }
 }
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 9c84e0e..f0f3387 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -579,12 +579,8 @@
             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                 SystemClock.uptimeMillis());
 
-            if (SamplingProfilerIntegration.isEnabled()) {
-                SamplingProfiler sp = SamplingProfiler.getInstance();
-                sp.pause();
-                SamplingProfilerIntegration.writeZygoteSnapshot();
-                sp.shutDown();
-            }
+            // Finish profiling the zygote initialization.
+            SamplingProfilerIntegration.writeZygoteSnapshot();
 
             // Do an initial gc to clean up after startup
             gc();
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
index a221faf..af0438c6 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
@@ -75,6 +75,13 @@
         setEnabled(itemData.isEnabled());
     }
 
+    @Override
+    public void setEnabled(boolean enabled) {
+        super.setEnabled(enabled);
+        mImageButton.setEnabled(enabled);
+        mTextButton.setEnabled(enabled);
+    }
+
     public void onClick(View v) {
         if (mItemInvoker != null) {
             mItemInvoker.invokeItem(mItemData);
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index d5a9979..939f118 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -19,8 +19,10 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.graphics.RectF;
 import android.graphics.Paint.FontMetricsInt;
 import android.util.Log;
+import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -29,17 +31,45 @@
 import java.util.ArrayList;
 
 public class PointerLocationView extends View {
+    private static final String TAG = "Pointer";
+    
     public static class PointerState {
-        private final ArrayList<Float> mXs = new ArrayList<Float>();
-        private final ArrayList<Float> mYs = new ArrayList<Float>();
+        // Trace of previous points.
+        private float[] mTraceX = new float[32];
+        private float[] mTraceY = new float[32];
+        private int mTraceCount;
+        
+        // True if the pointer is down.
         private boolean mCurDown;
-        private int mCurX;
-        private int mCurY;
-        private float mCurPressure;
-        private float mCurSize;
-        private int mCurWidth;
+        
+        // Most recent coordinates.
+        private MotionEvent.PointerCoords mCoords = new MotionEvent.PointerCoords();
+        
+        // Most recent velocity.
         private float mXVelocity;
         private float mYVelocity;
+        
+        public void clearTrace() {
+            mTraceCount = 0;
+        }
+        
+        public void addTrace(float x, float y) {
+            int traceCapacity = mTraceX.length;
+            if (mTraceCount == traceCapacity) {
+                traceCapacity *= 2;
+                float[] newTraceX = new float[traceCapacity];
+                System.arraycopy(mTraceX, 0, newTraceX, 0, mTraceCount);
+                mTraceX = newTraceX;
+                
+                float[] newTraceY = new float[traceCapacity];
+                System.arraycopy(mTraceY, 0, newTraceY, 0, mTraceCount);
+                mTraceY = newTraceY;
+            }
+            
+            mTraceX[mTraceCount] = x;
+            mTraceY[mTraceCount] = y;
+            mTraceCount += 1;
+        }
     }
 
     private final ViewConfiguration mVC;
@@ -54,11 +84,12 @@
     private boolean mCurDown;
     private int mCurNumPointers;
     private int mMaxNumPointers;
-    private final ArrayList<PointerState> mPointers
-             = new ArrayList<PointerState>();
+    private final ArrayList<PointerState> mPointers = new ArrayList<PointerState>();
     
     private final VelocityTracker mVelocity;
     
+    private final FasterStringBuilder mText = new FasterStringBuilder();
+    
     private boolean mPrintCoords = true;
     
     public PointerLocationView(Context c) {
@@ -94,6 +125,18 @@
         mPointers.add(ps);
         
         mVelocity = VelocityTracker.obtain();
+        
+        logInputDeviceCapabilities();
+    }
+    
+    private void logInputDeviceCapabilities() {
+        int[] deviceIds = InputDevice.getDeviceIds();
+        for (int i = 0; i < deviceIds.length; i++) {
+            InputDevice device = InputDevice.getDevice(deviceIds[i]);
+            if (device != null) {
+                Log.i(TAG, device.toString());
+            }
+        }
     }
 
     public void setPrintCoords(boolean state) {
@@ -113,6 +156,21 @@
                     + " bottom=" + mTextMetrics.bottom);
         }
     }
+    
+    // Draw an oval.  When angle is 0 radians, orients the major axis vertically,
+    // angles less than or greater than 0 radians rotate the major axis left or right.
+    private RectF mReusableOvalRect = new RectF();
+    private void drawOval(Canvas canvas, float x, float y, float major, float minor,
+            float angle, Paint paint) {
+        canvas.save(Canvas.MATRIX_SAVE_FLAG);
+        canvas.rotate((float) (angle * 180 / Math.PI), x, y);
+        mReusableOvalRect.left = x - minor / 2;
+        mReusableOvalRect.right = x + minor / 2;
+        mReusableOvalRect.top = y - major / 2;
+        mReusableOvalRect.bottom = y + major / 2;
+        canvas.drawOval(mReusableOvalRect, paint);
+        canvas.restore();
+    }
 
     @Override
     protected void onDraw(Canvas canvas) {
@@ -124,76 +182,80 @@
             
             final int NP = mPointers.size();
             
+            // Labels
             if (NP > 0) {
                 final PointerState ps = mPointers.get(0);
                 canvas.drawRect(0, 0, itemW-1, bottom,mTextBackgroundPaint);
-                canvas.drawText("P: " + mCurNumPointers + " / " + mMaxNumPointers,
-                        1, base, mTextPaint);
+                canvas.drawText(mText.clear()
+                        .append("P: ").append(mCurNumPointers)
+                        .append(" / ").append(mMaxNumPointers)
+                        .toString(), 1, base, mTextPaint);
                 
-                final int N = ps.mXs.size();
+                final int N = ps.mTraceCount;
                 if ((mCurDown && ps.mCurDown) || N == 0) {
                     canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom, mTextBackgroundPaint);
-                    canvas.drawText("X: " + ps.mCurX, 1 + itemW, base, mTextPaint);
+                    canvas.drawText(mText.clear()
+                            .append("X: ").append(ps.mCoords.x, 1)
+                            .toString(), 1 + itemW, base, mTextPaint);
                     canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom, mTextBackgroundPaint);
-                    canvas.drawText("Y: " + ps.mCurY, 1 + itemW * 2, base, mTextPaint);
+                    canvas.drawText(mText.clear()
+                            .append("Y: ").append(ps.mCoords.y, 1)
+                            .toString(), 1 + itemW * 2, base, mTextPaint);
                 } else {
-                    float dx = ps.mXs.get(N-1) - ps.mXs.get(0);
-                    float dy = ps.mYs.get(N-1) - ps.mYs.get(0);
+                    float dx = ps.mTraceX[N - 1] - ps.mTraceX[0];
+                    float dy = ps.mTraceY[N - 1] - ps.mTraceY[0];
                     canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom,
                             Math.abs(dx) < mVC.getScaledTouchSlop()
                             ? mTextBackgroundPaint : mTextLevelPaint);
-                    canvas.drawText("dX: " + String.format("%.1f", dx), 1 + itemW, base, mTextPaint);
+                    canvas.drawText(mText.clear()
+                            .append("dX: ").append(dx, 1)
+                            .toString(), 1 + itemW, base, mTextPaint);
                     canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom,
                             Math.abs(dy) < mVC.getScaledTouchSlop()
                             ? mTextBackgroundPaint : mTextLevelPaint);
-                    canvas.drawText("dY: " + String.format("%.1f", dy), 1 + itemW * 2, base, mTextPaint);
+                    canvas.drawText(mText.clear()
+                            .append("dY: ").append(dy, 1)
+                            .toString(), 1 + itemW * 2, base, mTextPaint);
                 }
                 
                 canvas.drawRect(itemW * 3, 0, (itemW * 4) - 1, bottom, mTextBackgroundPaint);
-                int velocity = (int) (ps.mXVelocity * 1000);
-                canvas.drawText("Xv: " + velocity, 1 + itemW * 3, base, mTextPaint);
+                canvas.drawText(mText.clear()
+                        .append("Xv: ").append(ps.mXVelocity, 3)
+                        .toString(), 1 + itemW * 3, base, mTextPaint);
                 
                 canvas.drawRect(itemW * 4, 0, (itemW * 5) - 1, bottom, mTextBackgroundPaint);
-                velocity = (int) (ps.mYVelocity * 1000);
-                canvas.drawText("Yv: " + velocity, 1 + itemW * 4, base, mTextPaint);
+                canvas.drawText(mText.clear()
+                        .append("Yv: ").append(ps.mYVelocity, 3)
+                        .toString(), 1 + itemW * 4, base, mTextPaint);
                 
                 canvas.drawRect(itemW * 5, 0, (itemW * 6) - 1, bottom, mTextBackgroundPaint);
-                canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCurPressure * itemW) - 1,
+                canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCoords.pressure * itemW) - 1,
                         bottom, mTextLevelPaint);
-                canvas.drawText("Prs: " + String.format("%.2f", ps.mCurPressure), 1 + itemW * 5,
-                        base, mTextPaint);
+                canvas.drawText(mText.clear()
+                        .append("Prs: ").append(ps.mCoords.pressure, 2)
+                        .toString(), 1 + itemW * 5, base, mTextPaint);
                 
                 canvas.drawRect(itemW * 6, 0, w, bottom, mTextBackgroundPaint);
-                canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCurSize * itemW) - 1,
+                canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCoords.size * itemW) - 1,
                         bottom, mTextLevelPaint);
-                canvas.drawText("Size: " + String.format("%.2f", ps.mCurSize), 1 + itemW * 6,
-                        base, mTextPaint);
+                canvas.drawText(mText.clear()
+                        .append("Size: ").append(ps.mCoords.size, 2)
+                        .toString(), 1 + itemW * 6, base, mTextPaint);
             }
             
-            for (int p=0; p<NP; p++) {
+            // Pointer trace.
+            for (int p = 0; p < NP; p++) {
                 final PointerState ps = mPointers.get(p);
                 
-                if (mCurDown && ps.mCurDown) {
-                    canvas.drawLine(0, (int)ps.mCurY, getWidth(), (int)ps.mCurY, mTargetPaint);
-                    canvas.drawLine((int)ps.mCurX, 0, (int)ps.mCurX, getHeight(), mTargetPaint);
-                    int pressureLevel = (int)(ps.mCurPressure*255);
-                    mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);
-                    canvas.drawPoint(ps.mCurX, ps.mCurY, mPaint);
-                    canvas.drawCircle(ps.mCurX, ps.mCurY, ps.mCurWidth, mPaint);
-                }
-            }
-            
-            for (int p=0; p<NP; p++) {
-                final PointerState ps = mPointers.get(p);
-                
-                final int N = ps.mXs.size();
-                float lastX=0, lastY=0;
+                // Draw path.
+                final int N = ps.mTraceCount;
+                float lastX = 0, lastY = 0;
                 boolean haveLast = false;
                 boolean drawn = false;
                 mPaint.setARGB(255, 128, 255, 255);
-                for (int i=0; i<N; i++) {
-                    float x = ps.mXs.get(i);
-                    float y = ps.mYs.get(i);
+                for (int i=0; i < N; i++) {
+                    float x = ps.mTraceX[i];
+                    float y = ps.mTraceY[i];
                     if (Float.isNaN(x)) {
                         haveLast = false;
                         continue;
@@ -208,21 +270,57 @@
                     haveLast = true;
                 }
                 
+                // Draw velocity vector.
                 if (drawn) {
                     mPaint.setARGB(255, 255, 64, 128);
-                    float xVel = ps.mXVelocity * (1000/60);
-                    float yVel = ps.mYVelocity * (1000/60);
-                    canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);
+                    float xVel = ps.mXVelocity * (1000 / 60);
+                    float yVel = ps.mYVelocity * (1000 / 60);
+                    canvas.drawLine(lastX, lastY, lastX + xVel, lastY + yVel, mPaint);
+                }
+                
+                if (mCurDown && ps.mCurDown) {
+                    // Draw crosshairs.
+                    canvas.drawLine(0, ps.mCoords.y, getWidth(), ps.mCoords.y, mTargetPaint);
+                    canvas.drawLine(ps.mCoords.x, 0, ps.mCoords.x, getHeight(), mTargetPaint);
+                    
+                    // Draw current point.
+                    int pressureLevel = (int)(ps.mCoords.pressure * 255);
+                    mPaint.setARGB(255, pressureLevel, 255, 255 - pressureLevel);
+                    canvas.drawPoint(ps.mCoords.x, ps.mCoords.y, mPaint);
+                    
+                    // Draw current touch ellipse.
+                    mPaint.setARGB(255, pressureLevel, 255 - pressureLevel, 128);
+                    drawOval(canvas, ps.mCoords.x, ps.mCoords.y, ps.mCoords.touchMajor,
+                            ps.mCoords.touchMinor, ps.mCoords.orientation, mPaint);
+                    
+                    // Draw current tool ellipse.
+                    mPaint.setARGB(255, pressureLevel, 128, 255 - pressureLevel);
+                    drawOval(canvas, ps.mCoords.x, ps.mCoords.y, ps.mCoords.toolMajor,
+                            ps.mCoords.toolMinor, ps.mCoords.orientation, mPaint);
                 }
             }
         }
     }
+    
+    private void logPointerCoords(MotionEvent.PointerCoords coords, int id) {
+        Log.i(TAG, mText.clear()
+                .append("Pointer ").append(id + 1)
+                .append(": (").append(coords.x, 3).append(", ").append(coords.y, 3)
+                .append(") Pressure=").append(coords.pressure, 3)
+                .append(" Size=").append(coords.size, 3)
+                .append(" TouchMajor=").append(coords.touchMajor, 3)
+                .append(" TouchMinor=").append(coords.touchMinor, 3)
+                .append(" ToolMajor=").append(coords.toolMajor, 3)
+                .append(" ToolMinor=").append(coords.toolMinor, 3)
+                .append(" Orientation=").append((float)(coords.orientation * 180 / Math.PI), 1)
+                .append("deg").toString());
+    }
 
     public void addTouchEvent(MotionEvent event) {
         synchronized (mPointers) {
             int action = event.getAction();
             
-            //Log.i("Pointer", "Motion: action=0x" + Integer.toHexString(action)
+            //Log.i(TAG, "Motion: action=0x" + Integer.toHexString(action)
             //        + " pointers=" + event.getPointerCount());
             
             int NP = mPointers.size();
@@ -235,35 +333,33 @@
             //} else {
             //    mRect.setEmpty();
             //}
-            if (action == MotionEvent.ACTION_DOWN) {
-                mVelocity.clear();
+            if (action == MotionEvent.ACTION_DOWN
+                    || (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
+                final int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
+                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; // will be 0 for down
+                if (action == MotionEvent.ACTION_DOWN) {
+                    for (int p=0; p<NP; p++) {
+                        final PointerState ps = mPointers.get(p);
+                        ps.clearTrace();
+                        ps.mCurDown = false;
+                    }
+                    mCurDown = true;
+                    mMaxNumPointers = 0;
+                    mVelocity.clear();
+                }
                 
-                for (int p=0; p<NP; p++) {
-                    final PointerState ps = mPointers.get(p);
-                    ps.mXs.clear();
-                    ps.mYs.clear();
-                    ps.mCurDown = false;
-                }
-                mPointers.get(0).mCurDown = true;
-                mMaxNumPointers = 0;
-                if (mPrintCoords) {
-                    Log.i("Pointer", "Pointer 1: DOWN");
-                }
-            }
-            
-            if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
-                final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
-                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                 final int id = event.getPointerId(index);
                 while (NP <= id) {
                     PointerState ps = new PointerState();
                     mPointers.add(ps);
                     NP++;
                 }
+                
                 final PointerState ps = mPointers.get(id);
                 ps.mCurDown = true;
                 if (mPrintCoords) {
-                    Log.i("Pointer", "Pointer " + (id+1) + ": DOWN");
+                    Log.i(TAG, mText.clear().append("Pointer ")
+                            .append(id + 1).append(": DOWN").toString());
                 }
             }
             
@@ -284,58 +380,38 @@
                 final PointerState ps = mPointers.get(id);
                 final int N = event.getHistorySize();
                 for (int j=0; j<N; j++) {
+                    event.getHistoricalPointerCoords(i, j, ps.mCoords);
                     if (mPrintCoords) {
-                        Log.i("Pointer", "Pointer " + (id+1) + ": ("
-                                + event.getHistoricalX(i, j)
-                                + ", " + event.getHistoricalY(i, j) + ")"
-                                + " Prs=" + event.getHistoricalPressure(i, j)
-                                + " Size=" + event.getHistoricalSize(i, j));
+                        logPointerCoords(ps.mCoords, id);
                     }
-                    ps.mXs.add(event.getHistoricalX(i, j));
-                    ps.mYs.add(event.getHistoricalY(i, j));
+                    ps.addTrace(event.getHistoricalX(i, j), event.getHistoricalY(i, j));
                 }
+                event.getPointerCoords(i, ps.mCoords);
                 if (mPrintCoords) {
-                    Log.i("Pointer", "Pointer " + (id+1) + ": ("
-                            + event.getX(i) + ", " + event.getY(i) + ")"
-                            + " Prs=" + event.getPressure(i)
-                            + " Size=" + event.getSize(i));
+                    logPointerCoords(ps.mCoords, id);
                 }
-                ps.mXs.add(event.getX(i));
-                ps.mYs.add(event.getY(i));
-                ps.mCurX = (int)event.getX(i);
-                ps.mCurY = (int)event.getY(i);
-                //Log.i("Pointer", "Pointer #" + p + ": (" + ps.mCurX
-                //        + "," + ps.mCurY + ")");
-                ps.mCurPressure = event.getPressure(i);
-                ps.mCurSize = event.getSize(i);
-                ps.mCurWidth = (int)(ps.mCurSize*(getWidth()/3));
+                ps.addTrace(ps.mCoords.x, ps.mCoords.y);
                 ps.mXVelocity = mVelocity.getXVelocity(id);
                 ps.mYVelocity = mVelocity.getYVelocity(id);
             }
             
-            if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
-                final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
-                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+            if (action == MotionEvent.ACTION_UP
+                    || (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
+                final int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
+                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; // will be 0 for UP
+                
                 final int id = event.getPointerId(index);
                 final PointerState ps = mPointers.get(id);
-                ps.mXs.add(Float.NaN);
-                ps.mYs.add(Float.NaN);
                 ps.mCurDown = false;
                 if (mPrintCoords) {
-                    Log.i("Pointer", "Pointer " + (id+1) + ": UP");
+                    Log.i(TAG, mText.clear().append("Pointer ")
+                            .append(id + 1).append(": UP").toString());
                 }
-            }
-            
-            if (action == MotionEvent.ACTION_UP) {
-                for (int i=0; i<NI; i++) {
-                    final int id = event.getPointerId(i);
-                    final PointerState ps = mPointers.get(id);
-                    if (ps.mCurDown) {
-                        ps.mCurDown = false;
-                        if (mPrintCoords) {
-                            Log.i("Pointer", "Pointer " + (id+1) + ": UP");
-                        }
-                    }
+
+                if (action == MotionEvent.ACTION_UP) {
+                    mCurDown = false;
+                } else {
+                    ps.addTrace(Float.NaN, Float.NaN);
                 }
             }
             
@@ -356,8 +432,120 @@
 
     @Override
     public boolean onTrackballEvent(MotionEvent event) {
-        Log.i("Pointer", "Trackball: " + event);
+        Log.i(TAG, "Trackball: " + event);
         return super.onTrackballEvent(event);
     }
     
+    // HACK
+    // A quick and dirty string builder implementation optimized for GC.
+    // Using the basic StringBuilder implementation causes the application grind to a halt when
+    // more than a couple of pointers are down due to the number of temporary objects allocated
+    // while formatting strings for drawing or logging.
+    private static final class FasterStringBuilder {
+        private char[] mChars;
+        private int mLength;
+        
+        public FasterStringBuilder() {
+            mChars = new char[64];
+        }
+        
+        public FasterStringBuilder clear() {
+            mLength = 0;
+            return this;
+        }
+        
+        public FasterStringBuilder append(String value) {
+            final int valueLength = value.length();
+            final int index = reserve(valueLength);
+            value.getChars(0, valueLength, mChars, index);
+            mLength += valueLength;
+            return this;
+        }
+        
+        public FasterStringBuilder append(int value) {
+            return append(value, 0);
+        }
+        
+        public FasterStringBuilder append(int value, int zeroPadWidth) {
+            final boolean negative = value < 0;
+            if (negative) {
+                value = - value;
+                if (value < 0) {
+                    append("-2147483648");
+                    return this;
+                }
+            }
+            
+            int index = reserve(11);
+            final char[] chars = mChars;
+            
+            if (value == 0) {
+                chars[index++] = '0';
+                mLength += 1;
+                return this;
+            }
+            
+            if (negative) {
+                chars[index++] = '-';
+            }
+
+            int divisor = 1000000000;
+            int numberWidth = 10;
+            while (value < divisor) {
+                divisor /= 10;
+                numberWidth -= 1;
+                if (numberWidth < zeroPadWidth) {
+                    chars[index++] = '0';
+                }
+            }
+            
+            do {
+                int digit = value / divisor;
+                value -= digit * divisor;
+                divisor /= 10;
+                chars[index++] = (char) (digit + '0');
+            } while (divisor != 0);
+            
+            mLength = index;
+            return this;
+        }
+        
+        public FasterStringBuilder append(float value, int precision) {
+            int scale = 1;
+            for (int i = 0; i < precision; i++) {
+                scale *= 10;
+            }
+            value = (float) (Math.rint(value * scale) / scale);
+            
+            append((int) value);
+
+            if (precision != 0) {
+                append(".");
+                value = Math.abs(value);
+                value -= Math.floor(value);
+                append((int) (value * scale), precision);
+            }
+            
+            return this;
+        }
+        
+        @Override
+        public String toString() {
+            return new String(mChars, 0, mLength);
+        }
+        
+        private int reserve(int length) {
+            final int oldLength = mLength;
+            final int newLength = mLength + length;
+            final char[] oldChars = mChars;
+            final int oldCapacity = oldChars.length;
+            if (newLength > oldCapacity) {
+                final int newCapacity = oldCapacity * 2;
+                final char[] newChars = new char[newCapacity];
+                System.arraycopy(oldChars, 0, newChars, 0, oldLength);
+                mChars = newChars;
+            }
+            return oldLength;
+        }
+    }
 }
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 6f6d919..c9d7e7f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -308,6 +308,8 @@
     jclass clazz;
     jmethodID methodId;
 
+    LOGD("Calling main entry %s", className);
+
     env = getJNIEnv();
     if (env == NULL)
         return UNKNOWN_ERROR;
@@ -914,7 +916,8 @@
  */
 void AndroidRuntime::start(const char* className, const bool startSystemServer)
 {
-    LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");
+    LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
+            className != NULL ? className : "(unknown)");
 
     char* slashClassName = NULL;
     char* cp;
@@ -1029,7 +1032,7 @@
 
 void AndroidRuntime::onExit(int code)
 {
-    LOGI("AndroidRuntime onExit calling exit(%d)", code);
+    LOGV("AndroidRuntime onExit calling exit(%d)", code);
     exit(code);
 }
 
@@ -1334,7 +1337,7 @@
      */
     androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
 
-    LOGD("--- registering native functions ---\n");
+    LOGV("--- registering native functions ---\n");
 
     /*
      * Every "register" function calls one or more things that return
diff --git a/core/jni/android_database_SQLiteQuery.cpp b/core/jni/android_database_SQLiteQuery.cpp
index 747ee50..e383123 100644
--- a/core/jni/android_database_SQLiteQuery.cpp
+++ b/core/jni/android_database_SQLiteQuery.cpp
@@ -205,7 +205,7 @@
                     int offset = window->alloc(size);
                     if (!offset) {
                         window->freeLastRow();
-                        LOGE("Failed allocating %u bytes for text/blob at %d,%d", size,
+                        LOGD("Failed allocating %u bytes for text/blob at %d,%d", size,
                                    startPos + numRows, i);
                         return startPos + numRows + finish_program_and_get_row_count(statement) + 1;
                     }
@@ -225,7 +225,7 @@
                     int64_t value = sqlite3_column_int64(statement, i);
                     if (!window->putLong(numRows, i, value)) {
                         window->freeLastRow();
-                        LOGE("Failed allocating space for a long in column %d", i);
+                        LOGD("Failed allocating space for a long in column %d", i);
                         return startPos + numRows + finish_program_and_get_row_count(statement) + 1;
                     }
                     LOG_WINDOW("%d,%d is INTEGER 0x%016llx", startPos + numRows, i, value);
@@ -234,7 +234,7 @@
                     double value = sqlite3_column_double(statement, i);
                     if (!window->putDouble(numRows, i, value)) {
                         window->freeLastRow();
-                        LOGE("Failed allocating space for a double in column %d", i);
+                        LOGD("Failed allocating space for a double in column %d", i);
                         return startPos + numRows + finish_program_and_get_row_count(statement) + 1;
                     }
                     LOG_WINDOW("%d,%d is FLOAT %lf", startPos + numRows, i, value);
@@ -245,7 +245,7 @@
                     int offset = window->alloc(size);
                     if (!offset) {
                         window->freeLastRow();
-                        LOGE("Failed allocating %u bytes for blob at %d,%d", size,
+                        LOGD("Failed allocating %u bytes for blob at %d,%d", size,
                                    startPos + numRows, i);
                         return startPos + numRows + finish_program_and_get_row_count(statement) + 1;
                     }
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index aec537d..c5ccc43 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -411,6 +411,30 @@
     return (jint)power;
 }
 
+static jboolean android_net_wifi_setBandCommand(JNIEnv* env, jobject clazz, jint band)
+{
+    char cmdstr[25];
+
+    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "DRIVER SETBAND %d", band);
+    int cmdTooLong = numWritten >= (int)sizeof(cmdstr);
+
+    return (jboolean)!cmdTooLong && doBooleanCommand(cmdstr, "OK");
+}
+
+static jint android_net_wifi_getBandCommand(JNIEnv* env, jobject clazz)
+{
+    char reply[25];
+    int band;
+
+    if (doCommand("DRIVER GETBAND", reply, sizeof(reply)) != 0) {
+        return (jint)-1;
+    }
+    // reply comes back in the form "Band X" where X is the
+    // number we're interested in.
+    sscanf(reply, "%*s %u", &band);
+    return (jint)band;
+}
+
 static jboolean android_net_wifi_setNumAllowedChannelsCommand(JNIEnv* env, jobject clazz, jint numChannels)
 {
     char cmdstr[256];
@@ -561,6 +585,8 @@
     { "stopPacketFiltering", "()Z", (void*) android_net_wifi_stopPacketFiltering },
     { "setPowerModeCommand", "(I)Z", (void*) android_net_wifi_setPowerModeCommand },
     { "getPowerModeCommand", "()I", (void*) android_net_wifi_getPowerModeCommand },
+    { "setBandCommand", "(I)Z", (void*) android_net_wifi_setBandCommand},
+    { "getBandCommand", "()I", (void*) android_net_wifi_getBandCommand},
     { "setNumAllowedChannelsCommand", "(I)Z", (void*) android_net_wifi_setNumAllowedChannelsCommand },
     { "getNumAllowedChannelsCommand", "()I", (void*) android_net_wifi_getNumAllowedChannelsCommand },
     { "setBluetoothCoexistenceModeCommand", "(I)Z",
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 6ef154e..1307ec3 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -50,6 +50,8 @@
 static jmethodID method_onDeviceCreated;
 static jmethodID method_onDeviceRemoved;
 static jmethodID method_onDeviceDisconnectRequested;
+static jmethodID method_onNetworkDeviceDisconnected;
+static jmethodID method_onNetworkDeviceConnected;
 
 static jmethodID method_onCreatePairedDeviceResult;
 static jmethodID method_onCreateDeviceResult;
@@ -100,6 +102,10 @@
     method_onDeviceRemoved = env->GetMethodID(clazz, "onDeviceRemoved", "(Ljava/lang/String;)V");
     method_onDeviceDisconnectRequested = env->GetMethodID(clazz, "onDeviceDisconnectRequested",
                                                         "(Ljava/lang/String;)V");
+    method_onNetworkDeviceConnected = env->GetMethodID(clazz, "onNetworkDeviceConnected",
+                                                              "(Ljava/lang/String;I)V");
+    method_onNetworkDeviceDisconnected = env->GetMethodID(clazz, "onNetworkDeviceDisconnected",
+                                                              "(Ljava/lang/String;)V");
 
     method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
                                                          "(Ljava/lang/String;I)V");
@@ -253,6 +259,13 @@
             return JNI_FALSE;
         }
         dbus_bus_add_match(nat->conn,
+                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".NetworkServer'",
+                &err);
+        if (dbus_error_is_set(&err)) {
+            LOG_AND_FREE_DBUS_ERROR(&err);
+            return JNI_FALSE;
+        }
+        dbus_bus_add_match(nat->conn,
                 "type='signal',interface='org.bluez.AudioSink'",
                 &err);
         if (dbus_error_is_set(&err)) {
@@ -409,13 +422,31 @@
         dbus_connection_unregister_object_path(nat->conn, agent_path);
 
         dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='org.bluez.AudioSink'",
+                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".AudioSink'",
                 &err);
         if (dbus_error_is_set(&err)) {
             LOG_AND_FREE_DBUS_ERROR(&err);
         }
         dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='org.bluez.audio.Device'",
+                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Device'",
+                &err);
+        if (dbus_error_is_set(&err)) {
+            LOG_AND_FREE_DBUS_ERROR(&err);
+        }
+        dbus_bus_remove_match(nat->conn,
+                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Input'",
+                &err);
+        if (dbus_error_is_set(&err)) {
+            LOG_AND_FREE_DBUS_ERROR(&err);
+        }
+        dbus_bus_remove_match(nat->conn,
+                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Network'",
+                &err);
+        if (dbus_error_is_set(&err)) {
+            LOG_AND_FREE_DBUS_ERROR(&err);
+        }
+        dbus_bus_remove_match(nat->conn,
+                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".NetworkServer'",
                 &err);
         if (dbus_error_is_set(&err)) {
             LOG_AND_FREE_DBUS_ERROR(&err);
@@ -912,7 +943,39 @@
            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        }
        goto success;
-   }
+    } else if (dbus_message_is_signal(msg,
+                                     "org.bluez.NetworkServer",
+                                     "DeviceDisconnected")) {
+       char *c_address;
+       if (dbus_message_get_args(msg, &err,
+                                  DBUS_TYPE_STRING, &c_address,
+                                  DBUS_TYPE_INVALID)) {
+           env->CallVoidMethod(nat->me,
+                               method_onNetworkDeviceDisconnected,
+                               env->NewStringUTF(c_address));
+       } else {
+           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
+       }
+       goto success;
+    } else if (dbus_message_is_signal(msg,
+                                     "org.bluez.NetworkServer",
+                                     "DeviceConnected")) {
+       char *c_address;
+       uint16_t uuid;
+
+       if (dbus_message_get_args(msg, &err,
+                                  DBUS_TYPE_STRING, &c_address,
+                                  DBUS_TYPE_UINT16, &uuid,
+                                  DBUS_TYPE_INVALID)) {
+           env->CallVoidMethod(nat->me,
+                               method_onNetworkDeviceConnected,
+                               env->NewStringUTF(c_address),
+                               uuid);
+       } else {
+           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
+       }
+       goto success;
+    }
 
     ret = a2dp_event_filter(msg, env);
     env->PopLocalFrame(NULL);
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 5c4e4fd..7a53874 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -270,6 +270,7 @@
 
         IPCThreadState* thread_state = IPCThreadState::self();
         const int strict_policy_before = thread_state->getStrictModePolicy();
+        thread_state->setLastTransactionBinderFlags(flags);
 
         //printf("Transact from %p to Java code sending: ", this);
         //data.print();
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 98c03a6..aa71746 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -84,6 +84,16 @@
     renderer->prepare();
 }
 
+static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject canvas,
+        OpenGLRenderer* renderer) {
+    renderer->acquireContext();
+}
+
+static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject canvas,
+        OpenGLRenderer* renderer) {
+    renderer->releaseContext();
+}
+
 // ----------------------------------------------------------------------------
 // State
 // ----------------------------------------------------------------------------
@@ -374,6 +384,8 @@
     { "nDestroyRenderer",   "(I)V",            (void*) android_view_GLES20Canvas_destroyRenderer },
     { "nSetViewport",       "(III)V",          (void*) android_view_GLES20Canvas_setViewport },
     { "nPrepare",           "(I)V",            (void*) android_view_GLES20Canvas_prepare },
+    { "nAcquireContext",    "(I)V",            (void*) android_view_GLES20Canvas_acquireContext },
+    { "nReleaseContext",    "(I)V",            (void*) android_view_GLES20Canvas_releaseContext },
 
     { "nSave",              "(II)I",           (void*) android_view_GLES20Canvas_save },
     { "nRestore",           "(I)V",            (void*) android_view_GLES20Canvas_restore },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1f66d05..c2c2138 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -193,20 +193,6 @@
         android:label="@string/permlab_writeContacts"
         android:description="@string/permdesc_writeContacts" />
 
-    <!-- Allows an application to read the owner's data. -->
-    <permission android:name="android.permission.READ_OWNER_DATA"
-        android:permissionGroup="android.permission-group.PERSONAL_INFO"
-        android:protectionLevel="dangerous"
-        android:label="@string/permlab_readOwnerData"
-        android:description="@string/permdesc_readOwnerData" />
-
-    <!-- Allows an application to write (but not read) the owner's data. -->
-    <permission android:name="android.permission.WRITE_OWNER_DATA"
-        android:permissionGroup="android.permission-group.PERSONAL_INFO"
-        android:protectionLevel="dangerous"
-        android:label="@string/permlab_writeOwnerData"
-        android:description="@string/permdesc_writeOwnerData" />
-
     <!-- Allows an application to read the user's calendar data. -->
     <permission android:name="android.permission.READ_CALENDAR"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
@@ -634,7 +620,10 @@
         android:label="@string/permlab_setAnimationScale"
         android:description="@string/permdesc_setAnimationScale" />
 
-    <!-- Allow an application to make its activities persistent. -->
+    <!-- @deprecated This functionality will be removed in the future; please do
+         not use.
+
+         Allow an application to make its activities persistent. -->
     <permission android:name="android.permission.PERSISTENT_ACTIVITY"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
         android:protectionLevel="dangerous"
@@ -776,7 +765,7 @@
     <!-- Allows applications to disable the keyguard -->
     <permission android:name="android.permission.DISABLE_KEYGUARD"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-        android:protectionLevel="normal"
+        android:protectionLevel="dangerous"
         android:description="@string/permdesc_disableKeyguard"
         android:label="@string/permlab_disableKeyguard" />
 
@@ -1285,7 +1274,7 @@
                 android:excludeFromRecents="true">
         </activity>
         <activity android:name="com.android.internal.app.PlatLogoActivity"
-                android:theme="@style/Theme.NoTitleBar.Fullscreen">
+                android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen">
         </activity>
         <activity android:name="com.android.internal.app.DisableCarModeActivity"
                 android:theme="@style/Theme.NoDisplay"
diff --git a/core/res/res/drawable-hdpi/ic_btn_find_next.png b/core/res/res/drawable-hdpi/ic_btn_find_next.png
new file mode 100644
index 0000000..b696a6b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_btn_find_next.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_btn_find_prev.png b/core/res/res/drawable-hdpi/ic_btn_find_prev.png
new file mode 100644
index 0000000..5550c5a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_btn_find_prev.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_find.png b/core/res/res/drawable-hdpi/ic_menu_find.png
new file mode 100644
index 0000000..17ac694
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_find.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_btn_find_next.png b/core/res/res/drawable-mdpi/ic_btn_find_next.png
new file mode 100644
index 0000000..abdc247
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_btn_find_next.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_btn_find_prev.png b/core/res/res/drawable-mdpi/ic_btn_find_prev.png
new file mode 100644
index 0000000..4e3da1d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_btn_find_prev.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_find.png b/core/res/res/drawable-mdpi/ic_menu_find.png
new file mode 100644
index 0000000..4d96348
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_find.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo.jpg b/core/res/res/drawable-nodpi/platlogo.jpg
deleted file mode 100644
index 0e7780c..0000000
--- a/core/res/res/drawable-nodpi/platlogo.jpg
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo.png b/core/res/res/drawable-nodpi/platlogo.png
new file mode 100644
index 0000000..e5af356
--- /dev/null
+++ b/core/res/res/drawable-nodpi/platlogo.png
Binary files differ
diff --git a/core/res/res/layout/locale_picker_item.xml b/core/res/res/layout/locale_picker_item.xml
new file mode 100644
index 0000000..b63f5ab
--- /dev/null
+++ b/core/res/res/layout/locale_picker_item.xml
@@ -0,0 +1,30 @@
+<?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:orientation="horizontal"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:gravity="center_vertical"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:padding="5dip">
+
+    <TextView android:id="@+id/locale"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+    />
+</LinearLayout >
diff --git a/core/res/res/layout/webview_find.xml b/core/res/res/layout/webview_find.xml
new file mode 100644
index 0000000..f2edb2b
--- /dev/null
+++ b/core/res/res/layout/webview_find.xml
@@ -0,0 +1,39 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    >
+    <EditText android:id="@+id/edit"
+        android:layout_width="0dip"
+        android:layout_weight="1"
+        android:layout_height="wrap_content"
+        android:scrollHorizontally="true"
+        android:inputType="text"
+        android:hint="@string/find_on_page"
+        android:imeOptions="actionDone"
+        android:layout_marginRight="10dip"
+        />
+    <TextView android:id="@+id/matches"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textColor="?android:attr/textColorSecondaryInverse"
+        />
+</LinearLayout>
diff --git a/core/res/res/menu/webview_copy.xml b/core/res/res/menu/webview_copy.xml
new file mode 100644
index 0000000..224f54f
--- /dev/null
+++ b/core/res/res/menu/webview_copy.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/copy"
+        android:icon="@drawable/ic_menu_attachment"
+        android:showAsAction="always"
+        />
+    <item android:id="@+id/share"
+        android:icon="@drawable/ic_menu_share"
+        android:showAsAction="always"
+        />
+    <item android:id="@+id/select_all"
+        android:icon="@drawable/ic_menu_chat_dashboard"
+        android:showAsAction="always"
+        />
+    <item android:id="@+id/find"
+        android:icon="@drawable/ic_menu_find"
+        android:showAsAction="always"
+        />
+</menu>
+
diff --git a/core/res/res/menu/webview_find.xml b/core/res/res/menu/webview_find.xml
new file mode 100644
index 0000000..74a40aa
--- /dev/null
+++ b/core/res/res/menu/webview_find.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/find_prev"
+        android:icon="@drawable/ic_btn_find_prev"
+        android:showAsAction="always"
+        />
+    <item android:id="@+id/find_next"
+        android:icon="@drawable/ic_btn_find_next"
+        android:showAsAction="always"
+        />
+</menu>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 9c51aeb..05e9faa 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Dotykem zahájíte konfiguraci"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Zpět"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Další"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Přeskočit"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Vysoké využití mobilních dat"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Dotykem zobrazíte další informace o využití mobilních dat"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Byl překročen limit mobilních dat"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index cf76818..f5331e5 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Tryk for at konfigurere"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tilbage"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Næste"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Spring over"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Højt mobildataforbrug"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Tryk for oplysninger om brug af mobildata"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Grænsen for mobildata er overskredet"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 712e10e..52ae3b4 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Zum Konfigurieren berühren"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Zurück"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Weiter"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Überspringen"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Hohe Mobildatennutzung"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Weitere Informationen über die Mobildatennutzung durch Berühren aufrufen"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Mobildatenlimit überschritten"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 9a6d9ee..c21321d 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Αγγίξτε για να γίνει διαμόρφωση"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Πίσω"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Επόμενο"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Παράβλεψη"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Υψηλή χρήση δεδομένων κινητής τηλεφωνίας"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Αγγίξτε για να μάθετε περισσότερα σχετικά με τη χρήση δεδομένων κινητής τηλεφωνίας"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Ξεπεράστηκε το όριο δεδομένων κινητής τηλεφωνίας"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index b720339..38ad404 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Tocar para configurar"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atrás"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Siguiente"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Omitir"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Amplia utilización de datos móviles"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Toca para obtener más información acerca de la utilización de datos móviles."</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Límite de datos móviles excedido "</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 0aeaf2e..bb2dfd8 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Toca para iniciar la configuración."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atrás"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Siguiente"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Omitir"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Uso elevado datos móviles"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Más información sobre uso de datos"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Límite datos superado"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 8884ddc..343829a 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Toucher pour configurer"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Retour"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Suivant"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Ignorer"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Utilisation élevée des données mobiles"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Touchez pour en savoir plus sur l\'utilisation des données mobiles"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Quota d\'utilisation des données mobiles dépassé"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 0cf7f38..58a34eb 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Tocca per configurare"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Indietro"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Avanti"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Salta"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Utilizzo dati cell. elevato"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Tocca per informazioni sull\'utilizzo dati cell."</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Limite dati cell. superato"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 468b692..7da30f7 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"タップして設定する"</string>
     <string name="back_button_label" msgid="2300470004503343439">"戻る"</string>
     <string name="next_button_label" msgid="1080555104677992408">"次へ"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"スキップ"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"モバイルデータの使用量が増えています"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"タップしてモバイルデータ利用の詳細を表示します"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"モバイルデータの制限を超えました"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index cb8f31b..144efa0 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"구성하려면 터치하세요."</string>
     <string name="back_button_label" msgid="2300470004503343439">"뒤로"</string>
     <string name="next_button_label" msgid="1080555104677992408">"다음"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"건너뛰기"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"높은 모바일 데이터 사용량"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"모바일 데이터 사용에 대해 자세히 알아보려면 터치하세요."</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"모바일 데이터 제한을 초과했습니다."</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 4485d27..b4aa661 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Trykk for å konfigurere"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tilbake"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Neste"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Hopp over"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Høy mobildatabruk"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Berør for å lese mer om bruk av mobildata"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Grensen for mobildatabruk er overskredet"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index abd791a..cc60101 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Aanraken om te configureren"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Vorige"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Volgende"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Overslaan"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Hoog mobiel gegevensgebruik"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Raak aan voor meer informatie over mobiel gegevensgebruik"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Mobiele gegevenslimiet overschreden"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 28ba755..a965316 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Dotknij, aby skonfigurować"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Wróć"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Dalej"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Pomiń"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Wysoki poziom użycia danych"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Dotknij, aby zobaczyć statystyki przesyłu danych"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Przekroczono limit danych"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 0cbc7c1..360b911 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Tocar para configurar"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Anterior"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Seguinte"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Ignorar"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Utilização elevada de dados móveis"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Toque para saber mais sobre a utilização de dados móveis"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Limite de dados móveis excedido"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4f229d7..dc5ee14 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Toque para configurar"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Voltar"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Avançar"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Ignorar"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Alto uso de dados do celular"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Toque para saber mais sobre uso de dados do celular"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Limite de dados do celular excedido"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index ff03e35..8405760 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -791,11 +791,11 @@
     <string name="perms_hide" msgid="7283915391320676226"><b>"Скрыть"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Показать все"</b></string>
     <string name="usb_storage_activity_title" msgid="2399289999608900443">"Запоминающее устройство USB"</string>
-    <string name="usb_storage_title" msgid="5901459041398751495">"устройство USB подключено"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB-подключение установлено"</string>
     <string name="usb_storage_message" msgid="4796759646167247178">"Телефон подключен к компьютеру через порт USB. Нажмите кнопку ниже, если необходимо копировать файлы с компьютера на SD-карту устройства Android (или наоборот)."</string>
     <string name="usb_storage_button_mount" msgid="1052259930369508235">"Включить USB-накопитель"</string>
     <string name="usb_storage_error_message" msgid="2534784751603345363">"При использовании SD-карты как USB-накопителя возникла неполадка."</string>
-    <string name="usb_storage_notification_title" msgid="8175892554757216525">"устройство USB подключено"</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB-подключение установлено"</string>
     <string name="usb_storage_notification_message" msgid="7380082404288219341">"Выберите копирование файлов на компьютер или с компьютера."</string>
     <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Выключить USB-накопитель"</string>
     <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"Выберите, чтобы выключить USB-накопитель."</string>
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Нажмите для настройки"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Далее"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Пропустить"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Активная передача данных"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Нажмите, чтобы узнать больше о мобильной передаче данных"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Превышен лимит на мобильные данные"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4d76987..46806ab 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Tryck om du vill konfigurera"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tillbaka"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Nästa"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Hoppa över"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Hög mobildataanvändning"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Tryck om du vill veta mer om mobildataanvändning"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Gränsen för mobildata har överskridits"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index b462c61..fffbcd7 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"Yapılandırmak için dokunun"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Geri"</string>
     <string name="next_button_label" msgid="1080555104677992408">"İleri"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"Atla"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Yüksek düzeyde mobil veri kullanımı"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Mobil veri kullanımı hakkında daha fazla bilgi edinmek için dokunun"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Mobil veri limiti aşıldı"</string>
diff --git a/core/res/res/values-xlarge/dimens.xml b/core/res/res/values-xlarge/dimens.xml
index 516fb5f..115cb30 100644
--- a/core/res/res/values-xlarge/dimens.xml
+++ b/core/res/res/values-xlarge/dimens.xml
@@ -18,12 +18,12 @@
 */
 -->
 <resources>
-    <dimen name="status_bar_height">50dip</dimen>
+    <dimen name="status_bar_height">48dip</dimen>
     <!-- Height of the status bar -->
-    <dimen name="status_bar_icon_size">50dip</dimen>
+    <dimen name="status_bar_icon_size">48dip</dimen>
     <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
     <!-- Margin for permanent screen decorations at the bottom. -->
-    <dimen name="screen_margin_bottom">50dip</dimen>
+    <dimen name="screen_margin_bottom">48dip</dimen>
     
     <!-- Default height of a key in the password keyboard for alpha -->
     <dimen name="password_keyboard_key_height_alpha">0.35in</dimen>
diff --git a/core/res/res/values-xlarge/styles.xml b/core/res/res/values-xlarge/styles.xml
index ff7df7c..4692656 100644
--- a/core/res/res/values-xlarge/styles.xml
+++ b/core/res/res/values-xlarge/styles.xml
@@ -27,7 +27,6 @@
     </style>
 
     <style name="TextAppearance.StatusBar.Icon">
-        <item name="android:textStyle">bold</item>
     </style>
     <style name="TextAppearance.StatusBar.EventContent">
         <item name="android:textColor">?android:attr/textColorPrimary</item>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index ff5d0e9..bff82b9 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"触摸可进行配置"</string>
     <string name="back_button_label" msgid="2300470004503343439">"上一步"</string>
     <string name="next_button_label" msgid="1080555104677992408">"下一步"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"跳过"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"手机流量过多"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"轻触以了解有关手机流量详情"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"已超出手机数据上限"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 4d42a4e..300cf20 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -871,8 +871,7 @@
     <string name="tethered_notification_message" msgid="3067108323903048927">"輕觸以設定"</string>
     <string name="back_button_label" msgid="2300470004503343439">"返回"</string>
     <string name="next_button_label" msgid="1080555104677992408">"繼續"</string>
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
+    <string name="skip_button_label" msgid="1275362299471631819">"略過"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"高行動資料用量"</string>
     <string name="throttle_warning_notification_message" msgid="2609734763845705708">"輕觸即可瞭解更多有關行動資料用量的詳細資訊"</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"已達行動資料上限"</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index aeee8af..b618756 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -117,4 +117,16 @@
         <item>3</item>
     </integer-array>
 
+    <!-- Used in LocalePicker -->
+    <string-array translatable="false" name="special_locale_codes">
+        <item>zh_CN</item>
+        <item>zh_TW</item>
+    </string-array>
+
+    <!-- Used in LocalePicker -->
+    <string-array translatable="false" name="special_locale_names">
+        <item>中文 (简体)</item>
+        <item>中文 (繁體)</item>
+    </string-array>
+
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a071cac..988176d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -399,4 +399,6 @@
          device is data-only. -->
     <bool name="config_voice_capable">true</bool>
 
+    <!-- IP address of the dns server to use if nobody else suggests one -->
+    <string name="config_default_dns_server">8.8.8.8</string>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e439593..26a75ee 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1324,12 +1324,12 @@
   <public type="attr" name="imeSubtypeMode" />
   <public type="attr" name="imeSubtypeExtraValue" />
   <public type="attr" name="splitMotionEvents" />
+  <public type="attr" name="listChoiceBackgroundIndicator" />
+  <public type="attr" name="spinnerMode" />
 
   <public type="anim" name="animator_fade_in" />
   <public type="anim" name="animator_fade_out" />
 
-  <public type="attr" name="listChoiceBackgroundIndicator" id="0x01010330" />
-
   <public type="id" name="home" />
   <!-- Context menu ID for the "Select text..." menu item to switch to text
        selection context mode in text views. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e38a228..e9d799b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -784,20 +784,6 @@
         applications can use this to erase or modify your contact data.</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_writeOwnerData">write owner data</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_writeOwnerData">Allows an application to modify the
-        phone owner data stored on your phone. Malicious
-        applications can use this to erase or modify owner data.</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_readOwnerData">read owner data</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_readOwnerData">Allows an application read the
-        phone owner data stored on your phone. Malicious
-        applications can use this to read phone owner data.</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_readCalendar">read calendar events</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_readCalendar">Allows an application to read all
@@ -2290,4 +2276,21 @@
     <!-- Shown when the users bandwidth is reduced because of excessive data use -->
     <string name="throttled_notification_title">Mobile data limit exceeded</string>
     <string name="throttled_notification_message">Touch to learn more about mobile data use</string>
+
+    <!-- Displayed on the Find dialog when there are no matches [CHAR LIMIT=NONE]-->
+    <string name="no_matches">No matches</string>
+
+    <!-- Find dialog hint text.  Also used in the menu item to open find on page [CHAR LIMIT=NONE] -->
+    <string name="find_on_page">Find on page</string>
+
+    <!-- Displayed on the Find dialog to display the index of the highlighted
+         match and total number of matches found in the current page. [CHAR LIMIT=NONE] -->
+    <plurals name="matches_found">
+        <!-- Case of one match -->
+        <item quantity="one">1 match</item>
+        <!-- Case of multiple total matches -->
+        <item quantity="other"><xliff:g id="index" example="2">%d</xliff:g> of <xliff:g id="total" example="137">%d</xliff:g></item>
+    </plurals>
+
+
 </resources>
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothRebootStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothRebootStressTest.java
new file mode 100644
index 0000000..33e9dd7
--- /dev/null
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothRebootStressTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.bluetooth;
+
+import android.content.Context;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Instrumentation test case for stress test involving rebooting the device.
+ * <p>
+ * This test case tests that bluetooth is enabled after a device reboot. Because
+ * the device will reboot, the instrumentation must be driven by a script on the
+ * host side.
+ */
+public class BluetoothRebootStressTest extends InstrumentationTestCase {
+    private static final String TAG = "BluetoothRebootStressTest";
+    private static final String OUTPUT_FILE = "BluetoothRebootStressTestOutput.txt";
+
+    private BluetoothTestUtils mTestUtils;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Context context = getInstrumentation().getTargetContext();
+        mTestUtils = new BluetoothTestUtils(context, TAG, OUTPUT_FILE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        mTestUtils.close();
+    }
+
+    /**
+     * Test method used to start the test by turning bluetooth on.
+     */
+    public void testStart() {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        mTestUtils.enable(adapter);
+    }
+
+    /**
+     * Test method used in the middle iterations of the test to check if
+     * bluetooth is on. Does not toggle bluetooth after the check. Assumes that
+     * bluetooth has been turned on by {@code #testStart()}
+     */
+    public void testMiddleNoToggle() {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+
+        assertTrue(adapter.isEnabled());
+    }
+
+    /**
+     * Test method used in the middle iterations of the test to check if
+     * bluetooth is on. Toggles bluetooth after the check. Assumes that
+     * bluetooth has been turned on by {@code #testStart()}
+     */
+    public void testMiddleToggle() {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+
+        assertTrue(adapter.isEnabled());
+
+        mTestUtils.disable(adapter);
+        mTestUtils.enable(adapter);
+    }
+
+    /**
+     * Test method used in the stop the test by turning bluetooth off. Assumes
+     * that bluetooth has been turned on by {@code #testStart()}
+     */
+    public void testStop() {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+
+        assertTrue(adapter.isEnabled());
+
+        mTestUtils.disable(adapter);
+    }
+}
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
index 7a6ee8e..d8d9eba 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
@@ -16,168 +16,28 @@
 
 package android.bluetooth;
 
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-
-import android.app.Instrumentation;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Environment;
 import android.test.InstrumentationTestCase;
-import android.util.Log;
 
 public class BluetoothStressTest extends InstrumentationTestCase {
     private static final String TAG = "BluetoothStressTest";
     private static final String OUTPUT_FILE = "BluetoothStressTestOutput.txt";
 
-    /**
-     * Timeout for {@link BluetoothAdapter#disable()} in ms.
-     */
-    private static final int DISABLE_TIMEOUT = 5000;
-
-    /**
-     * Timeout for {@link BluetoothAdapter#enable()} in ms.
-     */
-    private static final int ENABLE_TIMEOUT = 20000;
-
-    /**
-     * Timeout for {@link BluetoothAdapter#setScanMode(int)} in ms.
-     */
-    private static final int SET_SCAN_MODE_TIMEOUT = 5000;
-
-    /**
-     * Timeout for {@link BluetoothAdapter#startDiscovery()} in ms.
-     */
-    private static final int START_DISCOVERY_TIMEOUT = 5000;
-
-    /**
-     * Timeout for {@link BluetoothAdapter#cancelDiscovery()} in ms.
-     */
-    private static final int CANCEL_DISCOVERY_TIMEOUT = 5000;
-
-    private static final int DISCOVERY_STARTED_FLAG = 1;
-    private static final int DISCOVERY_FINISHED_FLAG = 1 << 1;
-    private static final int SCAN_MODE_NONE_FLAG = 1 << 2;
-    private static final int SCAN_MODE_CONNECTABLE_FLAG = 1 << 3;
-    private static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG = 1 << 4;
-    private static final int STATE_OFF_FLAG = 1 << 5;
-    private static final int STATE_TURNING_ON_FLAG = 1 << 6;
-    private static final int STATE_ON_FLAG = 1 << 7;
-    private static final int STATE_TURNING_OFF_FLAG = 1 << 8;
-
-    /**
-     * Time between polls in ms.
-     */
-    private static final int POLL_TIME = 100;
-
-    private Context mContext;
-
-    private Instrumentation mInstrumentation;
-
-    private BufferedWriter mOutputWriter;
-
-    private class BluetoothReceiver extends BroadcastReceiver {
-        private int mFiredFlags = 0;
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            synchronized (this) {
-                if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction())) {
-                    mFiredFlags |= DISCOVERY_STARTED_FLAG;
-                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) {
-                    mFiredFlags |= DISCOVERY_FINISHED_FLAG;
-                } else if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(intent.getAction())) {
-                    int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,
-                            BluetoothAdapter.ERROR);
-                    assertNotSame(mode, BluetoothAdapter.ERROR);
-                    switch (mode) {
-                        case BluetoothAdapter.SCAN_MODE_NONE:
-                            mFiredFlags |= SCAN_MODE_NONE_FLAG;
-                            break;
-                        case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
-                            mFiredFlags |= SCAN_MODE_CONNECTABLE_FLAG;
-                            break;
-                        case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
-                            mFiredFlags |= SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG;
-                            break;
-                    }
-                } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
-                    int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                            BluetoothAdapter.ERROR);
-                    assertNotSame(state, BluetoothAdapter.ERROR);
-                    switch (state) {
-                        case BluetoothAdapter.STATE_OFF:
-                            mFiredFlags |= STATE_OFF_FLAG;
-                            break;
-                        case BluetoothAdapter.STATE_TURNING_ON:
-                            mFiredFlags |= STATE_TURNING_ON_FLAG;
-                            break;
-                        case BluetoothAdapter.STATE_ON:
-                            mFiredFlags |= STATE_ON_FLAG;
-                            break;
-                        case BluetoothAdapter.STATE_TURNING_OFF:
-                            mFiredFlags |= STATE_TURNING_OFF_FLAG;
-                            break;
-                    }
-                }
-            }
-        }
-
-        public int getFiredFlags() {
-            synchronized (this) {
-                return mFiredFlags;
-            }
-        }
-
-        public void resetFiredFlags() {
-            synchronized (this) {
-                mFiredFlags = 0;
-            }
-        }
-    }
-
-    private BluetoothReceiver mReceiver = new BluetoothReceiver();
+    private BluetoothTestUtils mTestUtils;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
 
-        mInstrumentation = getInstrumentation();
-        mContext = mInstrumentation.getTargetContext();
-
-        try {
-            mOutputWriter = new BufferedWriter(new FileWriter(new File(
-                    Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
-        } catch (IOException e) {
-            Log.w(TAG, "Test output file could not be opened", e);
-            mOutputWriter = null;
-        }
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
-        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
-        filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
-        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
-        mContext.registerReceiver(mReceiver, filter);
+        Context context = getInstrumentation().getTargetContext();
+        mTestUtils = new BluetoothTestUtils(context, TAG, OUTPUT_FILE);
     }
 
     @Override
     protected void tearDown() throws Exception {
         super.tearDown();
 
-        mContext.unregisterReceiver(mReceiver);
-
-        if (mOutputWriter != null) {
-            try {
-                mOutputWriter.close();
-            } catch (IOException e) {
-                Log.w(TAG, "Test output file could not be closed", e);
-            }
-        }
+        mTestUtils.close();
     }
 
     public void testEnable() {
@@ -185,295 +45,37 @@
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
 
         for (int i = 0; i < iterations; i++) {
-            writeOutput("enable iteration " + (i + 1) + " of " + iterations);
-            enable(adapter);
-            disable(adapter);
+            mTestUtils.writeOutput("enable iteration " + (i + 1) + " of " + iterations);
+            mTestUtils.enable(adapter);
+            mTestUtils.disable(adapter);
         }
     }
 
     public void testDiscoverable() {
         int iterations = BluetoothTestRunner.sDiscoverableIterations;
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        enable(adapter);
+        mTestUtils.enable(adapter);
 
         for (int i = 0; i < iterations; i++) {
-            writeOutput("discoverable iteration " + (i + 1) + " of " + iterations);
-            discoverable(adapter);
-            undiscoverable(adapter);
+            mTestUtils.writeOutput("discoverable iteration " + (i + 1) + " of " + iterations);
+            mTestUtils.discoverable(adapter);
+            mTestUtils.undiscoverable(adapter);
         }
 
-        disable(adapter);
+        mTestUtils.disable(adapter);
     }
 
     public void testScan() {
         int iterations = BluetoothTestRunner.sScanIterations;
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        enable(adapter);
+        mTestUtils.enable(adapter);
 
         for (int i = 0; i < iterations; i++) {
-            writeOutput("scan iteration " + (i + 1) + " of " + iterations);
-            startScan(adapter);
-            stopScan(adapter);
+            mTestUtils.writeOutput("scan iteration " + (i + 1) + " of " + iterations);
+            mTestUtils.startScan(adapter);
+            mTestUtils.stopScan(adapter);
         }
 
-        disable(adapter);
-    }
-
-    private void disable(BluetoothAdapter adapter) {
-        int mask = STATE_TURNING_OFF_FLAG | STATE_OFF_FLAG | SCAN_MODE_NONE_FLAG;
-        mReceiver.resetFiredFlags();
-
-        int state = adapter.getState();
-        switch (state) {
-            case BluetoothAdapter.STATE_OFF:
-                assertFalse(adapter.isEnabled());
-                return;
-            case BluetoothAdapter.STATE_ON:
-                assertTrue(adapter.isEnabled());
-                assertTrue(adapter.disable());
-                break;
-            case BluetoothAdapter.STATE_TURNING_ON:
-                assertFalse(adapter.isEnabled());
-                assertTrue(adapter.disable());
-                break;
-            case BluetoothAdapter.STATE_TURNING_OFF:
-                assertFalse(adapter.isEnabled());
-                mask = 0; // Don't check for received intents since we might have missed them.
-                break;
-            default:
-                fail("disable() invalid state: state=" + state);
-        }
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < DISABLE_TIMEOUT) {
-            state = adapter.getState();
-            if (state == BluetoothAdapter.STATE_OFF) {
-                assertFalse(adapter.isEnabled());
-                if ((mReceiver.getFiredFlags() & mask) == mask) {
-                    mReceiver.resetFiredFlags();
-                    writeOutput(String.format("disable() completed in %d ms",
-                            (System.currentTimeMillis() - s)));
-                    return;
-                }
-            } else {
-                assertFalse(adapter.isEnabled());
-                assertEquals(BluetoothAdapter.STATE_TURNING_OFF, state);
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = mReceiver.getFiredFlags();
-        mReceiver.resetFiredFlags();
-        fail(String.format("disable() timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)",
-                state, BluetoothAdapter.STATE_OFF, firedFlags, mask));
-    }
-
-    private void enable(BluetoothAdapter adapter) {
-        int mask = STATE_TURNING_ON_FLAG | STATE_ON_FLAG | SCAN_MODE_CONNECTABLE_FLAG;
-        mReceiver.resetFiredFlags();
-
-        int state = adapter.getState();
-        switch (state) {
-            case BluetoothAdapter.STATE_ON:
-                assertTrue(adapter.isEnabled());
-                return;
-            case BluetoothAdapter.STATE_OFF:
-            case BluetoothAdapter.STATE_TURNING_OFF:
-                assertFalse(adapter.isEnabled());
-                assertTrue(adapter.enable());
-                break;
-            case BluetoothAdapter.STATE_TURNING_ON:
-                assertFalse(adapter.isEnabled());
-                mask = 0; // Don't check for received intents since we might have missed them.
-                break;
-            default:
-                fail("enable() invalid state: state=" + state);
-        }
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < ENABLE_TIMEOUT) {
-            state = adapter.getState();
-            if (state == BluetoothAdapter.STATE_ON) {
-                assertTrue(adapter.isEnabled());
-                if ((mReceiver.getFiredFlags() & mask) == mask) {
-                    mReceiver.resetFiredFlags();
-                    writeOutput(String.format("enable() completed in %d ms",
-                            (System.currentTimeMillis() - s)));
-                    return;
-                }
-            } else {
-                assertFalse(adapter.isEnabled());
-                assertEquals(BluetoothAdapter.STATE_TURNING_ON, state);
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = mReceiver.getFiredFlags();
-        mReceiver.resetFiredFlags();
-        fail(String.format("enable() timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)",
-                state, BluetoothAdapter.STATE_ON, firedFlags, mask));
-    }
-
-    private void discoverable(BluetoothAdapter adapter) {
-        int mask = SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG;
-        mReceiver.resetFiredFlags();
-
-        if (!adapter.isEnabled()) {
-            fail("discoverable() bluetooth not enabled");
-        }
-
-        int scanMode = adapter.getScanMode();
-        if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
-            return;
-        }
-
-        assertEquals(scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE);
-        assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE));
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < SET_SCAN_MODE_TIMEOUT) {
-            scanMode = adapter.getScanMode();
-            if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
-                if ((mReceiver.getFiredFlags() & mask) == mask) {
-                    mReceiver.resetFiredFlags();
-                    writeOutput(String.format("discoverable() completed in %d ms",
-                            (System.currentTimeMillis() - s)));
-                    return;
-                }
-            } else {
-                assertEquals(scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE);
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = mReceiver.getFiredFlags();
-        mReceiver.resetFiredFlags();
-        fail(String.format("discoverable() timeout: scanMode=%d (expected %d), flags=0x%x "
-                + "(expected 0x%x)", scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,
-                firedFlags, mask));
-    }
-
-    private void undiscoverable(BluetoothAdapter adapter) {
-        int mask = SCAN_MODE_CONNECTABLE_FLAG;
-        mReceiver.resetFiredFlags();
-
-        if (!adapter.isEnabled()) {
-            fail("undiscoverable() bluetooth not enabled");
-        }
-
-        int scanMode = adapter.getScanMode();
-        if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE) {
-            return;
-        }
-
-        assertEquals(scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
-        assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE));
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < SET_SCAN_MODE_TIMEOUT) {
-            scanMode = adapter.getScanMode();
-            if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE) {
-                if ((mReceiver.getFiredFlags() & mask) == mask) {
-                    mReceiver.resetFiredFlags();
-                    writeOutput(String.format("undiscoverable() completed in %d ms",
-                            (System.currentTimeMillis() - s)));
-                    return;
-                }
-            } else {
-                assertEquals(scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = mReceiver.getFiredFlags();
-        mReceiver.resetFiredFlags();
-        fail(String.format("undiscoverable() timeout: scanMode=%d (expected %d), flags=0x%x "
-                + "(expected 0x%x)", scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE, firedFlags,
-                mask));
-    }
-
-    private void startScan(BluetoothAdapter adapter) {
-        int mask = DISCOVERY_STARTED_FLAG;
-        mReceiver.resetFiredFlags();
-
-        if (!adapter.isEnabled()) {
-            fail("startScan() bluetooth not enabled");
-        }
-
-        if (adapter.isDiscovering()) {
-            return;
-        }
-
-        assertTrue(adapter.startDiscovery());
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < START_DISCOVERY_TIMEOUT) {
-            if (adapter.isDiscovering() && ((mReceiver.getFiredFlags() & mask) == mask)) {
-                mReceiver.resetFiredFlags();
-                writeOutput(String.format("startScan() completed in %d ms",
-                        (System.currentTimeMillis() - s)));
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = mReceiver.getFiredFlags();
-        mReceiver.resetFiredFlags();
-        fail(String.format("startScan() timeout: isDiscovering=%b, flags=0x%x (expected 0x%x)",
-                adapter.isDiscovering(), firedFlags, mask));
-    }
-
-    private void stopScan(BluetoothAdapter adapter) {
-        int mask = DISCOVERY_FINISHED_FLAG;
-        mReceiver.resetFiredFlags();
-
-        if (!adapter.isEnabled()) {
-            fail("stopScan() bluetooth not enabled");
-        }
-
-        if (!adapter.isDiscovering()) {
-            return;
-        }
-
-        // TODO: put assertTrue() around cancelDiscovery() once it starts
-        // returning true.
-        adapter.cancelDiscovery();
-
-        long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < CANCEL_DISCOVERY_TIMEOUT) {
-            if (!adapter.isDiscovering() && ((mReceiver.getFiredFlags() & mask) == mask)) {
-                mReceiver.resetFiredFlags();
-                writeOutput(String.format("stopScan() completed in %d ms",
-                        (System.currentTimeMillis() - s)));
-                return;
-            }
-            sleep(POLL_TIME);
-        }
-
-        int firedFlags = mReceiver.getFiredFlags();
-        mReceiver.resetFiredFlags();
-        fail(String.format("stopScan() timeout: isDiscovering=%b, flags=0x%x (expected 0x%x)",
-                adapter.isDiscovering(), firedFlags, mask));
-
-    }
-
-    private void writeOutput(String s) {
-        if (mOutputWriter == null) {
-            return;
-        }
-        try {
-            Log.i(TAG, s);
-            mOutputWriter.write(s + "\n");
-            mOutputWriter.flush();
-        } catch (IOException e) {
-            Log.w(TAG, "Could not write to output file", e);
-        }
-    }
-
-    private void sleep(long time) {
-        try {
-            Thread.sleep(time);
-        } catch (InterruptedException e) {
-        }
+        mTestUtils.disable(adapter);
     }
 }
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
new file mode 100644
index 0000000..82de509
--- /dev/null
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
@@ -0,0 +1,441 @@
+/*
+ * 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.bluetooth;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Environment;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+public class BluetoothTestUtils extends Assert {
+
+    /**
+     * Timeout for {@link BluetoothAdapter#disable()} in ms.
+     */
+    private static final int DISABLE_TIMEOUT = 5000;
+
+    /**
+     * Timeout for {@link BluetoothAdapter#enable()} in ms.
+     */
+    private static final int ENABLE_TIMEOUT = 20000;
+
+    /**
+     * Timeout for {@link BluetoothAdapter#setScanMode(int)} in ms.
+     */
+    private static final int SET_SCAN_MODE_TIMEOUT = 5000;
+
+    /**
+     * Timeout for {@link BluetoothAdapter#startDiscovery()} in ms.
+     */
+    private static final int START_DISCOVERY_TIMEOUT = 5000;
+
+    /**
+     * Timeout for {@link BluetoothAdapter#cancelDiscovery()} in ms.
+     */
+    private static final int CANCEL_DISCOVERY_TIMEOUT = 5000;
+
+    private static final int DISCOVERY_STARTED_FLAG = 1;
+    private static final int DISCOVERY_FINISHED_FLAG = 1 << 1;
+    private static final int SCAN_MODE_NONE_FLAG = 1 << 2;
+    private static final int SCAN_MODE_CONNECTABLE_FLAG = 1 << 3;
+    private static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG = 1 << 4;
+    private static final int STATE_OFF_FLAG = 1 << 5;
+    private static final int STATE_TURNING_ON_FLAG = 1 << 6;
+    private static final int STATE_ON_FLAG = 1 << 7;
+    private static final int STATE_TURNING_OFF_FLAG = 1 << 8;
+
+    /**
+     * Time between polls in ms.
+     */
+    private static final int POLL_TIME = 100;
+
+    private Context mContext;
+
+    private BufferedWriter mOutputWriter;
+
+    private String mOutputFile;
+    private String mTag;
+
+    private class BluetoothReceiver extends BroadcastReceiver {
+        private int mFiredFlags = 0;
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            synchronized (this) {
+                if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction())) {
+                    mFiredFlags |= DISCOVERY_STARTED_FLAG;
+                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) {
+                    mFiredFlags |= DISCOVERY_FINISHED_FLAG;
+                } else if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(intent.getAction())) {
+                    int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,
+                            BluetoothAdapter.ERROR);
+                    assertNotSame(mode, BluetoothAdapter.ERROR);
+                    switch (mode) {
+                        case BluetoothAdapter.SCAN_MODE_NONE:
+                            mFiredFlags |= SCAN_MODE_NONE_FLAG;
+                            break;
+                        case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
+                            mFiredFlags |= SCAN_MODE_CONNECTABLE_FLAG;
+                            break;
+                        case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
+                            mFiredFlags |= SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG;
+                            break;
+                    }
+                } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
+                    int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                            BluetoothAdapter.ERROR);
+                    assertNotSame(state, BluetoothAdapter.ERROR);
+                    switch (state) {
+                        case BluetoothAdapter.STATE_OFF:
+                            mFiredFlags |= STATE_OFF_FLAG;
+                            break;
+                        case BluetoothAdapter.STATE_TURNING_ON:
+                            mFiredFlags |= STATE_TURNING_ON_FLAG;
+                            break;
+                        case BluetoothAdapter.STATE_ON:
+                            mFiredFlags |= STATE_ON_FLAG;
+                            break;
+                        case BluetoothAdapter.STATE_TURNING_OFF:
+                            mFiredFlags |= STATE_TURNING_OFF_FLAG;
+                            break;
+                    }
+                }
+            }
+        }
+
+        public int getFiredFlags() {
+            synchronized (this) {
+                return mFiredFlags;
+            }
+        }
+
+        public void resetFiredFlags() {
+            synchronized (this) {
+                mFiredFlags = 0;
+            }
+        }
+    }
+
+    private BluetoothReceiver mReceiver = new BluetoothReceiver();
+
+    public BluetoothTestUtils(Context context, String tag) {
+        this(context, tag, null);
+    }
+
+    public BluetoothTestUtils(Context context, String tag, String outputFile) {
+        mContext = context;
+        mTag = tag;
+        mOutputFile = outputFile;
+
+        if (mOutputFile == null) {
+            mOutputWriter = null;
+        } else {
+            try {
+                mOutputWriter = new BufferedWriter(new FileWriter(new File(
+                        Environment.getExternalStorageDirectory(), mOutputFile), true));
+            } catch (IOException e) {
+                Log.w(mTag, "Test output file could not be opened", e);
+                mOutputWriter = null;
+            }
+        }
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
+        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
+        filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    public void close() {
+        mContext.unregisterReceiver(mReceiver);
+
+        if (mOutputWriter != null) {
+            try {
+                mOutputWriter.close();
+            } catch (IOException e) {
+                Log.w(mTag, "Test output file could not be closed", e);
+            }
+        }
+    }
+
+    public void enable(BluetoothAdapter adapter) {
+        int mask = STATE_TURNING_ON_FLAG | STATE_ON_FLAG | SCAN_MODE_CONNECTABLE_FLAG;
+        mReceiver.resetFiredFlags();
+
+        int state = adapter.getState();
+        switch (state) {
+            case BluetoothAdapter.STATE_ON:
+                assertTrue(adapter.isEnabled());
+                return;
+            case BluetoothAdapter.STATE_OFF:
+            case BluetoothAdapter.STATE_TURNING_OFF:
+                assertFalse(adapter.isEnabled());
+                assertTrue(adapter.enable());
+                break;
+            case BluetoothAdapter.STATE_TURNING_ON:
+                assertFalse(adapter.isEnabled());
+                mask = 0; // Don't check for received intents since we might have missed them.
+                break;
+            default:
+                fail("enable() invalid state: state=" + state);
+        }
+
+        long s = System.currentTimeMillis();
+        while (System.currentTimeMillis() - s < ENABLE_TIMEOUT) {
+            state = adapter.getState();
+            if (state == BluetoothAdapter.STATE_ON) {
+                assertTrue(adapter.isEnabled());
+                if ((mReceiver.getFiredFlags() & mask) == mask) {
+                    mReceiver.resetFiredFlags();
+                    writeOutput(String.format("enable() completed in %d ms",
+                            (System.currentTimeMillis() - s)));
+                    return;
+                }
+            } else {
+                assertFalse(adapter.isEnabled());
+                assertEquals(BluetoothAdapter.STATE_TURNING_ON, state);
+            }
+            sleep(POLL_TIME);
+        }
+
+        int firedFlags = mReceiver.getFiredFlags();
+        mReceiver.resetFiredFlags();
+        fail(String.format("enable() timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)",
+                state, BluetoothAdapter.STATE_ON, firedFlags, mask));
+    }
+
+    public void disable(BluetoothAdapter adapter) {
+        int mask = STATE_TURNING_OFF_FLAG | STATE_OFF_FLAG | SCAN_MODE_NONE_FLAG;
+        mReceiver.resetFiredFlags();
+
+        int state = adapter.getState();
+        switch (state) {
+            case BluetoothAdapter.STATE_OFF:
+                assertFalse(adapter.isEnabled());
+                return;
+            case BluetoothAdapter.STATE_ON:
+                assertTrue(adapter.isEnabled());
+                assertTrue(adapter.disable());
+                break;
+            case BluetoothAdapter.STATE_TURNING_ON:
+                assertFalse(adapter.isEnabled());
+                assertTrue(adapter.disable());
+                break;
+            case BluetoothAdapter.STATE_TURNING_OFF:
+                assertFalse(adapter.isEnabled());
+                mask = 0; // Don't check for received intents since we might have missed them.
+                break;
+            default:
+                fail("disable() invalid state: state=" + state);
+        }
+
+        long s = System.currentTimeMillis();
+        while (System.currentTimeMillis() - s < DISABLE_TIMEOUT) {
+            state = adapter.getState();
+            if (state == BluetoothAdapter.STATE_OFF) {
+                assertFalse(adapter.isEnabled());
+                if ((mReceiver.getFiredFlags() & mask) == mask) {
+                    mReceiver.resetFiredFlags();
+                    writeOutput(String.format("disable() completed in %d ms",
+                            (System.currentTimeMillis() - s)));
+                    return;
+                }
+            } else {
+                assertFalse(adapter.isEnabled());
+                assertEquals(BluetoothAdapter.STATE_TURNING_OFF, state);
+            }
+            sleep(POLL_TIME);
+        }
+
+        int firedFlags = mReceiver.getFiredFlags();
+        mReceiver.resetFiredFlags();
+        fail(String.format("disable() timeout: state=%d (expected %d), flags=0x%x (expected 0x%x)",
+                state, BluetoothAdapter.STATE_OFF, firedFlags, mask));
+    }
+
+    public void discoverable(BluetoothAdapter adapter) {
+        int mask = SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG;
+        mReceiver.resetFiredFlags();
+
+        if (!adapter.isEnabled()) {
+            fail("discoverable() bluetooth not enabled");
+        }
+
+        int scanMode = adapter.getScanMode();
+        if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+            return;
+        }
+
+        assertEquals(scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE);
+        assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE));
+
+        long s = System.currentTimeMillis();
+        while (System.currentTimeMillis() - s < SET_SCAN_MODE_TIMEOUT) {
+            scanMode = adapter.getScanMode();
+            if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+                if ((mReceiver.getFiredFlags() & mask) == mask) {
+                    mReceiver.resetFiredFlags();
+                    writeOutput(String.format("discoverable() completed in %d ms",
+                            (System.currentTimeMillis() - s)));
+                    return;
+                }
+            } else {
+                assertEquals(scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE);
+            }
+            sleep(POLL_TIME);
+        }
+
+        int firedFlags = mReceiver.getFiredFlags();
+        mReceiver.resetFiredFlags();
+        fail(String.format("discoverable() timeout: scanMode=%d (expected %d), flags=0x%x "
+                + "(expected 0x%x)", scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,
+                firedFlags, mask));
+    }
+
+    public void undiscoverable(BluetoothAdapter adapter) {
+        int mask = SCAN_MODE_CONNECTABLE_FLAG;
+        mReceiver.resetFiredFlags();
+
+        if (!adapter.isEnabled()) {
+            fail("undiscoverable() bluetooth not enabled");
+        }
+
+        int scanMode = adapter.getScanMode();
+        if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE) {
+            return;
+        }
+
+        assertEquals(scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+        assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE));
+
+        long s = System.currentTimeMillis();
+        while (System.currentTimeMillis() - s < SET_SCAN_MODE_TIMEOUT) {
+            scanMode = adapter.getScanMode();
+            if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE) {
+                if ((mReceiver.getFiredFlags() & mask) == mask) {
+                    mReceiver.resetFiredFlags();
+                    writeOutput(String.format("undiscoverable() completed in %d ms",
+                            (System.currentTimeMillis() - s)));
+                    return;
+                }
+            } else {
+                assertEquals(scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+            }
+            sleep(POLL_TIME);
+        }
+
+        int firedFlags = mReceiver.getFiredFlags();
+        mReceiver.resetFiredFlags();
+        fail(String.format("undiscoverable() timeout: scanMode=%d (expected %d), flags=0x%x "
+                + "(expected 0x%x)", scanMode, BluetoothAdapter.SCAN_MODE_CONNECTABLE, firedFlags,
+                mask));
+    }
+
+    public void startScan(BluetoothAdapter adapter) {
+        int mask = DISCOVERY_STARTED_FLAG;
+        mReceiver.resetFiredFlags();
+
+        if (!adapter.isEnabled()) {
+            fail("startScan() bluetooth not enabled");
+        }
+
+        if (adapter.isDiscovering()) {
+            return;
+        }
+
+        assertTrue(adapter.startDiscovery());
+
+        long s = System.currentTimeMillis();
+        while (System.currentTimeMillis() - s < START_DISCOVERY_TIMEOUT) {
+            if (adapter.isDiscovering() && ((mReceiver.getFiredFlags() & mask) == mask)) {
+                mReceiver.resetFiredFlags();
+                writeOutput(String.format("startScan() completed in %d ms",
+                        (System.currentTimeMillis() - s)));
+                return;
+            }
+            sleep(POLL_TIME);
+        }
+
+        int firedFlags = mReceiver.getFiredFlags();
+        mReceiver.resetFiredFlags();
+        fail(String.format("startScan() timeout: isDiscovering=%b, flags=0x%x (expected 0x%x)",
+                adapter.isDiscovering(), firedFlags, mask));
+    }
+
+    public void stopScan(BluetoothAdapter adapter) {
+        int mask = DISCOVERY_FINISHED_FLAG;
+        mReceiver.resetFiredFlags();
+
+        if (!adapter.isEnabled()) {
+            fail("stopScan() bluetooth not enabled");
+        }
+
+        if (!adapter.isDiscovering()) {
+            return;
+        }
+
+        // TODO: put assertTrue() around cancelDiscovery() once it starts returning true.
+        adapter.cancelDiscovery();
+
+        long s = System.currentTimeMillis();
+        while (System.currentTimeMillis() - s < CANCEL_DISCOVERY_TIMEOUT) {
+            if (!adapter.isDiscovering() && ((mReceiver.getFiredFlags() & mask) == mask)) {
+                mReceiver.resetFiredFlags();
+                writeOutput(String.format("stopScan() completed in %d ms",
+                        (System.currentTimeMillis() - s)));
+                return;
+            }
+            sleep(POLL_TIME);
+        }
+
+        int firedFlags = mReceiver.getFiredFlags();
+        mReceiver.resetFiredFlags();
+        fail(String.format("stopScan() timeout: isDiscovering=%b, flags=0x%x (expected 0x%x)",
+                adapter.isDiscovering(), firedFlags, mask));
+
+    }
+
+    public void writeOutput(String s) {
+        Log.i(mTag, s);
+        if (mOutputWriter == null) {
+            return;
+        }
+        try {
+            mOutputWriter.write(s + "\n");
+            mOutputWriter.flush();
+        } catch (IOException e) {
+            Log.w(mTag, "Could not write to output file", e);
+        }
+    }
+
+    private void sleep(long time) {
+        try {
+            Thread.sleep(time);
+        } catch (InterruptedException e) {
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index de3d153..975a4c2 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -1392,8 +1392,10 @@
                 assertNotNull(info);
                 if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) {
                     assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0);
+                    assertTrue(info.nativeLibraryDir.startsWith(info.dataDir));
                 } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){
                     assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
+                    assertTrue(info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX));
                 }
             }
         } catch (NameNotFoundException e) {
diff --git a/core/tests/coretests/src/android/database/DatabaseErrorHandlerTest.java b/core/tests/coretests/src/android/database/DatabaseErrorHandlerTest.java
new file mode 100644
index 0000000..48d25b9
--- /dev/null
+++ b/core/tests/coretests/src/android/database/DatabaseErrorHandlerTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.database;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+public class DatabaseErrorHandlerTest extends AndroidTestCase {
+
+    private SQLiteDatabase mDatabase;
+    private File mDatabaseFile;
+    private static final String DB_NAME = "database_test.db";
+    private File dbDir;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        dbDir = getContext().getDir(this.getClass().getName(), Context.MODE_PRIVATE);
+        mDatabaseFile = new File(dbDir, DB_NAME);
+        if (mDatabaseFile.exists()) {
+            mDatabaseFile.delete();
+        }
+        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null,
+                new MyDatabaseCorruptionHandler());
+        assertNotNull(mDatabase);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDatabase.close();
+        mDatabaseFile.delete();
+        super.tearDown();
+    }
+
+    public void testNoCorruptionCase() {
+        new MyDatabaseCorruptionHandler().onCorruption(mDatabase);
+        // database file should still exist
+        assertTrue(mDatabaseFile.exists());
+    }
+
+    public void testDatabaseIsCorrupt() throws IOException {
+        mDatabase.execSQL("create table t (i int);");
+        // write junk into the database file
+        BufferedWriter writer = new BufferedWriter(new FileWriter(mDatabaseFile.getPath()));
+        writer.write("blah");
+        writer.close();
+        assertTrue(mDatabaseFile.exists());
+        // since the database file is now corrupt, doing any sql on this database connection
+        // should trigger call to MyDatabaseCorruptionHandler.onCorruption
+        try {
+            mDatabase.execSQL("select * from t;");
+            fail("expected exception");
+        } catch (SQLiteException e) {
+            // expected
+        }
+        // after corruption handler is called, the database file should be free of
+        // database corruption
+        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null,
+                new MyDatabaseCorruptionHandler());
+        assertTrue(db.isDatabaseIntegrityOk());
+    }
+
+    /**
+     * An example implementation of {@link DatabaseErrorHandler} to demonstrate
+     * database corruption handler which checks to make sure database is indeed
+     * corrupt before deleting the file.
+     */
+    public class MyDatabaseCorruptionHandler implements DatabaseErrorHandler {
+        public void onCorruption(SQLiteDatabase dbObj) {
+            boolean databaseOk = dbObj.isDatabaseIntegrityOk();
+            // close the database
+            try {
+                dbObj.close();
+            } catch (SQLiteException e) {
+                /* ignore */
+            }
+            if (databaseOk) {
+                // database is just fine. no need to delete the database file
+                Log.e("MyDatabaseCorruptionHandler", "no corruption in the database: " +
+                        mDatabaseFile.getPath());
+            } else {
+                // database is corrupt. delete the database file
+                Log.e("MyDatabaseCorruptionHandler", "deleting the database file: " +
+                        mDatabaseFile.getPath());
+                new File(dbDir, DB_NAME).delete();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/data/etc/android.hardware.nfc.xml b/data/etc/android.hardware.nfc.xml
new file mode 100644
index 0000000..81c4a84
--- /dev/null
+++ b/data/etc/android.hardware.nfc.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<!-- This is the standard feature indicating that the device can communicate
+     using Near-Field Communications (NFC). -->
+<permissions>
+    <feature name="android.hardware.nfc" />
+</permissions>
diff --git a/data/etc/android.hardware.sensor.barometer.xml b/data/etc/android.hardware.sensor.barometer.xml
new file mode 100644
index 0000000..ebd392d
--- /dev/null
+++ b/data/etc/android.hardware.sensor.barometer.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<!-- Feature for devices with barometer. -->
+<permissions>
+    <feature name="android.hardware.sensor.barometer" />
+</permissions>
diff --git a/data/etc/android.hardware.sensor.gyroscope.xml b/data/etc/android.hardware.sensor.gyroscope.xml
new file mode 100644
index 0000000..fe79632
--- /dev/null
+++ b/data/etc/android.hardware.sensor.gyroscope.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<!-- Feature for devices with gyroscope. -->
+<permissions>
+    <feature name="android.hardware.sensor.gyroscope" />
+</permissions>
diff --git a/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml b/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml
new file mode 100644
index 0000000..80bf859
--- /dev/null
+++ b/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+
+<!-- This is the standard set of features for a touchscreen that supports
+     independently-trackable multiple-finger multitouch. -->
+<permissions>
+    <feature name="android.hardware.touchscreen" />
+    <feature name="android.hardware.touchscreen.multitouch" />
+    <feature name="android.hardware.touchscreen.multitouch.distinct" />
+    <feature name="android.hardware.touchscreen.multitouch.jazzhand" />
+</permissions>
diff --git a/data/etc/android.software.sip.voip.xml b/data/etc/android.software.sip.voip.xml
new file mode 100644
index 0000000..edd06c1
--- /dev/null
+++ b/data/etc/android.software.sip.voip.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- This is the standard set of features for devices that support SIP-based VoIP. -->
+<permissions>
+    <feature name="android.software.sip" />
+    <feature name="android.software.sip.voip" />
+</permissions>
diff --git a/data/etc/android.software.sip.xml b/data/etc/android.software.sip.xml
new file mode 100644
index 0000000..d9fcaad
--- /dev/null
+++ b/data/etc/android.software.sip.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- This is the standard set of features for devices that support the SIP API. -->
+<permissions>
+    <feature name="android.software.sip" />
+</permissions>
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index efca4c2..a3c9f6d 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -38,10 +38,19 @@
     <!-- devices with a front facing camera must include
          android.hardware.camera.front.xml -->
     <!-- devices with WiFi must also include android.hardware.wifi.xml -->
-    <!-- devices with limited/gestural multitouch must also include
-         android.hardware.touchscreen.multitouch.xml -->
-    <!-- devices with full multitouch must also include
-         android.hardware.touchscreen.multitouch.distinct.xml -->
+    <!-- devices that support multitouch must include the most appropriate one
+         of these files:
+
+         If only partial (non-independent) pointers are supported:
+         android.hardware.touchscreen.multitouch.xml
+
+         If up to 4 independently tracked pointers are supported:
+         include android.hardware.touchscreen.multitouch.distinct.xml
+
+         If 5 or more independently tracked pointers are supported:
+         include android.hardware.touchscreen.multitouch.jazzhand.xml
+
+         ONLY ONE of the above should be included. -->
     <!-- devices with an ambient light sensor must also include
          android.hardware.sensor.light.xml -->
     <!-- devices with a proximity sensor must also include
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 0e5df8c..439fc90 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -94,8 +94,6 @@
     <assign-permission name="android.permission.CALL_PHONE" uid="shell" />
     <assign-permission name="android.permission.READ_CONTACTS" uid="shell" />
     <assign-permission name="android.permission.WRITE_CONTACTS" uid="shell" />
-    <assign-permission name="android.permission.READ_OWNER_DATA" uid="shell" />
-    <assign-permission name="android.permission.WRITE_OWNER_DATA" uid="shell" />
     <assign-permission name="android.permission.READ_CALENDAR" uid="shell" />
     <assign-permission name="android.permission.WRITE_CALENDAR" uid="shell" />
     <assign-permission name="android.permission.READ_USER_DICTIONARY" uid="shell" />
diff --git a/data/etc/tablet_core_hardware.xml b/data/etc/tablet_core_hardware.xml
new file mode 100644
index 0000000..952d0782
--- /dev/null
+++ b/data/etc/tablet_core_hardware.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+
+<!-- These are the hardware components that all handheld devices
+     must include. Devices with optional hardware must also include extra
+     hardware files, per the comments below.
+
+     Handheld devices include phones, mobile Internet devices (MIDs),
+     Personal Media Players (PMPs), small tablets (7" or less), and similar
+     devices.
+-->
+<permissions>
+    <feature name="android.hardware.location" />
+    <feature name="android.hardware.location.network" />
+    <feature name="android.hardware.sensor.compass" />
+    <feature name="android.hardware.sensor.accelerometer" />
+    <feature name="android.hardware.bluetooth" />
+    <feature name="android.hardware.touchscreen" />
+    <feature name="android.hardware.touchscreen.multitouch" />
+    <feature name="android.hardware.touchscreen.multitouch.distinct" />
+    <feature name="android.hardware.microphone" />
+    <!-- devices with GPS must include android.hardware.location.gps.xml -->
+    <!-- devices with a rear-facing camera must include one of these as appropriate:
+         android.hardware.camera.xml or 
+         android.hardware.camera.autofocus.xml or 
+         android.hardware.camera.autofocus-flash.xml -->
+    <!-- devices with a front facing camera must include
+         android.hardware.camera.front.xml -->
+    <!-- devices with WiFi must also include android.hardware.wifi.xml -->
+    <!-- devices with an ambient light sensor must also include
+         android.hardware.sensor.light.xml -->
+    <!-- devices with a proximity sensor must also include
+         android.hardware.sensor.proximity.xml -->
+    <!-- devices with a barometer must also include
+         android.hardware.sensor.barometer.xml -->
+    <!-- devices with a gyroscope must also include
+         android.hardware.sensor.gyroscope.xml -->
+    <!-- GSM phones must also include android.hardware.telephony.gsm.xml -->
+    <!-- CDMA phones must also include android.hardware.telephony.cdma.xml -->
+</permissions>
diff --git a/docs/html/guide/topics/data/data-storage.jd b/docs/html/guide/topics/data/data-storage.jd
index 293a057..e20d1ed 100644
--- a/docs/html/guide/topics/data/data-storage.jd
+++ b/docs/html/guide/topics/data/data-storage.jd
@@ -115,7 +115,7 @@
     public static final String PREFS_NAME = "MyPrefsFile";
 
     &#64;Override
-    protected void onCreate(Bundle state){         
+    protected void onCreate(Bundle state){
        super.onCreate(state);
        . . .
 
@@ -374,7 +374,7 @@
 can execute a SQLite command to create tables in the database. For example:</p>
 
 <pre>
-public class MyDbOpenHelper extends SQLiteOpenHelper {
+public class DictionaryOpenHelper extends SQLiteOpenHelper {
 
     private static final int DATABASE_VERSION = 2;
     private static final String DICTIONARY_TABLE_NAME = "dictionary";
diff --git a/docs/html/guide/topics/resources/more-resources.jd b/docs/html/guide/topics/resources/more-resources.jd
index a647571..6cae1eb 100644
--- a/docs/html/guide/topics/resources/more-resources.jd
+++ b/docs/html/guide/topics/resources/more-resources.jd
@@ -216,10 +216,13 @@
 For example: 10px, 2in, 5sp. The following units of measure are supported by Android:</p>
 <dl>
   <dt>{@code dp}</dt>
-    <dd>Density-independent Pixels - an abstract unit that is based on the physical density of the screen.
-    These units are relative to a 160 dpi screen, so one dp is one pixel on a 160 dpi screen. The ratio of
-    dp-to-pixel will change with the screen density, but not necessarily in direct proportion. The
-      compiler accepts both "dip" and "dp", though "dp" is more consistent with "sp".</dd>
+    <dd>Density-independent Pixels - an abstract unit that is based on the physical density of the
+screen. These units are relative to a 160 dpi (dots per inch) screen, so <em>{@code 160dp} is
+always one inch</em> regardless of the screen density. The ratio of dp-to-pixel will change with the
+screen density, but not necessarily in direct proportion. You should use these units when specifying
+view dimensions in your layout, so the UI properly scales to render at the same actual size on
+different screens. (The compiler accepts both "dip" and "dp", though "dp" is more consistent with
+"sp".)</dd>
   <dt>{@code sp}</dt>
     <dd>Scale-independent Pixels - this is like the dp unit, but it is also scaled by the user's font
     size preference. It is recommend you use this unit when specifying font sizes, so they will be adjusted
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 36a8e57..e75a19e 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1551,7 +1551,52 @@
         drawPicture(picture);
         restore();
     }
-    
+
+    /**
+     * <p>Acquires the Canvas context. After invoking this method, the Canvas
+     * context  can be modified by the caller. For instance, if you acquire
+     * the context of an OpenGL Canvas you can reset the GL viewport, scissor,
+     * etc.</p>
+     * 
+     * <p>A call to {@link #acquireContext()} should aways be followed by
+     * a call to {@link #releaseContext()}, preferrably using a try block:</p>
+     * 
+     * <pre>
+     * try {
+     *     if (canvas.acquireContext()) {
+     *         // Use the canvas and/or its context
+     *     }
+     * } finally {
+     *     canvas.releaseContext();
+     * }
+     * </pre>
+     * 
+     * <p>Acquiring the context can be an expensive operation and should not
+     * be done unless absolutely necessary.</p>
+     * 
+     * <p>Applications should never invoke this method directly.</p>
+     * 
+     * @return True if the context could be acquired successfully, false
+     *         otherwise (if the context is already acquired for instance.)
+     * 
+     * @see #releaseContext() 
+     * 
+     * @hide
+     */
+    public boolean acquireContext() {
+        return false;
+    }
+
+    /**
+     * <p>Release the context acquired with {@link #acquireContext()}.</p>
+     * 
+     * @see #acquireContext() 
+     * 
+     * @hide
+     */
+    public void releaseContext() {
+    }
+
     @Override
     protected void finalize() throws Throwable {
         try {
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 6775c08..985d700 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -90,7 +90,7 @@
         subData1D(0, mType.getElementCount(), d);
     }
 
-    public void subData(int off, FieldPacker fp) {
+    public void subData(int xoff, FieldPacker fp) {
         int eSize = mType.mElement.getSizeBytes();
         final byte[] data = fp.getData();
 
@@ -99,8 +99,28 @@
             throw new IllegalArgumentException("Field packer length " + data.length +
                                                " not divisible by element size " + eSize + ".");
         }
-        data1DChecks(off, count, data.length, data.length);
-        mRS.nAllocationSubData1D(mID, off, count, data, data.length);
+        data1DChecks(xoff, count, data.length, data.length);
+        mRS.nAllocationSubData1D(mID, xoff, count, data, data.length);
+    }
+
+
+    public void subElementData(int xoff, int component_number, FieldPacker fp) {
+        if (component_number >= mType.mElement.mElements.length) {
+            throw new IllegalArgumentException("Component_number " + component_number + " out of range.");
+        }
+        if(xoff < 0) {
+            throw new IllegalArgumentException("Offset must be >= 0.");
+        }
+
+        final byte[] data = fp.getData();
+        int eSize = mType.mElement.mElements[component_number].getSizeBytes();
+
+        if (data.length != eSize) {
+            throw new IllegalArgumentException("Field packer sizelength " + data.length +
+                                               " does not match component size " + eSize + ".");
+        }
+
+        mRS.nAllocationSubElementData1D(mID, xoff, component_number, data, data.length);
     }
 
     private void data1DChecks(int off, int count, int len, int dataSize) {
@@ -142,7 +162,6 @@
     }
 
 
-
     public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
         mRS.validate();
         mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
@@ -163,20 +182,6 @@
         mRS.nAllocationRead(mID, d);
     }
 
-    public void data(Object o) {
-        mRS.validate();
-        mRS.nAllocationSubDataFromObject(mID, mType, 0, o);
-    }
-
-    public void read(Object o) {
-        mRS.validate();
-        mRS.nAllocationSubReadFromObject(mID, mType, 0, o);
-    }
-
-    public void subData(int offset, Object o) {
-        mRS.validate();
-        mRS.nAllocationSubDataFromObject(mID, mType, offset, o);
-    }
 
     public class Adapter1D extends BaseObj {
         Adapter1D(int id, RenderScript rs) {
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index fd89b6e..791dac8 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -55,13 +55,13 @@
         mCullMode = CullMode.BACK;
     }
 
-    public void setLineWidth(float w) {
+    void setLineWidth(float w) {
         mRS.validate();
         mLineWidth = w;
         mRS.nProgramRasterSetLineWidth(mID, w);
     }
 
-    public void setCullMode(CullMode m) {
+    void setCullMode(CullMode m) {
         mRS.validate();
         mCullMode = m;
         mRS.nProgramRasterSetCullMode(mID, m.mID);
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 08ba7e2..62d70a7 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -177,14 +177,6 @@
     synchronized int nTypeCreate() {
         return rsnTypeCreate(mContext);
     }
-    native void rsnTypeFinalDestroy(int con, Type t);
-    synchronized void nTypeFinalDestroy(Type t) {
-        rsnTypeFinalDestroy(mContext, t);
-    }
-    native void rsnTypeSetupFields(int con, Type t, int[] types, int[] bits, Field[] IDs);
-    synchronized void nTypeSetupFields(Type t, int[] types, int[] bits, Field[] IDs) {
-        rsnTypeSetupFields(mContext, t, types, bits, IDs);
-    }
     native void rsnTypeGetNativeData(int con, int id, int[] typeData);
     synchronized void nTypeGetNativeData(int id, int[] typeData) {
         rsnTypeGetNativeData(mContext, id, typeData);
@@ -232,6 +224,10 @@
     synchronized void nAllocationSubData1D(int id, int off, int count, byte[] d, int sizeBytes) {
         rsnAllocationSubData1D(mContext, id, off, count, d, sizeBytes);
     }
+    native void rsnAllocationSubElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
+    synchronized void nAllocationSubElementData1D(int id, int xoff, int compIdx, byte[] d, int sizeBytes) {
+        rsnAllocationSubElementData1D(mContext, id, xoff, compIdx, d, sizeBytes);
+    }
     native void rsnAllocationSubData1D(int con, int id, int off, int count, float[] d, int sizeBytes);
     synchronized void nAllocationSubData1D(int id, int off, int count, float[] d, int sizeBytes) {
         rsnAllocationSubData1D(mContext, id, off, count, d, sizeBytes);
@@ -253,14 +249,6 @@
     synchronized void nAllocationRead(int id, float[] d) {
         rsnAllocationRead(mContext, id, d);
     }
-    native void rsnAllocationSubDataFromObject(int con, int id, Type t, int offset, Object o);
-    synchronized void nAllocationSubDataFromObject(int id, Type t, int offset, Object o) {
-        rsnAllocationSubDataFromObject(mContext, id, t, offset, o);
-    }
-    native void rsnAllocationSubReadFromObject(int con, int id, Type t, int offset, Object o);
-    synchronized void nAllocationSubReadFromObject(int id, Type t, int offset, Object o) {
-        rsnAllocationSubReadFromObject(mContext, id, t, offset, o);
-    }
     native int  rsnAllocationGetType(int con, int id);
     synchronized int nAllocationGetType(int id) {
         return rsnAllocationGetType(mContext, id);
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index 21053c9..0b3db69 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -33,7 +33,6 @@
     int mElementCount;
     Element mElement;
 
-    private int mNativeCache;
     Class mJavaClass;
 
     public Element getElement() {
@@ -98,14 +97,9 @@
 
     Type(int id, RenderScript rs) {
         super(id, rs);
-        mNativeCache = 0;
     }
 
     protected void finalize() throws Throwable {
-        if(mNativeCache != 0) {
-            mRS.nTypeFinalDestroy(this);
-            mNativeCache = 0;
-        }
         super.finalize();
     }
 
diff --git a/graphics/jni/Android.mk b/graphics/jni/Android.mk
index 8476be1..4c4a128 100644
--- a/graphics/jni/Android.mk
+++ b/graphics/jni/Android.mk
@@ -13,14 +13,13 @@
 
 LOCAL_SHARED_LIBRARIES := \
         libandroid_runtime \
-        libacc \
         libnativehelper \
         libRS \
         libcutils \
         libskia \
         libutils \
         libui \
-        libsurfaceflinger_client 
+        libsurfaceflinger_client
 
 LOCAL_STATIC_LIBRARIES :=
 
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 81f08e9..c8e6656 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -70,9 +70,6 @@
 
     jclass bitmapClass = _env->FindClass("android/graphics/Bitmap");
     gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I");
-
-    jclass typeClass = _env->FindClass("android/renderscript/Type");
-    gTypeNativeCache = _env->GetFieldID(typeClass, "mNativeCache", "I");
 }
 
 static void nInitElements(JNIEnv *_env, jobject _this, jint a8, jint rgba4444, jint rgba8888, jint rgb565)
@@ -360,124 +357,6 @@
     }
 }
 
-static void * SF_LoadInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
-{
-    ((int32_t *)buffer)[0] = _env->GetIntField(_obj, _field);
-    return ((uint8_t *)buffer) + 4;
-}
-
-static void * SF_LoadShort(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
-{
-    ((int16_t *)buffer)[0] = _env->GetShortField(_obj, _field);
-    return ((uint8_t *)buffer) + 2;
-}
-
-static void * SF_LoadByte(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
-{
-    ((int8_t *)buffer)[0] = _env->GetByteField(_obj, _field);
-    return ((uint8_t *)buffer) + 1;
-}
-
-static void * SF_LoadFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
-{
-    ((float *)buffer)[0] = _env->GetFloatField(_obj, _field);
-    return ((uint8_t *)buffer) + 4;
-}
-
-static void * SF_SaveInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
-{
-    _env->SetIntField(_obj, _field, ((int32_t *)buffer)[0]);
-    return ((uint8_t *)buffer) + 4;
-}
-
-static void * SF_SaveShort(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
-{
-    _env->SetShortField(_obj, _field, ((int16_t *)buffer)[0]);
-    return ((uint8_t *)buffer) + 2;
-}
-
-static void * SF_SaveByte(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
-{
-    _env->SetByteField(_obj, _field, ((int8_t *)buffer)[0]);
-    return ((uint8_t *)buffer) + 1;
-}
-
-static void * SF_SaveFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
-{
-    _env->SetFloatField(_obj, _field, ((float *)buffer)[0]);
-    return ((uint8_t *)buffer) + 4;
-}
-
-struct TypeFieldCache {
-    jfieldID field;
-    int bits;
-    void * (*ptr)(JNIEnv *, jobject, jfieldID, void *buffer);
-    void * (*readPtr)(JNIEnv *, jobject, jfieldID, void *buffer);
-};
-
-struct TypeCache {
-    int fieldCount;
-    int size;
-    TypeFieldCache fields[1];
-};
-
-//{"nTypeFinalDestroy",              "(Landroid/renderscript/Type;)V",       (void*)nTypeFinalDestroy },
-static void
-nTypeFinalDestroy(JNIEnv *_env, jobject _this, RsContext con, jobject _type)
-{
-    TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache);
-    free(tc);
-}
-
-// native void nTypeSetupFields(Type t, int[] types, int[] bits, Field[] IDs);
-static void
-nTypeSetupFields(JNIEnv *_env, jobject _this, RsContext con, jobject _type, jintArray _types, jintArray _bits, jobjectArray _IDs)
-{
-    int fieldCount = _env->GetArrayLength(_types);
-    size_t structSize = sizeof(TypeCache) + (sizeof(TypeFieldCache) * (fieldCount-1));
-    TypeCache *tc = (TypeCache *)malloc(structSize);
-    memset(tc, 0, structSize);
-
-    TypeFieldCache *tfc = &tc->fields[0];
-    tc->fieldCount = fieldCount;
-    _env->SetIntField(_type, gTypeNativeCache, (jint)tc);
-
-    jint *fType = _env->GetIntArrayElements(_types, NULL);
-    jint *fBits = _env->GetIntArrayElements(_bits, NULL);
-    for (int ct=0; ct < fieldCount; ct++) {
-        jobject field = _env->GetObjectArrayElement(_IDs, ct);
-        tfc[ct].field = _env->FromReflectedField(field);
-        tfc[ct].bits = fBits[ct];
-
-        switch(fType[ct]) {
-        case RS_TYPE_FLOAT_32:
-            tfc[ct].ptr = SF_LoadFloat;
-            tfc[ct].readPtr = SF_SaveFloat;
-            break;
-        case RS_TYPE_UNSIGNED_32:
-        case RS_TYPE_SIGNED_32:
-            tfc[ct].ptr = SF_LoadInt;
-            tfc[ct].readPtr = SF_SaveInt;
-            break;
-        case RS_TYPE_UNSIGNED_16:
-        case RS_TYPE_SIGNED_16:
-            tfc[ct].ptr = SF_LoadShort;
-            tfc[ct].readPtr = SF_SaveShort;
-            break;
-        case RS_TYPE_UNSIGNED_8:
-        case RS_TYPE_SIGNED_8:
-            tfc[ct].ptr = SF_LoadByte;
-            tfc[ct].readPtr = SF_SaveByte;
-            break;
-        }
-        tc->size += 4;
-    }
-
-    _env->ReleaseIntArrayElements(_types, fType, JNI_ABORT);
-    _env->ReleaseIntArrayElements(_bits, fBits, JNI_ABORT);
-}
-
-
 // -----------------------------------
 
 static jint
@@ -649,6 +528,17 @@
 }
 
 static void
+//    native void rsnAllocationSubElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
+nAllocationSubElementData1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint compIdx, jbyteArray data, int sizeBytes)
+{
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocationSubElementData1D, 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);
+    rsAllocation1DSubElementData(con, (RsAllocation)alloc, offset, ptr, compIdx, sizeBytes);
+    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
 nAllocationSubData2D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint w, jint h, jintArray data, int sizeBytes)
 {
     jint len = _env->GetArrayLength(data);
@@ -688,45 +578,6 @@
     _env->ReleaseFloatArrayElements(data, ptr, 0);
 }
 
-
-//{"nAllocationDataFromObject",      "(ILandroid/renderscript/Type;Ljava/lang/Object;)V",   (void*)nAllocationDataFromObject },
-static void
-nAllocationSubDataFromObject(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject _type, jint offset, jobject _o)
-{
-    LOG_API("nAllocationDataFromObject con(%p), alloc(%p)", con, (RsAllocation)alloc);
-
-    const TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache);
-
-    void * bufAlloc = malloc(tc->size);
-    void * buf = bufAlloc;
-    for (int ct=0; ct < tc->fieldCount; ct++) {
-        const TypeFieldCache *tfc = &tc->fields[ct];
-        buf = tfc->ptr(_env, _o, tfc->field, buf);
-    }
-    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, 1, bufAlloc, tc->size);
-    free(bufAlloc);
-}
-
-static void
-nAllocationSubReadFromObject(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject _type, jint offset, jobject _o)
-{
-    LOG_API("nAllocationReadFromObject con(%p), alloc(%p)", con, (RsAllocation)alloc);
-
-    assert(offset == 0);
-
-    const TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache);
-
-    void * bufAlloc = malloc(tc->size);
-    void * buf = bufAlloc;
-    rsAllocationRead(con, (RsAllocation)alloc, bufAlloc);
-
-    for (int ct=0; ct < tc->fieldCount; ct++) {
-        const TypeFieldCache *tfc = &tc->fields[ct];
-        buf = tfc->readPtr(_env, _o, tfc->field, buf);
-    }
-    free(bufAlloc);
-}
-
 static jint
 nAllocationGetType(JNIEnv *_env, jobject _this, RsContext con, jint a)
 {
@@ -1386,8 +1237,6 @@
 {"rsnTypeBegin",                     "(II)V",                                 (void*)nTypeBegin },
 {"rsnTypeAdd",                       "(III)V",                                (void*)nTypeAdd },
 {"rsnTypeCreate",                    "(I)I",                                  (void*)nTypeCreate },
-{"rsnTypeFinalDestroy",              "(ILandroid/renderscript/Type;)V",       (void*)nTypeFinalDestroy },
-{"rsnTypeSetupFields",               "(ILandroid/renderscript/Type;[I[I[Ljava/lang/reflect/Field;)V", (void*)nTypeSetupFields },
 {"rsnTypeGetNativeData",             "(II[I)V",                                (void*)nTypeGetNativeData },
 
 {"rsnAllocationCreateTyped",         "(II)I",                                 (void*)nAllocationCreateTyped },
@@ -1401,12 +1250,11 @@
 {"rsnAllocationSubData1D",           "(IIII[SI)V",                            (void*)nAllocationSubData1D_s },
 {"rsnAllocationSubData1D",           "(IIII[BI)V",                            (void*)nAllocationSubData1D_b },
 {"rsnAllocationSubData1D",           "(IIII[FI)V",                            (void*)nAllocationSubData1D_f },
+{"rsnAllocationSubElementData1D",    "(IIII[BI)V",                            (void*)nAllocationSubElementData1D },
 {"rsnAllocationSubData2D",           "(IIIIII[II)V",                          (void*)nAllocationSubData2D_i },
 {"rsnAllocationSubData2D",           "(IIIIII[FI)V",                          (void*)nAllocationSubData2D_f },
 {"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
 {"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
-{"rsnAllocationSubDataFromObject",   "(IILandroid/renderscript/Type;ILjava/lang/Object;)V",   (void*)nAllocationSubDataFromObject },
-{"rsnAllocationSubReadFromObject",   "(IILandroid/renderscript/Type;ILjava/lang/Object;)V",   (void*)nAllocationSubReadFromObject },
 {"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
 
 {"rsnAdapter1DBindAllocation",       "(III)V",                                (void*)nAdapter1DBindAllocation },
diff --git a/graphics/tests/graphicstests/src/android/graphics/BitmapFactoryTest.java b/graphics/tests/graphicstests/src/android/graphics/BitmapFactoryTest.java
new file mode 100644
index 0000000..09820ef
--- /dev/null
+++ b/graphics/tests/graphicstests/src/android/graphics/BitmapFactoryTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.os.ParcelFileDescriptor;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+
+import junit.framework.TestCase;
+
+
+public class BitmapFactoryTest extends TestCase {
+
+    // tests that we can decode bitmaps from MemoryFiles
+    @SmallTest
+    public void testBitmapParcelFileDescriptor() throws Exception {
+        Bitmap bitmap1 = Bitmap.createBitmap(
+                new int[] { Color.BLUE }, 1, 1, Bitmap.Config.RGB_565);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        bitmap1.compress(Bitmap.CompressFormat.PNG, 100, out);
+        ParcelFileDescriptor pfd = ParcelFileDescriptor.fromData(out.toByteArray(), null);
+        FileDescriptor fd = pfd.getFileDescriptor();
+        assertNotNull("Got null FileDescriptor", fd);
+        assertTrue("Got invalid FileDescriptor", fd.valid());
+        Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fd);
+        assertNotNull("BitmapFactory returned null", bitmap);
+        assertEquals("Bitmap width", 1, bitmap.getWidth());
+        assertEquals("Bitmap height", 1, bitmap.getHeight());
+    }
+
+}
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 04e24d2..b54718f 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -43,7 +43,10 @@
 
             void                setStrictModePolicy(int32_t policy);
             int32_t             getStrictModePolicy() const;
-            
+
+            void                setLastTransactionBinderFlags(int32_t flags);
+            int32_t             getLastTransactionBinderFlags() const;
+
             int64_t             clearCallingIdentity();
             void                restoreCallingIdentity(int64_t token);
             
@@ -113,6 +116,7 @@
             pid_t               mCallingPid;
             uid_t               mCallingUid;
             int32_t             mStrictModePolicy;
+            int32_t             mLastTransactionBinderFlags;
 };
 
 }; // namespace android
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index a5c7874..7c5371a 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -286,13 +286,6 @@
     // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
     static const char KEY_VIDEO_FRAME_FORMAT[];
 
-    // Metering mode. This affects how camera determines exposure.
-    // Example value: "spot" or METERING_MODE_XXX constants. Read/write.
-    static const char KEY_METERING_MODE[];
-    // Supported metering modes.
-    // Example value: "center-weighted,frame-average,spot". Read only.
-    static const char KEY_SUPPORTED_METERING_MODES[];
-
     // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
     static const char TRUE[];
 
@@ -394,16 +387,6 @@
     // focus, applications should change the focus mode to other modes.
     static const char FOCUS_MODE_CONTINUOUS[];
 
-    // The camera determines the exposure by giving more weight to the
-    // central part of the scene.
-    static const char METERING_MODE_CENTER_WEIGHTED[];
-    // The camera determines the exposure by averaging the entire scene,
-    // giving no weighting to any particular area.
-    static const char METERING_MODE_FRAME_AVERAGE[];
-    // The camera determines the exposure by a very small area of the scene,
-    // typically the center.
-    static const char METERING_MODE_SPOT[];
-
 private:
     DefaultKeyedVector<String8,String8>    mMap;
 };
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
index 54b197c..28be7c1 100644
--- a/include/media/IMediaRecorder.h
+++ b/include/media/IMediaRecorder.h
@@ -40,6 +40,7 @@
     virtual	status_t		setAudioEncoder(int ae) = 0;
     virtual	status_t		setOutputFile(const char* path) = 0;
     virtual	status_t		setOutputFile(int fd, int64_t offset, int64_t length) = 0;
+    virtual	status_t		setOutputFileAuxiliary(int fd) = 0;
     virtual	status_t		setVideoSize(int width, int height) = 0;
     virtual	status_t		setVideoFrameRate(int frames_per_second) = 0;
     virtual     status_t                setParameters(const String8& params) = 0;
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 2f61cbe..1f8ce71 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -19,6 +19,7 @@
 #define ANDROID_IOMX_H_
 
 #include <binder/IInterface.h>
+#include <ui/GraphicBuffer.h>
 #include <utils/List.h>
 #include <utils/String8.h>
 
@@ -78,10 +79,17 @@
             node_id node, OMX_INDEXTYPE index,
             const void *params, size_t size) = 0;
 
+    virtual status_t enableGraphicBuffers(
+            node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
+
     virtual status_t useBuffer(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer) = 0;
 
+    virtual status_t useGraphicBuffer(
+            node_id node, OMX_U32 port_index,
+            const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) = 0;
+
     // This API clearly only makes sense if the caller lives in the
     // same process as the callee, i.e. is the media_server, as the
     // returned "buffer_data" pointer is just that, a pointer into local
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
index e5edd29..c42346e 100644
--- a/include/media/MediaRecorderBase.h
+++ b/include/media/MediaRecorderBase.h
@@ -40,6 +40,7 @@
     virtual status_t setPreviewSurface(const sp<Surface>& surface) = 0;
     virtual status_t setOutputFile(const char *path) = 0;
     virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;
+    virtual status_t setOutputFileAuxiliary(int fd) {return INVALID_OPERATION;}
     virtual status_t setParameters(const String8& params) = 0;
     virtual status_t setListener(const sp<IMediaRecorderClient>& listener) = 0;
     virtual status_t prepare() = 0;
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 291b18a..a600f6b 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -170,6 +170,7 @@
     status_t    setAudioEncoder(int ae);
     status_t    setOutputFile(const char* path);
     status_t    setOutputFile(int fd, int64_t offset, int64_t length);
+    status_t    setOutputFileAuxiliary(int fd);
     status_t    setVideoSize(int width, int height);
     status_t    setVideoFrameRate(int frames_per_second);
     status_t    setParameters(const String8& params);
@@ -196,6 +197,7 @@
     bool                        mIsAudioEncoderSet;
     bool                        mIsVideoEncoderSet;
     bool                        mIsOutputFileSet;
+    bool                        mIsAuxiliaryOutputFileSet;
     Mutex                       mLock;
     Mutex                       mNotifyLock;
 };
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 1af4254..a5cec78 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -72,6 +72,7 @@
     int64_t mPrevSampleTimeUs;
     int64_t mTotalLostFrames;
     int64_t mPrevLostBytes;
+    int64_t mInitialReadTimeUs;
 
     MediaBufferGroup *mGroup;
 
diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h
index 221c679..4ded5e8 100644
--- a/include/media/stagefright/HardwareAPI.h
+++ b/include/media/stagefright/HardwareAPI.h
@@ -21,10 +21,60 @@
 #include <media/stagefright/OMXPluginBase.h>
 #include <media/stagefright/VideoRenderer.h>
 #include <surfaceflinger/ISurface.h>
+#include <ui/android_native_buffer.h>
 #include <utils/RefBase.h>
 
 #include <OMX_Component.h>
 
+namespace android {
+
+// A pointer to this struct is passed to the OMX_SetParameter when the extension
+// index for the 'OMX.google.android.index.enableAndroidNativeBuffers' extension
+// is given.
+//
+// When Android native buffer use is disabled for a port (the default state),
+// the OMX node should operate as normal, and expect UseBuffer calls to set its
+// buffers.  This is the mode that will be used when CPU access to the buffer is
+// required.
+//
+// When Android native buffer use has been enabled, the OMX node must support
+// only color formats in the range [OMX_COLOR_FormatAndroidPrivateStart,
+// OMX_COLOR_FormatAndroidPrivateEnd).  The node should then expect to receive
+// UseAndroidNativeBuffer calls (via OMX_SetParameter) rather than UseBuffer
+// calls.
+struct EnableAndroidNativeBuffersParams {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL enable;
+};
+
+// Color formats in the range [OMX_COLOR_FormatAndroidPrivateStart,
+// OMX_COLOR_FormatAndroidPrivateEnd) will be converted to a gralloc pixel
+// format when used to allocate Android native buffers via gralloc.  The
+// conversion is done by subtracting OMX_COLOR_FormatAndroidPrivateStart from
+// the color format reported by the codec.
+enum {
+    OMX_COLOR_FormatAndroidPrivateStart = 0xA0000000,
+    OMX_COLOR_FormatAndroidPrivateEnd = 0xB0000000,
+};
+
+// A pointer to this struct is passed to OMX_SetParameter when the extension
+// index for the 'OMX.google.android.index.useAndroidNativeBuffer' extension is
+// given.  This call will only be performed if a prior call was made with the
+// 'OMX.google.android.index.enableAndroidNativeBuffers' extension index,
+// enabling use of Android native buffers.
+struct UseAndroidNativeBufferParams {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_PTR pAppPrivate;
+    OMX_BUFFERHEADERTYPE **bufferHeader;
+    const sp<android_native_buffer_t>& nativeBuffer;
+};
+
+}  // namespace android
+
 extern android::VideoRenderer *createRenderer(
         const android::sp<android::ISurface> &surface,
         const char *componentName,
@@ -35,4 +85,3 @@
 extern android::OMXPluginBase *createOMXPlugin();
 
 #endif  // HARDWARE_API_H_
-
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 2412f6a..70bd8e8 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -62,6 +62,7 @@
     class Track;
 
     FILE *mFile;
+    bool mUse4ByteNalLength;
     bool mUse32BitOffset;
     bool mPaused;
     bool mStarted;
@@ -132,9 +133,13 @@
     // Adjust other track media clock (presumably wall clock)
     // based on audio track media clock with the drift time.
     int64_t mDriftTimeUs;
-    void addDriftTimeUs(int64_t driftTimeUs);
+    void setDriftTimeUs(int64_t driftTimeUs);
     int64_t getDriftTimeUs();
 
+    // Return whether the nal length is 4 bytes or 2 bytes
+    // Only makes sense for H.264/AVC
+    bool useNalLengthFour();
+
     void lock();
     void unlock();
 
@@ -144,6 +149,7 @@
 
     inline size_t write(const void *ptr, size_t size, size_t nmemb, FILE* stream);
     bool exceedsFileSizeLimit();
+    bool use32BitFileOffset() const;
     bool exceedsFileDurationLimit();
     void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
 
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 43354c2..1e447f1 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -48,6 +48,7 @@
     kKeyTime              = 'time',  // int64_t (usecs)
     kKeyNTPTime           = 'ntpT',  // uint64_t (ntp-timestamp)
     kKeyTargetTime        = 'tarT',  // int64_t (usecs)
+    kKeyDriftTime         = 'dftT',  // int64_t (usecs)
     kKeyDuration          = 'dura',  // int64_t (usecs)
     kKeyColorFormat       = 'colf',
     kKeyPlatformPrivate   = 'priv',  // pointer
@@ -78,6 +79,7 @@
 
     // Set this key to enable authoring files in 64-bit offset
     kKey64BitFileOffset   = 'fobt',  // int32_t (bool)
+    kKey2ByteNalLength    = '2NAL',  // int32_t (bool)
 
     // Identify the file output format for authoring
     // Please see <media/mediarecorder.h> for the supported
@@ -90,6 +92,8 @@
 
     kKeyNotRealTime       = 'ntrt',  // bool (int32_t)
 
+    // Ogg files can be tagged to be automatically looping...
+    kKeyAutoLoop          = 'autL',  // bool (int32_t)
 };
 
 enum {
diff --git a/include/media/stagefright/VideoSourceDownSampler.h b/include/media/stagefright/VideoSourceDownSampler.h
new file mode 100644
index 0000000..439918c
--- /dev/null
+++ b/include/media/stagefright/VideoSourceDownSampler.h
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+// VideoSourceDownSampler implements the MediaSource interface,
+// downsampling frames provided from a real video source.
+
+#ifndef VIDEO_SOURCE_DOWN_SAMPLER_H_
+
+#define VIDEO_SOURCE_DOWN_SAMPLER_H_
+
+#include <media/stagefright/MediaSource.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class IMemory;
+class MediaBuffer;
+class MetaData;
+
+class VideoSourceDownSampler : public MediaSource {
+public:
+    virtual ~VideoSourceDownSampler();
+
+    // Constructor:
+    // videoSource: The real video source which provides the original frames.
+    // width, height: The desired width, height. These should be less than or equal
+    // to those of the real video source. We then downsample the original frames to
+    // this size.
+    VideoSourceDownSampler(const sp<MediaSource> &videoSource,
+        int32_t width, int32_t height);
+
+    // MediaSource interface
+    virtual status_t start(MetaData *params = NULL);
+
+    virtual status_t stop();
+
+    virtual sp<MetaData> getFormat();
+
+    virtual status_t read(
+            MediaBuffer **buffer, const ReadOptions *options = NULL);
+
+    virtual status_t pause();
+
+private:
+    // Reference to the real video source.
+    sp<MediaSource> mRealVideoSource;
+
+    // Size of frames to be provided by this source.
+    int32_t mWidth;
+    int32_t mHeight;
+
+    // Size of frames provided by the real source.
+    int32_t mRealSourceWidth;
+    int32_t mRealSourceHeight;
+
+    // Down sampling paramters.
+    int32_t mDownSampleOffsetX;
+    int32_t mDownSampleOffsetY;
+    int32_t mDownSampleSkipX;
+    int32_t mDownSampleSkipY;
+
+    // True if we need to crop the still video image to get the video frame.
+    bool mNeedDownSampling;
+
+    // Meta data. This is a copy of the real source except for the width and
+    // height parameters.
+    sp<MetaData> mMeta;
+
+    // Computes the offset, skip parameters for downsampling the original frame
+    // to the desired size.
+    void computeDownSamplingParameters();
+
+    // Downsamples the frame in sourceBuffer to size (mWidth x mHeight). A new
+    // buffer is created which stores the downsampled image.
+    void downSampleYUVImage(const MediaBuffer &sourceBuffer, MediaBuffer **buffer) const;
+
+    // Disallow these.
+    VideoSourceDownSampler(const VideoSourceDownSampler &);
+    VideoSourceDownSampler &operator=(const VideoSourceDownSampler &);
+};
+
+}  // namespace android
+
+#endif  // VIDEO_SOURCE_DOWN_SAMPLER_H_
diff --git a/include/media/stagefright/foundation/ALooper.h b/include/media/stagefright/foundation/ALooper.h
index 153ead9..70e0c5e 100644
--- a/include/media/stagefright/foundation/ALooper.h
+++ b/include/media/stagefright/foundation/ALooper.h
@@ -19,6 +19,7 @@
 #define A_LOOPER_H_
 
 #include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
 #include <utils/List.h>
@@ -36,6 +37,9 @@
 
     ALooper();
 
+    // Takes effect in a subsequent call to start().
+    void setName(const char *name);
+
     handler_id registerHandler(const sp<AHandler> &handler);
     void unregisterHandler(handler_id handlerID);
 
@@ -63,6 +67,8 @@
     Mutex mLock;
     Condition mQueueChangedCondition;
 
+    AString mName;
+
     List<Event> mEventQueue;
 
     struct LooperThread;
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index 3d42856..25d5afb 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -82,6 +82,14 @@
     int32_t fuzz;      // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
 
     inline int32_t getRange() { return maxValue - minValue; }
+
+    inline void clear() {
+        valid = false;
+        minValue = 0;
+        maxValue = 0;
+        flat = 0;
+        fuzz = 0;
+    }
 };
 
 /*
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 2385973..3fa825f 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -453,6 +453,10 @@
     inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
     inline int32_t getKeyboardType() const { return mKeyboardType; }
 
+    inline const KeyedVector<int32_t, MotionRange> getMotionRanges() const {
+        return mMotionRanges;
+    }
+
 private:
     int32_t mId;
     String8 mName;
@@ -462,29 +466,6 @@
     KeyedVector<int32_t, MotionRange> mMotionRanges;
 };
 
-/*
- * Provides remote access to information about an input device.
- *
- * Note: This is essentially a wrapper for Binder calls into the Window Manager Service.
- */
-class InputDeviceProxy : public RefBase, public AInputDevice {
-protected:
-    InputDeviceProxy();
-    virtual ~InputDeviceProxy();
-
-public:
-    static void getDeviceIds(Vector<int32_t>& outIds);
-
-    static sp<InputDeviceProxy> getDevice(int32_t id);
-
-    inline const InputDeviceInfo* getInfo() { return & mInfo; }
-
-    // TODO add hasKeys, keymap, etc...
-
-private:
-    InputDeviceInfo mInfo;
-};
-
 
 } // namespace android
 
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index 56d2765..7a089a45 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -35,6 +35,34 @@
 class InputDevice;
 class InputMapper;
 
+/* Describes a virtual key. */
+struct VirtualKeyDefinition {
+    int32_t scanCode;
+
+    // configured position data, specified in display coords
+    int32_t centerX;
+    int32_t centerY;
+    int32_t width;
+    int32_t height;
+};
+
+
+/* Specifies input device calibration settings. */
+class InputDeviceCalibration {
+public:
+    InputDeviceCalibration();
+
+    void clear();
+    void addProperty(const String8& key, const String8& value);
+
+    bool tryGetProperty(const String8& key, String8& outValue) const;
+    bool tryGetProperty(const String8& key, int32_t& outValue) const;
+    bool tryGetProperty(const String8& key, float& outValue) const;
+
+private:
+    KeyedVector<String8, String8> mProperties;
+};
+
 
 /*
  * Input reader policy interface.
@@ -73,17 +101,6 @@
         ACTION_APP_SWITCH_COMING = 0x00000002,
     };
 
-    /* Describes a virtual key. */
-    struct VirtualKeyDefinition {
-        int32_t scanCode;
-
-        // configured position data, specified in display coords
-        int32_t centerX;
-        int32_t centerY;
-        int32_t width;
-        int32_t height;
-    };
-
     /* Gets information about the display with the specified id.
      * Returns true if the display info is available, false otherwise.
      */
@@ -135,6 +152,10 @@
     virtual void getVirtualKeyDefinitions(const String8& deviceName,
             Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0;
 
+    /* Gets the calibration for an input device. */
+    virtual void getInputDeviceCalibration(const String8& deviceName,
+            InputDeviceCalibration& outCalibration) = 0;
+
     /* Gets the excluded device names for the platform. */
     virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
 };
@@ -327,6 +348,10 @@
 
     int32_t getMetaState();
 
+    inline const InputDeviceCalibration& getCalibration() {
+        return mCalibration;
+    }
+
 private:
     InputReaderContext* mContext;
     int32_t mId;
@@ -338,6 +363,8 @@
 
     typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
     int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
+
+    InputDeviceCalibration mCalibration;
 };
 
 
@@ -538,12 +565,12 @@
         }
     };
 
+    // Raw data for a single pointer.
     struct PointerData {
         uint32_t id;
         int32_t x;
         int32_t y;
         int32_t pressure;
-        int32_t size;
         int32_t touchMajor;
         int32_t touchMinor;
         int32_t toolMajor;
@@ -551,6 +578,7 @@
         int32_t orientation;
     };
 
+    // Raw data for a collection of pointers including a pointer id mapping table.
     struct TouchData {
         uint32_t pointerCount;
         PointerData pointers[MAX_POINTERS];
@@ -584,18 +612,82 @@
         bool useAveragingTouchFilter;
     } mParameters;
 
-    // Raw axis information.
-    struct Axes {
+    // Immutable calibration parameters in parsed form.
+    struct Calibration {
+        // Touch Area
+        enum TouchAreaCalibration {
+            TOUCH_AREA_CALIBRATION_DEFAULT,
+            TOUCH_AREA_CALIBRATION_NONE,
+            TOUCH_AREA_CALIBRATION_GEOMETRIC,
+            TOUCH_AREA_CALIBRATION_PRESSURE,
+        };
+
+        TouchAreaCalibration touchAreaCalibration;
+
+        // Tool Area
+        enum ToolAreaCalibration {
+            TOOL_AREA_CALIBRATION_DEFAULT,
+            TOOL_AREA_CALIBRATION_NONE,
+            TOOL_AREA_CALIBRATION_GEOMETRIC,
+            TOOL_AREA_CALIBRATION_LINEAR,
+        };
+
+        ToolAreaCalibration toolAreaCalibration;
+        bool haveToolAreaLinearScale;
+        float toolAreaLinearScale;
+        bool haveToolAreaLinearBias;
+        float toolAreaLinearBias;
+        bool haveToolAreaIsSummed;
+        int32_t toolAreaIsSummed;
+
+        // Pressure
+        enum PressureCalibration {
+            PRESSURE_CALIBRATION_DEFAULT,
+            PRESSURE_CALIBRATION_NONE,
+            PRESSURE_CALIBRATION_PHYSICAL,
+            PRESSURE_CALIBRATION_AMPLITUDE,
+        };
+        enum PressureSource {
+            PRESSURE_SOURCE_DEFAULT,
+            PRESSURE_SOURCE_PRESSURE,
+            PRESSURE_SOURCE_TOUCH,
+        };
+
+        PressureCalibration pressureCalibration;
+        PressureSource pressureSource;
+        bool havePressureScale;
+        float pressureScale;
+
+        // Size
+        enum SizeCalibration {
+            SIZE_CALIBRATION_DEFAULT,
+            SIZE_CALIBRATION_NONE,
+            SIZE_CALIBRATION_NORMALIZED,
+        };
+
+        SizeCalibration sizeCalibration;
+
+        // Orientation
+        enum OrientationCalibration {
+            ORIENTATION_CALIBRATION_DEFAULT,
+            ORIENTATION_CALIBRATION_NONE,
+            ORIENTATION_CALIBRATION_INTERPOLATED,
+        };
+
+        OrientationCalibration orientationCalibration;
+    } mCalibration;
+
+    // Raw axis information from the driver.
+    struct RawAxes {
         RawAbsoluteAxisInfo x;
         RawAbsoluteAxisInfo y;
         RawAbsoluteAxisInfo pressure;
-        RawAbsoluteAxisInfo size;
         RawAbsoluteAxisInfo touchMajor;
         RawAbsoluteAxisInfo touchMinor;
         RawAbsoluteAxisInfo toolMajor;
         RawAbsoluteAxisInfo toolMinor;
         RawAbsoluteAxisInfo orientation;
-    } mAxes;
+    } mRawAxes;
 
     // Current and previous touch sample data.
     TouchData mCurrentTouch;
@@ -620,10 +712,13 @@
         float yScale;
         float yPrecision;
 
-        int32_t pressureOrigin;
+        float geometricScale;
+
+        float toolAreaLinearScale;
+        float toolAreaLinearBias;
+
         float pressureScale;
 
-        int32_t sizeOrigin;
         float sizeScale;
 
         float orientationScale;
@@ -632,12 +727,22 @@
         struct OrientedRanges {
             InputDeviceInfo::MotionRange x;
             InputDeviceInfo::MotionRange y;
+
+            bool havePressure;
             InputDeviceInfo::MotionRange pressure;
+
+            bool haveSize;
             InputDeviceInfo::MotionRange size;
+
+            bool haveTouchArea;
             InputDeviceInfo::MotionRange touchMajor;
             InputDeviceInfo::MotionRange touchMinor;
+
+            bool haveToolArea;
             InputDeviceInfo::MotionRange toolMajor;
             InputDeviceInfo::MotionRange toolMinor;
+
+            bool haveOrientation;
             InputDeviceInfo::MotionRange orientation;
         } orientedRanges;
 
@@ -653,9 +758,14 @@
         } currentVirtualKey;
     } mLocked;
 
-    virtual void configureAxes();
+    virtual void configureParameters();
+    virtual void configureRawAxes();
+    virtual void logRawAxes();
     virtual bool configureSurfaceLocked();
     virtual void configureVirtualKeysLocked();
+    virtual void parseCalibration();
+    virtual void resolveCalibration();
+    virtual void logCalibration();
 
     enum TouchResult {
         // Dispatch the touch normally.
@@ -713,7 +823,8 @@
     TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
     void dispatchTouches(nsecs_t when, uint32_t policyFlags);
     void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
-            BitSet32 idBits, uint32_t changedId, int32_t motionEventAction);
+            BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
+            int32_t motionEventAction);
 
     void applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
             int32_t keyEventAction, int32_t keyEventFlags,
@@ -738,7 +849,7 @@
     virtual void process(const RawEvent* rawEvent);
 
 protected:
-    virtual void configureAxes();
+    virtual void configureRawAxes();
 
 private:
     struct Accumulator {
@@ -767,7 +878,7 @@
     int32_t mX;
     int32_t mY;
     int32_t mPressure;
-    int32_t mSize;
+    int32_t mToolWidth;
 
     void initialize();
 
@@ -784,7 +895,7 @@
     virtual void process(const RawEvent* rawEvent);
 
 protected:
-    virtual void configureAxes();
+    virtual void configureRawAxes();
 
 private:
     struct Accumulator {
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index f6582e6..a3e117f 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -377,6 +377,16 @@
     return mStrictModePolicy;
 }
 
+void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
+{
+    mLastTransactionBinderFlags = flags;
+}
+
+int32_t IPCThreadState::getLastTransactionBinderFlags() const
+{
+    return mLastTransactionBinderFlags;
+}
+
 void IPCThreadState::restoreCallingIdentity(int64_t token)
 {
     mCallingUid = (int)(token>>32);
@@ -598,8 +608,10 @@
 }
 
 IPCThreadState::IPCThreadState()
-    : mProcess(ProcessState::self()), mMyThreadId(androidGetTid()),
-      mStrictModePolicy(0)
+    : mProcess(ProcessState::self()),
+      mMyThreadId(androidGetTid()),
+      mStrictModePolicy(0),
+      mLastTransactionBinderFlags(0)
 {
     pthread_setspecific(gTLS, this);
     clearCaller();
@@ -983,11 +995,11 @@
             }
             if (tr.target.ptr) {
                 sp<BBinder> b((BBinder*)tr.cookie);
-                const status_t error = b->transact(tr.code, buffer, &reply, 0);
+                const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
                 if (error < NO_ERROR) reply.setError(error);
-                
+
             } else {
-                const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
+                const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
                 if (error < NO_ERROR) reply.setError(error);
             }
             
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 18f75df..f329ac4 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -464,7 +464,16 @@
     if (threadState == NULL) {
         threadState = IPCThreadState::self();
     }
-    threadState->setStrictModePolicy(strictPolicy);
+    if ((threadState->getLastTransactionBinderFlags() &
+         IBinder::FLAG_ONEWAY) != 0) {
+      // For one-way calls, the callee is running entirely
+      // disconnected from the caller, so disable StrictMode entirely.
+      // Not only does disk/network usage not impact the caller, but
+      // there's no way to commuicate back any violations anyway.
+      threadState->setStrictModePolicy(0);
+    } else {
+      threadState->setStrictModePolicy(strictPolicy);
+    }
     const String16 str(readString16());
     if (str == interface) {
         return true;
diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
index d0ed7df..362d9ee 100644
--- a/libs/camera/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -73,8 +73,6 @@
 const char CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED[] = "smooth-zoom-supported";
 const char CameraParameters::KEY_FOCUS_DISTANCES[] = "focus-distances";
 const char CameraParameters::KEY_VIDEO_FRAME_FORMAT[] = "video-frame-format";
-const char CameraParameters::KEY_METERING_MODE[] = "metering-mode";
-const char CameraParameters::KEY_SUPPORTED_METERING_MODES[] = "metering-mode-values";
 
 const char CameraParameters::TRUE[] = "true";
 const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity";
@@ -146,11 +144,6 @@
 const char CameraParameters::FOCUS_MODE_EDOF[] = "edof";
 const char CameraParameters::FOCUS_MODE_CONTINUOUS[] = "continuous";
 
-// Values for metering mode settings.
-const char CameraParameters::METERING_MODE_CENTER_WEIGHTED[] = "center-weighted";
-const char CameraParameters::METERING_MODE_FRAME_AVERAGE[] = "frame-average";
-const char CameraParameters::METERING_MODE_SPOT[] = "spot";
-
 CameraParameters::CameraParameters()
                 : mMap()
 {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 4ce30b0..47ab355 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -127,7 +127,8 @@
 }
 
 void OpenGLRenderer::prepare() {
-    mSnapshot = new Snapshot(mFirstSnapshot);
+    mSnapshot = new Snapshot(mFirstSnapshot,
+            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
     mSaveCount = 1;
 
     glViewport(0, 0, mWidth, mHeight);
@@ -143,6 +144,29 @@
     mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
 }
 
+void OpenGLRenderer::acquireContext() {
+    if (mCaches.currentProgram) {
+        if (mCaches.currentProgram->isInUse()) {
+            mCaches.currentProgram->remove();
+            mCaches.currentProgram = NULL;
+        }
+    }
+}
+
+void OpenGLRenderer::releaseContext() {
+    glViewport(0, 0, mSnapshot->viewport.getWidth(), mSnapshot->viewport.getHeight());
+
+    glEnable(GL_SCISSOR_TEST);
+    setScissorFromClip();
+
+    if (mCaches.blend) {
+        glEnable(GL_BLEND);
+        glBlendFunc(mCaches.lastSrcMode, mCaches.lastDstMode);
+    } else {
+        glDisable(GL_BLEND);
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // State management
 ///////////////////////////////////////////////////////////////////////////////
@@ -152,7 +176,7 @@
 }
 
 int OpenGLRenderer::save(int flags) {
-    return saveSnapshot();
+    return saveSnapshot(flags);
 }
 
 void OpenGLRenderer::restore() {
@@ -169,8 +193,8 @@
     }
 }
 
-int OpenGLRenderer::saveSnapshot() {
-    mSnapshot = new Snapshot(mSnapshot);
+int OpenGLRenderer::saveSnapshot(int flags) {
+    mSnapshot = new Snapshot(mSnapshot, flags);
     return mSaveCount++;
 }
 
@@ -208,7 +232,7 @@
 
 int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
         const SkPaint* p, int flags) {
-    int count = saveSnapshot();
+    int count = saveSnapshot(flags);
 
     int alpha = 255;
     SkXfermode::Mode mode;
@@ -235,13 +259,13 @@
 
 int OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
         int alpha, int flags) {
-    int count = saveSnapshot();
-    if (alpha > 0 && !mSnapshot->invisible) {
-        createLayer(mSnapshot, left, top, right, bottom, alpha, SkXfermode::kSrcOver_Mode, flags);
+    if (alpha == 0xff) {
+        return saveLayer(left, top, right, bottom, NULL, flags);
     } else {
-        mSnapshot->invisible = true;
+        SkPaint paint;
+        paint.setAlpha(alpha);
+        return saveLayer(left, top, right, bottom, &paint, flags);
     }
-    return count;
 }
 
 bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
@@ -249,8 +273,12 @@
     LAYER_LOGD("Requesting layer %fx%f", right - left, bottom - top);
     LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize());
 
+    Rect bounds(left, top, right, bottom);
+    // TODO: Apply transformations and treat layers in screen coordinates
+    // mSnapshot->transform->mapRect(bounds);
+
     GLuint previousFbo = snapshot->previous.get() ? snapshot->previous->fbo : 0;
-    LayerSize size(right - left, bottom - top);
+    LayerSize size(bounds.getWidth(), bounds.getHeight());
 
     Layer* layer = mCaches.layerCache.get(size, previousFbo);
     if (!layer) {
@@ -267,24 +295,26 @@
 
     layer->mode = mode;
     layer->alpha = alpha / 255.0f;
-    layer->layer.set(left, top, right, bottom);
+    layer->layer.set(bounds);
 
     // Save the layer in the snapshot
     snapshot->flags |= Snapshot::kFlagIsLayer;
     snapshot->layer = layer;
     snapshot->fbo = layer->fbo;
-    snapshot->transform.loadTranslate(-left, -top, 0.0f);
-    snapshot->setClip(0.0f, 0.0f, right - left, bottom - top);
-    snapshot->viewport.set(0.0f, 0.0f, right - left, bottom - top);
-    snapshot->height = bottom - top;
+    // TODO: Temporary until real layer support is implemented
+    snapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
+    // TODO: Temporary until real layer support is implemented
+    snapshot->resetClip(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
+    snapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
+    snapshot->height = bounds.getHeight();
     snapshot->flags |= Snapshot::kFlagDirtyOrtho;
     snapshot->orthoMatrix.load(mOrthoMatrix);
 
     setScissorFromClip();
 
     // Change the ortho projection
-    glViewport(0, 0, right - left, bottom - top);
-    mOrthoMatrix.loadOrtho(0.0f, right - left, bottom - top, 0.0f, -1.0f, 1.0f);
+    glViewport(0, 0, bounds.getWidth(), bounds.getHeight());
+    mOrthoMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f);
 
     return true;
 }
@@ -300,8 +330,8 @@
     glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
 
     // Restore the clip from the previous snapshot
-    const Rect& clip = previous->clipRect;
-    glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight());
+    const Rect& clip = *previous->clipRect;
+    glScissor(clip.left, previous->height - clip.bottom, clip.getWidth(), clip.getHeight());
 
     Layer* layer = current->layer;
     const Rect& rect = layer->layer;
@@ -332,28 +362,28 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void OpenGLRenderer::translate(float dx, float dy) {
-    mSnapshot->transform.translate(dx, dy, 0.0f);
+    mSnapshot->transform->translate(dx, dy, 0.0f);
 }
 
 void OpenGLRenderer::rotate(float degrees) {
-    mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f);
+    mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f);
 }
 
 void OpenGLRenderer::scale(float sx, float sy) {
-    mSnapshot->transform.scale(sx, sy, 1.0f);
+    mSnapshot->transform->scale(sx, sy, 1.0f);
 }
 
 void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
-    mSnapshot->transform.load(*matrix);
+    mSnapshot->transform->load(*matrix);
 }
 
 void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
-    mSnapshot->transform.copyTo(*matrix);
+    mSnapshot->transform->copyTo(*matrix);
 }
 
 void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
     mat4 m(*matrix);
-    mSnapshot->transform.multiply(m);
+    mSnapshot->transform->multiply(m);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -361,7 +391,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void OpenGLRenderer::setScissorFromClip() {
-    const Rect& clip = mSnapshot->clipRect;
+    const Rect& clip = *mSnapshot->clipRect;
     glScissor(clip.left, mSnapshot->height - clip.bottom, clip.getWidth(), clip.getHeight());
 }
 
@@ -373,8 +403,8 @@
     if (mSnapshot->invisible) return true;
 
     Rect r(left, top, right, bottom);
-    mSnapshot->transform.mapRect(r);
-    return !mSnapshot->clipRect.intersects(r);
+    mSnapshot->transform->mapRect(r);
+    return !mSnapshot->clipRect->intersects(r);
 }
 
 bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
@@ -382,7 +412,7 @@
     if (clipped) {
         setScissorFromClip();
     }
-    return !mSnapshot->clipRect.isEmpty();
+    return !mSnapshot->clipRect->isEmpty();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -478,7 +508,7 @@
 
 void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
     if (mSnapshot->invisible) return;
-    const Rect& clip = mSnapshot->clipRect;
+    const Rect& clip = *mSnapshot->clipRect;
     drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
 }
 
@@ -515,7 +545,7 @@
     float scaleX = paint->getTextScaleX();
     bool applyScaleX = scaleX < 0.9999f || scaleX > 1.0001f;
     if (applyScaleX) {
-        save(0);
+        save(SkCanvas::kMatrix_SaveFlag);
         translate(x - (x * scaleX), 0.0f);
         scale(scaleX, 1.0f);
     }
@@ -724,7 +754,7 @@
      } else {
          mModelView.loadIdentity();
      }
-     mCaches.currentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);
+     mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
      glUniform4f(mCaches.currentProgram->color, r, g, b, a);
 
      textureUnit++;
@@ -829,7 +859,7 @@
     mModelView.loadTranslate(left, top, 0.0f);
     mModelView.scale(right - left, bottom - top, 1.0f);
     if (!ignoreTransform) {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);
+        mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
     } else {
         mat4 identity;
         mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity);
@@ -877,7 +907,7 @@
     mModelView.scale(right - left, bottom - top, 1.0f);
 
     useProgram(mCaches.programCache.get(description));
-    mCaches.currentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);
+    mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
 
     chooseBlending(blend || alpha < 1.0f, mode);
 
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 5748d57..0e90d20 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -58,6 +58,8 @@
 
     void setViewport(int width, int height);
     void prepare();
+    void acquireContext();
+    void releaseContext();
 
     int getSaveCount() const;
     int save(int flags);
@@ -106,9 +108,11 @@
      * The new snapshot is saved in mSnapshot and the previous snapshot
      * is linked from mSnapshot->previous.
      *
+     * @param flags The save flags; see SkCanvas for more information
+     *
      * @return The new save count. This value can be passed to #restoreToCount()
      */
-    int saveSnapshot();
+    int saveSnapshot(int flags);
 
     /**
      * Restores the current snapshot; mSnapshot becomes mSnapshot->previous.
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 7be0c340..6b22c2b 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -91,11 +91,11 @@
         set(r.left, r.top, r.right, r.bottom);
     }
 
-    float getWidth() const {
+    inline float getWidth() const {
         return right - left;
     }
 
-    float getHeight() const {
+    inline float getHeight() const {
         return bottom - top;
     }
 
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index c7a01b1..a5e0f78 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -167,12 +167,12 @@
         shaderMatrix.mapPoint(start.left, start.top);
         shaderMatrix.mapPoint(start.right, start.bottom);
     }
-    snapshot.transform.mapRect(start);
+    snapshot.transform->mapRect(start);
 
     const float gradientX = start.right - start.left;
     const float gradientY = start.bottom - start.top;
 
-    mat4 screenSpace(snapshot.transform);
+    mat4 screenSpace(*snapshot.transform);
     screenSpace.multiply(modelView);
 
     // Uniforms
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 97e7cae..da48243 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -22,6 +22,7 @@
 
 #include <utils/RefBase.h>
 
+#include <SkCanvas.h>
 #include <SkRegion.h>
 
 #include "Layer.h"
@@ -42,27 +43,40 @@
  */
 class Snapshot: public LightRefBase<Snapshot> {
 public:
-    Snapshot(): invisible(false), flags(0), previous(NULL), layer(NULL), fbo(0) { }
+    Snapshot(): invisible(false), flags(0), previous(NULL), layer(NULL), fbo(0) {
+        transform = &mTransformRoot;
+        clipRect = &mClipRectRoot;
+    }
 
     /**
-     * Copies the specified snapshot. Only the transform and clip rectangle
-     * are copied. The layer information is set to 0 and the transform is
-     * assumed to be dirty. The specified snapshot is stored as the previous
-     * snapshot.
+     * Copies the specified snapshot/ The specified snapshot is stored as
+     * the previous snapshot.
      */
-    Snapshot(const sp<Snapshot>& s):
+    Snapshot(const sp<Snapshot>& s, int saveFlags):
             height(s->height),
-            transform(s->transform),
-            clipRect(s->clipRect),
             invisible(s->invisible),
             flags(0),
             previous(s),
             layer(NULL),
             fbo(s->fbo),
             viewport(s->viewport) {
+        if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
+            mTransformRoot.load(*s->transform);
+            transform = &mTransformRoot;
+        } else {
+            transform = s->transform;
+        }
+
+        if (saveFlags & SkCanvas::kClip_SaveFlag) {
+            mClipRectRoot.set(*s->clipRect);
+            clipRect = &mClipRectRoot;
+        } else {
+            clipRect = s->clipRect;
+        }
+
         if ((s->flags & Snapshot::kFlagClipSet) &&
                 !(s->flags & Snapshot::kFlagDirtyLocalClip)) {
-            localClip.set(s->localClip);
+            mLocalClip.set(s->mLocalClip);
         } else {
             flags |= Snapshot::kFlagDirtyLocalClip;
         }
@@ -99,23 +113,23 @@
         bool clipped = false;
 
         Rect r(left, top, right, bottom);
-        transform.mapRect(r);
+        transform->mapRect(r);
 
         switch (op) {
             case SkRegion::kDifference_Op:
                 break;
             case SkRegion::kIntersect_Op:
-                clipped = clipRect.intersect(r);
+                clipped = clipRect->intersect(r);
                 break;
             case SkRegion::kUnion_Op:
-                clipped = clipRect.unionWith(r);
+                clipped = clipRect->unionWith(r);
                 break;
             case SkRegion::kXOR_Op:
                 break;
             case SkRegion::kReverseDifference_Op:
                 break;
             case SkRegion::kReplace_Op:
-                clipRect.set(r);
+                clipRect->set(r);
                 clipped = true;
                 break;
         }
@@ -131,21 +145,34 @@
      * Sets the current clip.
      */
     void setClip(float left, float top, float right, float bottom) {
-        clipRect.set(left, top, right, bottom);
+        clipRect->set(left, top, right, bottom);
         flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
     }
 
     const Rect& getLocalClip() {
         if (flags & Snapshot::kFlagDirtyLocalClip) {
             mat4 inverse;
-            inverse.loadInverse(transform);
+            inverse.loadInverse(*transform);
 
-            localClip.set(clipRect);
-            inverse.mapRect(localClip);
+            mLocalClip.set(*clipRect);
+            inverse.mapRect(mLocalClip);
 
             flags &= ~Snapshot::kFlagDirtyLocalClip;
         }
-        return localClip;
+        return mLocalClip;
+    }
+
+    // TODO: Temporary
+    void resetTransform(float x, float y, float z) {
+        transform = &mTransformRoot;
+        transform->loadTranslate(x, y, z);
+    }
+
+    // TODO: Temporary
+    void resetClip(float left, float top, float right, float bottom) {
+        clipRect = &mClipRectRoot;
+        clipRect->set(left, top, right, bottom);
+        flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
     }
 
     /**
@@ -154,18 +181,6 @@
     int height;
 
     /**
-     * Local transformation. Holds the current translation, scale and
-     * rotation values.
-     */
-    mat4 transform;
-
-    /**
-     * Current clip region. The clip is stored in canvas-space coordinates,
-     * (screen-space coordinates in the regular case.)
-     */
-    Rect clipRect;
-
-    /**
      * If true, the layer won't be rendered.
      */
     bool invisible;
@@ -196,8 +211,22 @@
      */
     mat4 orthoMatrix;
 
+    /**
+     * Local transformation. Holds the current translation, scale and
+     * rotation values.
+     */
+    mat4* transform;
+
+    /**
+     * Current clip region. The clip is stored in canvas-space coordinates,
+     * (screen-space coordinates in the regular case.)
+     */
+    Rect* clipRect;
+
 private:
-    Rect localClip;
+    mat4 mTransformRoot;
+    Rect mClipRectRoot;
+    Rect mLocalClip;
 
 }; // class Snapshot
 
diff --git a/libs/rs/java/Samples/res/raw/shaderf.glsl b/libs/rs/java/Samples/res/raw/shaderf.glsl
index 81452ab..fdcf481 100644
--- a/libs/rs/java/Samples/res/raw/shaderf.glsl
+++ b/libs/rs/java/Samples/res/raw/shaderf.glsl
@@ -7,12 +7,9 @@
 void main() {
    vec2 t0 = varTex0.xy;
    lowp vec4 col = texture2D(uni_Tex0, t0).rgba;
-   /*col = col * (light0_Diffuse * UNI_light0_DiffuseColor + light1_Diffuse * UNI_light1_DiffuseColor);
-   col += light0_Specular * UNI_light0_SpecularColor;
-   col += light1_Specular * UNI_light1_SpecularColor;*/
-   col = col * (light0_Diffuse + light1_Diffuse);
-   col += light0_Specular;
-   col += light1_Specular;
+   col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor + light1_Diffuse * UNI_light1_DiffuseColor);
+   col.xyz += light0_Specular * UNI_light0_SpecularColor;
+   col.xyz += light1_Specular * UNI_light1_SpecularColor;
    gl_FragColor = col;
 }
 
diff --git a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
index 165a6d7..4bcf7f5 100644
--- a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
+++ b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
@@ -73,6 +73,8 @@
 //What we are showing
 #pragma rs export_var(gDisplayMode)
 
+float gDt = 0;
+
 void init() {
 }
 
@@ -300,7 +302,7 @@
     rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
 
     // Aplly a rotation to our mesh
-    gTorusRotation += 50.0f * rsGetDt();
+    gTorusRotation += 50.0f * gDt;
     if(gTorusRotation > 360.0f) {
         gTorusRotation -= 360.0f;
     }
@@ -333,15 +335,15 @@
     float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f};
     float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f};
     float3 light0DiffCol = {0.9f, 0.7f, 0.7f};
-    float3 light0SpecCol = {0.9f, 0.8f, 0.8f};
-    float3 light1DiffCol = {0.7f, 0.7f, 0.9f};
-    float3 light1SpecCol = {0.8f, 0.8f, 0.9f};
+    float3 light0SpecCol = {0.9f, 0.6f, 0.6f};
+    float3 light1DiffCol = {0.5f, 0.5f, 0.9f};
+    float3 light1SpecCol = {0.5f, 0.5f, 0.9f};
 
-    gLight0Rotation += 150.0f * rsGetDt();
+    gLight0Rotation += 50.0f * gDt;
     if(gLight0Rotation > 360.0f) {
         gLight0Rotation -= 360.0f;
     }
-    gLight1Rotation -= 50.0f * rsGetDt();
+    gLight1Rotation -= 50.0f * gDt;
     if(gLight1Rotation > 360.0f) {
         gLight1Rotation -= 360.0f;
     }
@@ -359,7 +361,7 @@
     gVSConstants->light0_Posision.z = light0Pos.z;
     gVSConstants->light0_Diffuse = 1.0f;
     gVSConstants->light0_Specular = 0.5f;
-    gVSConstants->light0_CosinePower = 70.0f;
+    gVSConstants->light0_CosinePower = 40.0f;
     // Set light 1 properties
     gVSConstants->light1_Posision.x = light1Pos.x;
     gVSConstants->light1_Posision.y = light1Pos.y;
@@ -367,6 +369,7 @@
     gVSConstants->light1_Diffuse = 1.0f;
     gVSConstants->light1_Specular = 0.7f;
     gVSConstants->light1_CosinePower = 50.0f;
+    rsAllocationMarkDirty(rsGetAllocation(gVSConstants));
 
     // Update fragmetn shader constants
     // Set light 0 colors
@@ -375,6 +378,7 @@
     // Set light 1 colors
     gFSConstants->light1_DiffuseColor = light1DiffCol;
     gFSConstants->light1_SpecularColor = light1SpecCol;
+    rsAllocationMarkDirty(rsGetAllocation(gFSConstants));
 }
 
 void displayCustomShaderSamples() {
@@ -382,7 +386,7 @@
     // Update vertex shader constants
     // Load model matrix
     // Aplly a rotation to our mesh
-    gTorusRotation += 50.0f * rsGetDt();
+    gTorusRotation += 50.0f * gDt;
     if(gTorusRotation > 360.0f) {
         gTorusRotation -= 360.0f;
     }
@@ -390,6 +394,7 @@
     // Position our model on the screen
     rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
     rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+    rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
     setupCustomShaderLights();
 
     rsgBindProgramVertex(gProgVertexCustom);
@@ -416,6 +421,8 @@
 
 int root(int launchID) {
 
+    gDt = rsGetDt();
+
     rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
     rsgClearDepth(1.0f);
 
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 781dbea..ad162bb 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -184,6 +184,16 @@
 	togglePlay
 	}
 
+Allocation1DSubElementData {
+	param RsAllocation va
+	param uint32_t x
+	param const void *data
+	param uint32_t comp_offset
+	param uint32_t bytes
+	handcodeApi
+	togglePlay
+	}
+
 Allocation2DSubData {
 	param RsAllocation va
 	param uint32_t xoff
@@ -194,6 +204,15 @@
 	param uint32_t bytes
 	}
 
+Allocation2DSubElementData {
+	param RsAllocation va
+	param uint32_t x
+	param uint32_t y
+	param const void *data
+	param uint32_t element_offset
+	param uint32_t bytes
+	}
+
 AllocationRead {
 	param RsAllocation va
 	param void * data
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 7e44fea..60998c31 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -230,7 +230,7 @@
 }
 
 
-void Allocation::data(const void *data, uint32_t sizeBytes)
+void Allocation::data(Context *rsc, const void *data, uint32_t sizeBytes)
 {
     uint32_t size = mType->getSizeBytes();
     if (size != sizeBytes) {
@@ -253,7 +253,7 @@
     memcpy(data, mPtr, mType->getSizeBytes());
 }
 
-void Allocation::subData(uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
+void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
 {
     uint32_t eSize = mType->getElementSizeBytes();
     uint8_t * ptr = static_cast<uint8_t *>(mPtr);
@@ -276,7 +276,7 @@
     mUploadDefered = true;
 }
 
-void Allocation::subData(uint32_t xoff, uint32_t yoff,
+void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff,
              uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
 {
     uint32_t eSize = mType->getElementSizeBytes();
@@ -306,11 +306,93 @@
     mUploadDefered = true;
 }
 
-void Allocation::subData(uint32_t xoff, uint32_t yoff, uint32_t zoff,
+void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
              uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes)
 {
 }
 
+void Allocation::subElementData(Context *rsc, uint32_t x, const void *data,
+                                uint32_t cIdx, uint32_t sizeBytes)
+{
+    uint32_t eSize = mType->getElementSizeBytes();
+    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+    ptr += eSize * x;
+
+    if (cIdx >= mType->getElement()->getFieldCount()) {
+        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
+        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
+        return;
+    }
+
+    if (x >= mType->getDimX()) {
+        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
+        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
+        return;
+    }
+
+    const Element * e = mType->getElement()->getField(cIdx);
+    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
+
+    if (sizeBytes != e->getSizeBytes()) {
+        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
+        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
+        return;
+    }
+
+    if (e->getHasReferences()) {
+        e->incRefs(data);
+        e->decRefs(ptr);
+    }
+
+    memcpy(ptr, data, sizeBytes);
+    sendDirty();
+    mUploadDefered = true;
+}
+
+void Allocation::subElementData(Context *rsc, uint32_t x, uint32_t y,
+                                const void *data, uint32_t cIdx, uint32_t sizeBytes)
+{
+    uint32_t eSize = mType->getElementSizeBytes();
+    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+    ptr += eSize * (x + y * mType->getDimX());
+
+    if (x >= mType->getDimX()) {
+        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
+        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
+        return;
+    }
+
+    if (y >= mType->getDimY()) {
+        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
+        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
+        return;
+    }
+
+    if (cIdx >= mType->getElement()->getFieldCount()) {
+        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
+        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
+        return;
+    }
+
+    const Element * e = mType->getElement()->getField(cIdx);
+    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
+
+    if (sizeBytes != e->getSizeBytes()) {
+        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
+        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
+        return;
+    }
+
+    if (e->getHasReferences()) {
+        e->incRefs(data);
+        e->decRefs(ptr);
+    }
+
+    memcpy(ptr, data, sizeBytes);
+    sendDirty();
+    mUploadDefered = true;
+}
+
 void Allocation::addProgramToDirty(const Program *p)
 {
     mToDirtyList.push(p);
@@ -394,7 +476,7 @@
     alloc->setName(name.string(), name.size());
 
     // Read in all of our allocation data
-    alloc->data(stream->getPtr() + stream->getPos(), dataSize);
+    alloc->data(rsc, stream->getPtr() + stream->getPos(), dataSize);
     stream->reset(stream->getPos() + dataSize);
 
     return alloc;
@@ -662,16 +744,19 @@
     }
 
     ElementConverter_t cvt = pickConverter(dst, src);
-    cvt(texAlloc->getPtr(), data, w * h);
-
-    if (genMips) {
-        Adapter2D adapt(rsc, texAlloc);
-        Adapter2D adapt2(rsc, texAlloc);
-        for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
-            adapt.setLOD(lod);
-            adapt2.setLOD(lod + 1);
-            mip(adapt2, adapt);
+    if (cvt) {
+        cvt(texAlloc->getPtr(), data, w * h);
+        if (genMips) {
+            Adapter2D adapt(rsc, texAlloc);
+            Adapter2D adapt2(rsc, texAlloc);
+            for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
+                adapt.setLOD(lod);
+                adapt2.setLOD(lod + 1);
+                mip(adapt2, adapt);
+            }
         }
+    } else {
+        rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
     }
 
     return texAlloc;
@@ -708,19 +793,31 @@
 void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes)
 {
     Allocation *a = static_cast<Allocation *>(va);
-    a->data(data, sizeBytes);
+    a->data(rsc, data, sizeBytes);
 }
 
 void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
 {
     Allocation *a = static_cast<Allocation *>(va);
-    a->subData(xoff, count, data, sizeBytes);
+    a->subData(rsc, xoff, count, data, sizeBytes);
+}
+
+void rsi_Allocation2DSubElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, const void *data, uint32_t eoff, uint32_t sizeBytes)
+{
+    Allocation *a = static_cast<Allocation *>(va);
+    a->subElementData(rsc, x, y, data, eoff, sizeBytes);
+}
+
+void rsi_Allocation1DSubElementData(Context *rsc, RsAllocation va, uint32_t x, const void *data, uint32_t eoff, uint32_t sizeBytes)
+{
+    Allocation *a = static_cast<Allocation *>(va);
+    a->subElementData(rsc, x, data, eoff, sizeBytes);
 }
 
 void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
 {
     Allocation *a = static_cast<Allocation *>(va);
-    a->subData(xoff, yoff, w, h, data, sizeBytes);
+    a->subData(rsc, xoff, yoff, w, h, data, sizeBytes);
 }
 
 void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data)
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 177d5a4..b6b5d2f 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -56,13 +56,18 @@
     uint32_t getBufferObjectID() const {return mBufferID;}
 
 
-    void data(const void *data, uint32_t sizeBytes);
-    void subData(uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes);
-    void subData(uint32_t xoff, uint32_t yoff,
+    void data(Context *rsc, const void *data, uint32_t sizeBytes);
+    void subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes);
+    void subData(Context *rsc, uint32_t xoff, uint32_t yoff,
                  uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes);
-    void subData(uint32_t xoff, uint32_t yoff, uint32_t zoff,
+    void subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
                  uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes);
 
+    void subElementData(Context *rsc, uint32_t x,
+                        const void *data, uint32_t elementOff, uint32_t sizeBytes);
+    void subElementData(Context *rsc, uint32_t x, uint32_t y,
+                        const void *data, uint32_t elementOff, uint32_t sizeBytes);
+
     void read(void *data);
 
     void enableGLVertexBuffers() const;
@@ -84,9 +89,9 @@
     void incRefs(const void *ptr, size_t ct) const;
     void decRefs(const void *ptr, size_t ct) const;
 
-protected:
     void sendDirty() const;
 
+protected:
     ObjectBaseRef<const Type> mType;
     void * mPtr;
 
diff --git a/libs/rs/rsHandcode.h b/libs/rs/rsHandcode.h
index 353b73a..c02fd42 100644
--- a/libs/rs/rsHandcode.h
+++ b/libs/rs/rsHandcode.h
@@ -96,3 +96,26 @@
 
 }
 
+static inline void rsHCAPI_Allocation1DSubElementData (RsContext rsc, RsAllocation va, uint32_t x, const void * data, uint32_t comp_offset, uint32_t sizeBytes)
+{
+    ThreadIO *io = &((Context *)rsc)->mIO;
+    uint32_t size = sizeof(RS_CMD_Allocation1DSubElementData);
+    if (sizeBytes < DATA_SYNC_SIZE) {
+        size += (sizeBytes + 3) & ~3;
+    }
+    RS_CMD_Allocation1DSubElementData *cmd = static_cast<RS_CMD_Allocation1DSubElementData *>(io->mToCore.reserve(size));
+    cmd->va = va;
+    cmd->x = x;
+    cmd->data = data;
+    cmd->comp_offset = comp_offset;
+    cmd->bytes = sizeBytes;
+    if (sizeBytes < DATA_SYNC_SIZE) {
+        cmd->data = (void *)(cmd+1);
+        memcpy(cmd+1, data, sizeBytes);
+        io->mToCore.commit(RS_CMD_ID_Allocation1DSubElementData, size);
+    } else {
+        io->mToCore.commitSync(RS_CMD_ID_Allocation1DSubElementData, size);
+    }
+
+}
+
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index c4f8b2e..6041db8 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -241,7 +241,129 @@
     mUserShader.setTo(txt, len);
 }
 
+void Program::appendUserConstants() {
+    for (uint32_t ct=0; ct < mConstantCount; ct++) {
+        const Element *e = mConstantTypes[ct]->getElement();
+        for (uint32_t field=0; field < e->getFieldCount(); field++) {
+            const Element *f = e->getField(field);
+            const char *fn = e->getFieldName(field);
 
+            if (fn[0] == '#') {
+                continue;
+            }
+
+            // Cannot be complex
+            rsAssert(!f->getFieldCount());
+            if(f->getType() == RS_TYPE_MATRIX_4X4) {
+                mShader.append("uniform mat4 UNI_");
+            }
+            else if(f->getType() == RS_TYPE_MATRIX_3X3) {
+                mShader.append("uniform mat3 UNI_");
+            }
+            else if(f->getType() == RS_TYPE_MATRIX_2X2) {
+                mShader.append("uniform mat2 UNI_");
+            }
+            else {
+                switch(f->getComponent().getVectorSize()) {
+                case 1: mShader.append("uniform float UNI_"); break;
+                case 2: mShader.append("uniform vec2 UNI_"); break;
+                case 3: mShader.append("uniform vec3 UNI_"); break;
+                case 4: mShader.append("uniform vec4 UNI_"); break;
+                default:
+                    rsAssert(0);
+                }
+            }
+
+            mShader.append(fn);
+            mShader.append(";\n");
+        }
+    }
+}
+
+void Program::setupUserConstants(ShaderCache *sc, bool isFragment) {
+    uint32_t uidx = 1;
+    for (uint32_t ct=0; ct < mConstantCount; ct++) {
+        Allocation *alloc = mConstants[ct+1].get();
+        if (!alloc) {
+            continue;
+        }
+
+        const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
+        const Element *e = mConstantTypes[ct]->getElement();
+        for (uint32_t field=0; field < e->getFieldCount(); field++) {
+            const Element *f = e->getField(field);
+            const char *fieldName = e->getFieldName(field);
+            // If this field is padding, skip it
+            if(fieldName[0] == '#') {
+                continue;
+            }
+
+            uint32_t offset = e->getFieldOffsetBytes(field);
+            const float *fd = reinterpret_cast<const float *>(&data[offset]);
+
+            int32_t slot = -1;
+            if(!isFragment) {
+                slot = sc->vtxUniformSlot(uidx);
+            }
+            else {
+                slot = sc->fragUniformSlot(uidx);
+            }
+
+            //LOGE("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
+            if (slot >= 0) {
+                if(f->getType() == RS_TYPE_MATRIX_4X4) {
+                    glUniformMatrix4fv(slot, 1, GL_FALSE, fd);
+                }
+                else if(f->getType() == RS_TYPE_MATRIX_3X3) {
+                    glUniformMatrix3fv(slot, 1, GL_FALSE, fd);
+                }
+                else if(f->getType() == RS_TYPE_MATRIX_2X2) {
+                    glUniformMatrix2fv(slot, 1, GL_FALSE, fd);
+                }
+                else {
+                    switch(f->getComponent().getVectorSize()) {
+                    case 1:
+                        //LOGE("Uniform 1 = %f", fd[0]);
+                        glUniform1fv(slot, 1, fd);
+                        break;
+                    case 2:
+                        //LOGE("Uniform 2 = %f %f", fd[0], fd[1]);
+                        glUniform2fv(slot, 1, fd);
+                        break;
+                    case 3:
+                        //LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
+                        glUniform3fv(slot, 1, fd);
+                        break;
+                    case 4:
+                        //LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
+                        glUniform4fv(slot, 1, fd);
+                        break;
+                    default:
+                        rsAssert(0);
+                    }
+                }
+            }
+            uidx ++;
+        }
+    }
+}
+
+void Program::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix)
+{
+    rsAssert(e->getFieldCount());
+    for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
+        const Element *ce = e->getField(ct);
+        if (ce->getFieldCount()) {
+            initAddUserElement(ce, names, count, prefix);
+        }
+        else if(e->getFieldName(ct)[0] != '#') {
+            String8 tmp(prefix);
+            tmp.append(e->getFieldName(ct));
+            names[*count].setTo(tmp.string());
+            (*count)++;
+        }
+    }
+}
 
 namespace android {
 namespace renderscript {
diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h
index 86f85fb..ddc5e8a 100644
--- a/libs/rs/rsProgram.h
+++ b/libs/rs/rsProgram.h
@@ -72,6 +72,11 @@
     uint32_t mConstantCount;
     bool mIsValid;
 
+    // Applies to vertex and fragment shaders only
+    void appendUserConstants();
+    void setupUserConstants(ShaderCache *sc, bool isFragment);
+    void initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix);
+
     ObjectBaseRef<Allocation> mConstants[MAX_UNIFORMS];
 
     mutable bool mDirty;
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index a045043..83321d3 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -62,16 +62,7 @@
         mTextureEnableMask |= 2;
     }
 
-    mUniformCount = 0;
-    mUniformNames[mUniformCount++].setTo("uni_Tex0");
-    mUniformNames[mUniformCount++].setTo("uni_Tex1");
-
-    mConstantColorUniformIndex = -1;
-    //if (!mVaryingColor) {
-        mConstantColorUniformIndex = mUniformCount;
-        mUniformNames[mUniformCount++].setTo("uni_Color");
-    //}
-    createShader();
+    init(rsc);
 }
 
 ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
@@ -89,13 +80,9 @@
 
     LOGE("Custom FP");
 
-    mUniformCount = 2;
-    mUniformNames[0].setTo("uni_Tex0");
-    mUniformNames[1].setTo("uni_Tex1");
-
-    createShader();
-
     mTextureEnableMask = (1 << mTextureCount) -1;
+
+    init(rsc);
 }
 
 
@@ -134,6 +121,9 @@
         rsc->checkError("ProgramFragment::color setup");
     }
 
+    rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
+    setupUserConstants(sc, true);
+
     for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
         glActiveTexture(GL_TEXTURE0 + ct);
         if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
@@ -153,7 +143,7 @@
             rsc->checkError("ProgramFragment::setupGL2 tex env");
         }
 
-        glUniform1i(sc->fragUniformSlot(ct), ct);
+        glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
         rsc->checkError("ProgramFragment::setupGL2 uniforms");
     }
 
@@ -174,12 +164,12 @@
     mShader.append("uniform vec4 uni_Color;\n");
 
     if (mUserShader.length() > 1) {
+        appendUserConstants();
         for (uint32_t ct=0; ct < mTextureCount; ct++) {
             char buf[256];
             sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
             mShader.append(buf);
         }
-
         mShader.append(mUserShader);
     } else {
         uint32_t mask = mTextureEnableMask;
@@ -272,6 +262,22 @@
 
 void ProgramFragment::init(Context *rsc)
 {
+    mUniformCount = 0;
+    //if (!mVaryingColor) {
+        mConstantColorUniformIndex = mUniformCount;
+        mUniformNames[mUniformCount++].setTo("uni_Color");
+    //}
+
+    if (mUserShader.size() > 0) {
+        for (uint32_t ct=0; ct < mConstantCount; ct++) {
+            initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
+        }
+    }
+    mTextureUniformIndexStart = mUniformCount;
+    mUniformNames[mUniformCount++].setTo("uni_Tex0");
+    mUniformNames[mUniformCount++].setTo("uni_Tex1");
+
+    createShader();
 }
 
 void ProgramFragment::serialize(OStream *stream) const
@@ -304,7 +310,6 @@
     };
     ProgramFragment *pf = new ProgramFragment(rsc, tmp, 6);
     mDefault.set(pf);
-    pf->init(rsc);
 }
 
 void ProgramFragmentState::deinit(Context *rsc)
diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h
index 7c1598e..f08bb25 100644
--- a/libs/rs/rsProgramFragment.h
+++ b/libs/rs/rsProgramFragment.h
@@ -57,6 +57,7 @@
 
     float mConstantColor[4];
     int32_t mConstantColorUniformIndex;
+    int32_t mTextureUniformIndexStart;
 };
 
 class ProgramFragmentState
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 8468e26..68e3705 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -70,52 +70,7 @@
 
 void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state)
 {
-    if ((state->mLast.get() == this) && !mDirty) {
-        return;
-    }
-    state->mLast.set(this);
-
-    const float *f = static_cast<const float *>(mConstants[0]->getPtr());
-
-    glMatrixMode(GL_TEXTURE);
-    if (mTextureMatrixEnable) {
-        glLoadMatrixf(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]);
-    } else {
-        glLoadIdentity();
-    }
-
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-    if (mLightCount) {
-#ifndef ANDROID_RS_BUILD_FOR_HOST // GLES Only
-        int v = 0;
-        glEnable(GL_LIGHTING);
-
-        glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v);
-
-        for (uint32_t ct = 0; ct < mLightCount; ct++) {
-            const Light *l = mLights[ct].get();
-            glEnable(GL_LIGHT0 + ct);
-            l->setupGL(ct);
-        }
-        for (uint32_t ct = mLightCount; ct < MAX_LIGHTS; ct++) {
-            glDisable(GL_LIGHT0 + ct);
-        }
-#endif //ANDROID_RS_BUILD_FOR_HOST
-    } else {
-        glDisable(GL_LIGHTING);
-    }
-
-    if (!f) {
-        LOGE("Must bind constants to vertex program");
-    }
-
-    glMatrixMode(GL_PROJECTION);
-    glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
-    glMatrixMode(GL_MODELVIEW);
-    glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
-
-    mDirty = false;
+    assert(0);
 }
 
 void ProgramVertex::loadShader(Context *rsc) {
@@ -134,43 +89,7 @@
         mShader.append(mUniformNames[0]);
         mShader.append(";\n");
 
-        for (uint32_t ct=0; ct < mConstantCount; ct++) {
-            const Element *e = mConstantTypes[ct]->getElement();
-            for (uint32_t field=0; field < e->getFieldCount(); field++) {
-                const Element *f = e->getField(field);
-                const char *fn = e->getFieldName(field);
-
-                if (fn[0] == '#') {
-                    continue;
-                }
-
-                // Cannot be complex
-                rsAssert(!f->getFieldCount());
-                if(f->getType() == RS_TYPE_MATRIX_4X4) {
-                    mShader.append("uniform mat4 UNI_");
-                }
-                else if(f->getType() == RS_TYPE_MATRIX_3X3) {
-                    mShader.append("uniform mat3 UNI_");
-                }
-                else if(f->getType() == RS_TYPE_MATRIX_2X2) {
-                    mShader.append("uniform mat2 UNI_");
-                }
-                else {
-                    switch(f->getComponent().getVectorSize()) {
-                    case 1: mShader.append("uniform float UNI_"); break;
-                    case 2: mShader.append("uniform vec2 UNI_"); break;
-                    case 3: mShader.append("uniform vec3 UNI_"); break;
-                    case 4: mShader.append("uniform vec4 UNI_"); break;
-                    default:
-                        rsAssert(0);
-                    }
-                }
-
-                mShader.append(fn);
-                mShader.append(";\n");
-            }
-        }
-
+        appendUserConstants();
 
         for (uint32_t ct=0; ct < mInputCount; ct++) {
             const Element *e = mInputElements[ct].get();
@@ -248,65 +167,7 @@
     }
 
     rsc->checkError("ProgramVertex::setupGL2 begin uniforms");
-    uint32_t uidx = 1;
-    for (uint32_t ct=0; ct < mConstantCount; ct++) {
-        Allocation *alloc = mConstants[ct+1].get();
-        if (!alloc) {
-            continue;
-        }
-
-        const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
-        const Element *e = mConstantTypes[ct]->getElement();
-        for (uint32_t field=0; field < e->getFieldCount(); field++) {
-            const Element *f = e->getField(field);
-            uint32_t offset = e->getFieldOffsetBytes(field);
-            int32_t slot = sc->vtxUniformSlot(uidx);
-            const char *fieldName = e->getFieldName(field);
-
-            const float *fd = reinterpret_cast<const float *>(&data[offset]);
-
-            // If this field is padding, skip it
-            if(fieldName[0] == '#') {
-                continue;
-            }
-
-            //LOGE("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
-            if (slot >= 0) {
-                if(f->getType() == RS_TYPE_MATRIX_4X4) {
-                    glUniformMatrix4fv(slot, 1, GL_FALSE, fd);
-                }
-                else if(f->getType() == RS_TYPE_MATRIX_3X3) {
-                    glUniformMatrix3fv(slot, 1, GL_FALSE, fd);
-                }
-                else if(f->getType() == RS_TYPE_MATRIX_2X2) {
-                    glUniformMatrix2fv(slot, 1, GL_FALSE, fd);
-                }
-                else {
-                    switch(f->getComponent().getVectorSize()) {
-                    case 1:
-                        //LOGE("Uniform 1 = %f", fd[0]);
-                        glUniform1fv(slot, 1, fd);
-                        break;
-                    case 2:
-                        //LOGE("Uniform 2 = %f %f", fd[0], fd[1]);
-                        glUniform2fv(slot, 1, fd);
-                        break;
-                    case 3:
-                        //LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
-                        glUniform3fv(slot, 1, fd);
-                        break;
-                    case 4:
-                        //LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
-                        glUniform4fv(slot, 1, fd);
-                        break;
-                    default:
-                        rsAssert(0);
-                    }
-                }
-            }
-            uidx ++;
-        }
-    }
+    setupUserConstants(sc, false);
 
     state->mLast.set(this);
     rsc->checkError("ProgramVertex::setupGL2");
@@ -356,24 +217,6 @@
     mvp.vectorMultiply(v4out, v3in);
 }
 
-void ProgramVertex::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix)
-{
-    rsAssert(e->getFieldCount());
-    for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
-        const Element *ce = e->getField(ct);
-        if (ce->getFieldCount()) {
-            initAddUserElement(ce, names, count, prefix);
-        }
-        else if(e->getFieldName(ct)[0] != '#') {
-            String8 tmp(prefix);
-            tmp.append(e->getFieldName(ct));
-            names[*count].setTo(tmp.string());
-            (*count)++;
-        }
-    }
-}
-
-
 void ProgramVertex::init(Context *rsc)
 {
     mAttribCount = 0;
@@ -443,10 +286,10 @@
 {
     Matrix m;
     m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1);
-    mDefaultAlloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4);
+    mDefaultAlloc->subData(rsc, RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4);
 
     m.loadIdentity();
-    mDefaultAlloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4);
+    mDefaultAlloc->subData(rsc, RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4);
 }
 
 void ProgramVertexState::deinit(Context *rsc)
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
index a17c9ea..59fd3195 100644
--- a/libs/rs/rsProgramVertex.h
+++ b/libs/rs/rsProgramVertex.h
@@ -63,9 +63,6 @@
 
     // Hacks to create a program for now
     bool mTextureMatrixEnable;
-
-private:
-    void initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix);
 };
 
 
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 5a2b6ba..41828dc 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -18,7 +18,6 @@
 #include "rsScriptC.h"
 #include "rsMatrix.h"
 
-#include "acc/acc.h"
 #include "utils/Timers.h"
 
 #include <time.h>
@@ -357,6 +356,11 @@
     return (int)alloc;
 }
 
+void SC_allocationMarkDirty(RsAllocation a)
+{
+    Allocation *alloc = static_cast<Allocation *>(a);
+    alloc->sendDirty();
+}
 
 void SC_ForEach(RsScript vs,
                 RsAllocation vin,
@@ -423,6 +427,8 @@
     { "_Z13rsClearObjectP13rs_allocation", (void *)&SC_clearObject },
     { "_Z10rsIsObject13rs_allocation", (void *)&SC_isObject },
 
+    { "_Z21rsAllocationMarkDirty13rs_allocation", (void *)&SC_allocationMarkDirty },
+
 
     // Debug
     { "_Z7rsDebugPKcf", (void *)&SC_debugF },
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index a7877cdb..2f8f79a 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -18,7 +18,6 @@
 #include "rsScriptC.h"
 #include "rsMatrix.h"
 
-#include "acc/acc.h"
 #include "utils/Timers.h"
 
 #define GL_GLEXT_PROTOTYPES
diff --git a/libs/rs/scriptc/rs_math.rsh b/libs/rs/scriptc/rs_math.rsh
index c842ef1..5720b05 100644
--- a/libs/rs/scriptc/rs_math.rsh
+++ b/libs/rs/scriptc/rs_math.rsh
@@ -107,6 +107,10 @@
 extern rs_allocation __attribute__((overloadable))
     rsGetAllocation(const void *);
 
+// Mark the allocation dirty and notify those using it
+extern void __attribute__((overloadable))
+    rsAllocationMarkDirty(rs_allocation);
+
 // Return the dimensions associated with an allocation.
 extern uint32_t __attribute__((overloadable))
     rsAllocationGetDimX(rs_allocation);
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index 891661d..1d38b4b 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -139,11 +139,7 @@
 
 status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
         RawAbsoluteAxisInfo* outAxisInfo) const {
-    outAxisInfo->valid = false;
-    outAxisInfo->minValue = 0;
-    outAxisInfo->maxValue = 0;
-    outAxisInfo->flat = 0;
-    outAxisInfo->fuzz = 0;
+    outAxisInfo->clear();
 
     AutoMutex _l(mLock);
     device_t* device = getDevice(deviceId);
@@ -709,8 +705,7 @@
     LOGV("Getting absolute controllers...");
     if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0) {
         // Is this a new modern multi-touch driver?
-        if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)
-                && test_bit(ABS_MT_POSITION_X, abs_bitmask)
+        if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
                 && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
             device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT;
 
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 5fbaf09..4973cd8 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -210,21 +210,4 @@
     mMotionRanges.add(rangeType, range);
 }
 
-// class InputDeviceProxy
-
-InputDeviceProxy::InputDeviceProxy() {
-}
-
-InputDeviceProxy::~InputDeviceProxy() {
-}
-
-void InputDeviceProxy::getDeviceIds(Vector<int32_t>& outIds) {
-    // TODO use Binder
-}
-
-sp<InputDeviceProxy> InputDeviceProxy::getDevice(int32_t id) {
-    // TODO use Binder
-    return NULL;
-}
-
 } // namespace android
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index e35050c..886c785 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -405,12 +405,15 @@
         sampleCount += 1;
     }
     for (uint32_t i = 0; i < entry->pointerCount; i++) {
-        LOGD("  Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
+        LOGD("  Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
+                "touchMajor=%f, touchMinor=%d, toolMajor=%f, toolMinor=%f, "
+                "orientation=%f",
                 i, entry->pointerIds[i],
-                sample->pointerCoords[i].x,
-                sample->pointerCoords[i].y,
-                sample->pointerCoords[i].pressure,
-                sample->pointerCoords[i].size);
+                sample->pointerCoords[i].x, sample->pointerCoords[i].y,
+                sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
+                sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
+                sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
+                sample->pointerCoords[i].orientation);
     }
 
     // Keep in mind that due to batching, it is possible for the number of samples actually
@@ -1080,9 +1083,14 @@
             eventTime, deviceId, source, policyFlags, action, metaState, edgeFlags,
             xPrecision, yPrecision, downTime);
     for (uint32_t i = 0; i < pointerCount; i++) {
-        LOGD("  Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
+        LOGD("  Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
+                "touchMajor=%f, touchMinor=%d, toolMajor=%f, toolMinor=%f, "
+                "orientation=%f",
                 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
-                pointerCoords[i].pressure, pointerCoords[i].size);
+                pointerCoords[i].pressure, pointerCoords[i].size,
+                pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
+                pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
+                pointerCoords[i].orientation);
     }
 #endif
 
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 6f042ec..8ffb48d 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -26,11 +26,14 @@
 #include <ui/InputReader.h>
 
 #include <stddef.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <limits.h>
 #include <math.h>
 
+#define INDENT "  "
+
 namespace android {
 
 // --- Static Functions ---
@@ -52,6 +55,14 @@
     b = temp;
 }
 
+inline static float avg(float x, float y) {
+    return (x + y) / 2;
+}
+
+inline static float pythag(float x, float y) {
+    return sqrtf(x * x + y * y);
+}
+
 
 int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
     int32_t mask;
@@ -116,6 +127,64 @@
 }
 
 
+// --- InputDeviceCalibration ---
+
+InputDeviceCalibration::InputDeviceCalibration() {
+}
+
+void InputDeviceCalibration::clear() {
+    mProperties.clear();
+}
+
+void InputDeviceCalibration::addProperty(const String8& key, const String8& value) {
+    mProperties.add(key, value);
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, String8& outValue) const {
+    ssize_t index = mProperties.indexOfKey(key);
+    if (index < 0) {
+        return false;
+    }
+
+    outValue = mProperties.valueAt(index);
+    return true;
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, int32_t& outValue) const {
+    String8 stringValue;
+    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+        return false;
+    }
+
+    char* end;
+    int value = strtol(stringValue.string(), & end, 10);
+    if (*end != '\0') {
+        LOGW("Input device calibration key '%s' has invalid value '%s'.  Expected an integer.",
+                key.string(), stringValue.string());
+        return false;
+    }
+    outValue = value;
+    return true;
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, float& outValue) const {
+    String8 stringValue;
+    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+        return false;
+    }
+
+    char* end;
+    float value = strtof(stringValue.string(), & end);
+    if (*end != '\0') {
+        LOGW("Input device calibration key '%s' has invalid value '%s'.  Expected a float.",
+                key.string(), stringValue.string());
+        return false;
+    }
+    outValue = value;
+    return true;
+}
+
+
 // --- InputReader ---
 
 InputReader::InputReader(const sp<EventHubInterface>& eventHub,
@@ -167,9 +236,18 @@
     String8 name = mEventHub->getDeviceName(deviceId);
     uint32_t classes = mEventHub->getDeviceClasses(deviceId);
 
+    // Write a log message about the added device as a heading for subsequent log messages.
+    LOGI("Device added: id=0x%x, name=%s", deviceId, name.string());
+
     InputDevice* device = createDevice(deviceId, name, classes);
     device->configure();
 
+    if (device->isIgnored()) {
+        LOGI(INDENT "Sources: none (device is ignored)");
+    } else {
+        LOGI(INDENT "Sources: 0x%08x", device->getSources());
+    }
+
     bool added = false;
     { // acquire device registry writer lock
         RWLock::AutoWLock _wl(mDeviceRegistryLock);
@@ -187,14 +265,6 @@
         return;
     }
 
-    if (device->isIgnored()) {
-        LOGI("Device added: id=0x%x, name=%s (ignored non-input device)",
-                deviceId, name.string());
-    } else {
-        LOGI("Device added: id=0x%x, name=%s, sources=%08x",
-                deviceId, name.string(), device->getSources());
-    }
-
     handleConfigurationChanged(when);
 }
 
@@ -217,8 +287,7 @@
         return;
     }
 
-    device->reset();
-
+    // Write a log message about the removed device as a heading for subsequent log messages.
     if (device->isIgnored()) {
         LOGI("Device removed: id=0x%x, name=%s (ignored non-input device)",
                 device->getId(), device->getName().string());
@@ -227,6 +296,8 @@
                 device->getId(), device->getName().string(), device->getSources());
     }
 
+    device->reset();
+
     delete device;
 
     handleConfigurationChanged(when);
@@ -537,6 +608,10 @@
 }
 
 void InputDevice::configure() {
+    if (! isIgnored()) {
+        mContext->getPolicy()->getInputDeviceCalibration(mName, mCalibration);
+    }
+
     mSources = 0;
 
     size_t numMappers = mMappers.size();
@@ -1121,13 +1196,35 @@
 
         info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
         info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
-        info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, mLocked.orientedRanges.pressure);
-        info->addMotionRange(AINPUT_MOTION_RANGE_SIZE, mLocked.orientedRanges.size);
-        info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR, mLocked.orientedRanges.touchMajor);
-        info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR, mLocked.orientedRanges.touchMinor);
-        info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR, mLocked.orientedRanges.toolMajor);
-        info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR, mLocked.orientedRanges.toolMinor);
-        info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION, mLocked.orientedRanges.orientation);
+
+        if (mLocked.orientedRanges.havePressure) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE,
+                    mLocked.orientedRanges.pressure);
+        }
+
+        if (mLocked.orientedRanges.haveSize) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_SIZE,
+                    mLocked.orientedRanges.size);
+        }
+
+        if (mLocked.orientedRanges.haveTouchArea) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR,
+                    mLocked.orientedRanges.touchMajor);
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR,
+                    mLocked.orientedRanges.touchMinor);
+        }
+
+        if (mLocked.orientedRanges.haveToolArea) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR,
+                    mLocked.orientedRanges.toolMajor);
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR,
+                    mLocked.orientedRanges.toolMinor);
+        }
+
+        if (mLocked.orientedRanges.haveOrientation) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION,
+                    mLocked.orientedRanges.orientation);
+        }
     } // release lock
 }
 
@@ -1144,77 +1241,72 @@
     mJumpyTouchFilter.jumpyPointsDropped = 0;
 
     mLocked.currentVirtualKey.down = false;
+
+    mLocked.orientedRanges.havePressure = false;
+    mLocked.orientedRanges.haveSize = false;
+    mLocked.orientedRanges.haveTouchArea = false;
+    mLocked.orientedRanges.haveToolArea = false;
+    mLocked.orientedRanges.haveOrientation = false;
+}
+
+static void logAxisInfo(RawAbsoluteAxisInfo axis, const char* name) {
+    if (axis.valid) {
+        LOGI(INDENT "Raw %s axis: min=%d, max=%d, flat=%d, fuzz=%d",
+                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz);
+    } else {
+        LOGI(INDENT "Raw %s axis: unknown range", name);
+    }
 }
 
 void TouchInputMapper::configure() {
     InputMapper::configure();
 
     // Configure basic parameters.
-    mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
-    mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
-    mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
+    configureParameters();
 
     // Configure absolute axis information.
-    configureAxes();
+    configureRawAxes();
+    logRawAxes();
+
+    // Prepare input device calibration.
+    parseCalibration();
+    resolveCalibration();
+    logCalibration();
 
     { // acquire lock
         AutoMutex _l(mLock);
 
-        // Configure pressure factors.
-        if (mAxes.pressure.valid) {
-            mLocked.pressureOrigin = mAxes.pressure.minValue;
-            mLocked.pressureScale = 1.0f / mAxes.pressure.getRange();
-        } else {
-            mLocked.pressureOrigin = 0;
-            mLocked.pressureScale = 1.0f;
-        }
-
-        mLocked.orientedRanges.pressure.min = 0.0f;
-        mLocked.orientedRanges.pressure.max = 1.0f;
-        mLocked.orientedRanges.pressure.flat = 0.0f;
-        mLocked.orientedRanges.pressure.fuzz = mLocked.pressureScale;
-
-        // Configure size factors.
-        if (mAxes.size.valid) {
-            mLocked.sizeOrigin = mAxes.size.minValue;
-            mLocked.sizeScale = 1.0f / mAxes.size.getRange();
-        } else {
-            mLocked.sizeOrigin = 0;
-            mLocked.sizeScale = 1.0f;
-        }
-
-        mLocked.orientedRanges.size.min = 0.0f;
-        mLocked.orientedRanges.size.max = 1.0f;
-        mLocked.orientedRanges.size.flat = 0.0f;
-        mLocked.orientedRanges.size.fuzz = mLocked.sizeScale;
-
-        // Configure orientation factors.
-        if (mAxes.orientation.valid && mAxes.orientation.maxValue > 0) {
-            mLocked.orientationScale = float(M_PI_2) / mAxes.orientation.maxValue;
-        } else {
-            mLocked.orientationScale = 0.0f;
-        }
-
-        mLocked.orientedRanges.orientation.min = - M_PI_2;
-        mLocked.orientedRanges.orientation.max = M_PI_2;
-        mLocked.orientedRanges.orientation.flat = 0;
-        mLocked.orientedRanges.orientation.fuzz = mLocked.orientationScale;
-
-        // Configure surface dimensions and orientation.
+         // Configure surface dimensions and orientation.
         configureSurfaceLocked();
     } // release lock
 }
 
-void TouchInputMapper::configureAxes() {
-    mAxes.x.valid = false;
-    mAxes.y.valid = false;
-    mAxes.pressure.valid = false;
-    mAxes.size.valid = false;
-    mAxes.touchMajor.valid = false;
-    mAxes.touchMinor.valid = false;
-    mAxes.toolMajor.valid = false;
-    mAxes.toolMinor.valid = false;
-    mAxes.orientation.valid = false;
+void TouchInputMapper::configureParameters() {
+    mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
+    mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
+    mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
+}
+
+void TouchInputMapper::configureRawAxes() {
+    mRawAxes.x.clear();
+    mRawAxes.y.clear();
+    mRawAxes.pressure.clear();
+    mRawAxes.touchMajor.clear();
+    mRawAxes.touchMinor.clear();
+    mRawAxes.toolMajor.clear();
+    mRawAxes.toolMinor.clear();
+    mRawAxes.orientation.clear();
+}
+
+void TouchInputMapper::logRawAxes() {
+    logAxisInfo(mRawAxes.x, "x");
+    logAxisInfo(mRawAxes.y, "y");
+    logAxisInfo(mRawAxes.pressure, "pressure");
+    logAxisInfo(mRawAxes.touchMajor, "touchMajor");
+    logAxisInfo(mRawAxes.touchMinor, "touchMinor");
+    logAxisInfo(mRawAxes.toolMajor, "toolMajor");
+    logAxisInfo(mRawAxes.toolMinor, "toolMinor");
+    logAxisInfo(mRawAxes.orientation, "orientation");
 }
 
 bool TouchInputMapper::configureSurfaceLocked() {
@@ -1228,8 +1320,8 @@
         }
     } else {
         orientation = InputReaderPolicyInterface::ROTATION_0;
-        width = mAxes.x.getRange();
-        height = mAxes.y.getRange();
+        width = mRawAxes.x.getRange();
+        height = mRawAxes.y.getRange();
     }
 
     bool orientationChanged = mLocked.surfaceOrientation != orientation;
@@ -1239,24 +1331,24 @@
 
     bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
     if (sizeChanged) {
+        LOGI("Device configured: id=0x%x, name=%s (display size was changed)",
+                getDeviceId(), getDeviceName().string());
+
         mLocked.surfaceWidth = width;
         mLocked.surfaceHeight = height;
 
-        // Compute size-dependent translation and scaling factors and place virtual keys.
-        if (mAxes.x.valid && mAxes.y.valid) {
-            mLocked.xOrigin = mAxes.x.minValue;
-            mLocked.yOrigin = mAxes.y.minValue;
-
-            LOGI("Device configured: id=0x%x, name=%s (display size was changed)",
-                    getDeviceId(), getDeviceName().string());
-
-            mLocked.xScale = float(width) / mAxes.x.getRange();
-            mLocked.yScale = float(height) / mAxes.y.getRange();
+        // Configure X and Y factors.
+        if (mRawAxes.x.valid && mRawAxes.y.valid) {
+            mLocked.xOrigin = mRawAxes.x.minValue;
+            mLocked.yOrigin = mRawAxes.y.minValue;
+            mLocked.xScale = float(width) / mRawAxes.x.getRange();
+            mLocked.yScale = float(height) / mRawAxes.y.getRange();
             mLocked.xPrecision = 1.0f / mLocked.xScale;
             mLocked.yPrecision = 1.0f / mLocked.yScale;
 
             configureVirtualKeysLocked();
         } else {
+            LOGW(INDENT "Touch device did not report support for X or Y axis!");
             mLocked.xOrigin = 0;
             mLocked.yOrigin = 0;
             mLocked.xScale = 1.0f;
@@ -1265,22 +1357,112 @@
             mLocked.yPrecision = 1.0f;
         }
 
-        // Configure touch and tool area ranges.
-        float diagonal = sqrt(float(width * width + height * height));
-        float diagonalFuzz = sqrt(mLocked.xScale * mLocked.xScale
-                + mLocked.yScale * mLocked.yScale);
+        // Scale factor for terms that are not oriented in a particular axis.
+        // If the pixels are square then xScale == yScale otherwise we fake it
+        // by choosing an average.
+        mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale);
 
-        InputDeviceInfo::MotionRange area;
-        area.min = 0.0f;
-        area.max = diagonal;
-        area.flat = 0.0f;
-        area.fuzz = diagonalFuzz;
+        // Size of diagonal axis.
+        float diagonalSize = pythag(width, height);
 
-        mLocked.orientedRanges.touchMajor = area;
-        mLocked.orientedRanges.touchMinor = area;
+        // TouchMajor and TouchMinor factors.
+        if (mCalibration.touchAreaCalibration != Calibration::TOUCH_AREA_CALIBRATION_NONE) {
+            mLocked.orientedRanges.haveTouchArea = true;
+            mLocked.orientedRanges.touchMajor.min = 0;
+            mLocked.orientedRanges.touchMajor.max = diagonalSize;
+            mLocked.orientedRanges.touchMajor.flat = 0;
+            mLocked.orientedRanges.touchMajor.fuzz = 0;
+            mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
+        }
 
-        mLocked.orientedRanges.toolMajor = area;
-        mLocked.orientedRanges.toolMinor = area;
+        // ToolMajor and ToolMinor factors.
+        if (mCalibration.toolAreaCalibration != Calibration::TOOL_AREA_CALIBRATION_NONE) {
+            mLocked.toolAreaLinearScale = 0;
+            mLocked.toolAreaLinearBias = 0;
+            if (mCalibration.toolAreaCalibration == Calibration::TOOL_AREA_CALIBRATION_LINEAR) {
+                if (mCalibration.haveToolAreaLinearScale) {
+                    mLocked.toolAreaLinearScale = mCalibration.toolAreaLinearScale;
+                } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
+                    mLocked.toolAreaLinearScale = float(min(width, height))
+                            / mRawAxes.toolMajor.maxValue;
+                }
+
+                if (mCalibration.haveToolAreaLinearBias) {
+                    mLocked.toolAreaLinearBias = mCalibration.toolAreaLinearBias;
+                }
+            }
+
+            mLocked.orientedRanges.haveToolArea = true;
+            mLocked.orientedRanges.toolMajor.min = 0;
+            mLocked.orientedRanges.toolMajor.max = diagonalSize;
+            mLocked.orientedRanges.toolMajor.flat = 0;
+            mLocked.orientedRanges.toolMajor.fuzz = 0;
+            mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
+        }
+
+        // Pressure factors.
+        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) {
+            RawAbsoluteAxisInfo rawPressureAxis;
+            switch (mCalibration.pressureSource) {
+            case Calibration::PRESSURE_SOURCE_PRESSURE:
+                rawPressureAxis = mRawAxes.pressure;
+                break;
+            case Calibration::PRESSURE_SOURCE_TOUCH:
+                rawPressureAxis = mRawAxes.touchMajor;
+                break;
+            default:
+                rawPressureAxis.clear();
+            }
+
+            mLocked.pressureScale = 0;
+            if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
+                    || mCalibration.pressureCalibration
+                            == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
+                if (mCalibration.havePressureScale) {
+                    mLocked.pressureScale = mCalibration.pressureScale;
+                } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) {
+                    mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue;
+                }
+            }
+
+            mLocked.orientedRanges.havePressure = true;
+            mLocked.orientedRanges.pressure.min = 0;
+            mLocked.orientedRanges.pressure.max = 1.0;
+            mLocked.orientedRanges.pressure.flat = 0;
+            mLocked.orientedRanges.pressure.fuzz = 0;
+        }
+
+        // Size factors.
+        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
+            mLocked.sizeScale = 0;
+            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) {
+                if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
+                    mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue;
+                }
+            }
+
+            mLocked.orientedRanges.haveSize = true;
+            mLocked.orientedRanges.size.min = 0;
+            mLocked.orientedRanges.size.max = 1.0;
+            mLocked.orientedRanges.size.flat = 0;
+            mLocked.orientedRanges.size.fuzz = 0;
+        }
+
+        // Orientation
+        if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
+            mLocked.orientationScale = 0;
+            if (mCalibration.orientationCalibration
+                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
+                if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) {
+                    mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue;
+                }
+            }
+
+            mLocked.orientedRanges.orientation.min = - M_PI_2;
+            mLocked.orientedRanges.orientation.max = M_PI_2;
+            mLocked.orientedRanges.orientation.flat = 0;
+            mLocked.orientedRanges.orientation.fuzz = 0;
+        }
     }
 
     if (orientationChanged || sizeChanged) {
@@ -1322,10 +1504,10 @@
 }
 
 void TouchInputMapper::configureVirtualKeysLocked() {
-    assert(mAxes.x.valid && mAxes.y.valid);
+    assert(mRawAxes.x.valid && mRawAxes.y.valid);
 
     // Note: getVirtualKeyDefinitions is non-reentrant so we can continue holding the lock.
-    Vector<InputReaderPolicyInterface::VirtualKeyDefinition> virtualKeyDefinitions;
+    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
     getPolicy()->getVirtualKeyDefinitions(getDeviceName(), virtualKeyDefinitions);
 
     mLocked.virtualKeys.clear();
@@ -1336,13 +1518,13 @@
 
     mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
 
-    int32_t touchScreenLeft = mAxes.x.minValue;
-    int32_t touchScreenTop = mAxes.y.minValue;
-    int32_t touchScreenWidth = mAxes.x.getRange();
-    int32_t touchScreenHeight = mAxes.y.getRange();
+    int32_t touchScreenLeft = mRawAxes.x.minValue;
+    int32_t touchScreenTop = mRawAxes.y.minValue;
+    int32_t touchScreenWidth = mRawAxes.x.getRange();
+    int32_t touchScreenHeight = mRawAxes.y.getRange();
 
     for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
-        const InputReaderPolicyInterface::VirtualKeyDefinition& virtualKeyDefinition =
+        const VirtualKeyDefinition& virtualKeyDefinition =
                 virtualKeyDefinitions[i];
 
         mLocked.virtualKeys.add();
@@ -1353,7 +1535,8 @@
         uint32_t flags;
         if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
                 & keyCode, & flags)) {
-            LOGW("  VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
+            LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
+                    virtualKey.scanCode);
             mLocked.virtualKeys.pop(); // drop the key
             continue;
         }
@@ -1374,12 +1557,316 @@
         virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
                 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
 
-        LOGI("  VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
+        LOGI(INDENT "VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
                 virtualKey.scanCode, virtualKey.keyCode,
                 virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
     }
 }
 
+void TouchInputMapper::parseCalibration() {
+    const InputDeviceCalibration& in = getDevice()->getCalibration();
+    Calibration& out = mCalibration;
+
+    // Touch Area
+    out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_DEFAULT;
+    String8 touchAreaCalibrationString;
+    if (in.tryGetProperty(String8("touch.touchArea.calibration"), touchAreaCalibrationString)) {
+        if (touchAreaCalibrationString == "none") {
+            out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_NONE;
+        } else if (touchAreaCalibrationString == "geometric") {
+            out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC;
+        } else if (touchAreaCalibrationString == "pressure") {
+            out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_PRESSURE;
+        } else if (touchAreaCalibrationString != "default") {
+            LOGW("Invalid value for touch.touchArea.calibration: '%s'",
+                    touchAreaCalibrationString.string());
+        }
+    }
+
+    // Tool Area
+    out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_DEFAULT;
+    String8 toolAreaCalibrationString;
+    if (in.tryGetProperty(String8("tool.toolArea.calibration"), toolAreaCalibrationString)) {
+        if (toolAreaCalibrationString == "none") {
+            out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_NONE;
+        } else if (toolAreaCalibrationString == "geometric") {
+            out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC;
+        } else if (toolAreaCalibrationString == "linear") {
+            out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_LINEAR;
+        } else if (toolAreaCalibrationString != "default") {
+            LOGW("Invalid value for tool.toolArea.calibration: '%s'",
+                    toolAreaCalibrationString.string());
+        }
+    }
+
+    out.haveToolAreaLinearScale = in.tryGetProperty(String8("touch.toolArea.linearScale"),
+            out.toolAreaLinearScale);
+    out.haveToolAreaLinearBias = in.tryGetProperty(String8("touch.toolArea.linearBias"),
+            out.toolAreaLinearBias);
+    out.haveToolAreaIsSummed = in.tryGetProperty(String8("touch.toolArea.isSummed"),
+            out.toolAreaIsSummed);
+
+    // Pressure
+    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
+    String8 pressureCalibrationString;
+    if (in.tryGetProperty(String8("tool.pressure.calibration"), pressureCalibrationString)) {
+        if (pressureCalibrationString == "none") {
+            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
+        } else if (pressureCalibrationString == "physical") {
+            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
+        } else if (pressureCalibrationString == "amplitude") {
+            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
+        } else if (pressureCalibrationString != "default") {
+            LOGW("Invalid value for tool.pressure.calibration: '%s'",
+                    pressureCalibrationString.string());
+        }
+    }
+
+    out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT;
+    String8 pressureSourceString;
+    if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) {
+        if (pressureSourceString == "pressure") {
+            out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
+        } else if (pressureSourceString == "touch") {
+            out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
+        } else if (pressureSourceString != "default") {
+            LOGW("Invalid value for touch.pressure.source: '%s'",
+                    pressureSourceString.string());
+        }
+    }
+
+    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
+            out.pressureScale);
+
+    // Size
+    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
+    String8 sizeCalibrationString;
+    if (in.tryGetProperty(String8("tool.size.calibration"), sizeCalibrationString)) {
+        if (sizeCalibrationString == "none") {
+            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
+        } else if (sizeCalibrationString == "normalized") {
+            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
+        } else if (sizeCalibrationString != "default") {
+            LOGW("Invalid value for tool.size.calibration: '%s'",
+                    sizeCalibrationString.string());
+        }
+    }
+
+    // Orientation
+    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
+    String8 orientationCalibrationString;
+    if (in.tryGetProperty(String8("tool.orientation.calibration"), orientationCalibrationString)) {
+        if (orientationCalibrationString == "none") {
+            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
+        } else if (orientationCalibrationString == "interpolated") {
+            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
+        } else if (orientationCalibrationString != "default") {
+            LOGW("Invalid value for tool.orientation.calibration: '%s'",
+                    orientationCalibrationString.string());
+        }
+    }
+}
+
+void TouchInputMapper::resolveCalibration() {
+    // Pressure
+    switch (mCalibration.pressureSource) {
+    case Calibration::PRESSURE_SOURCE_DEFAULT:
+        if (mRawAxes.pressure.valid) {
+            mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
+        } else if (mRawAxes.touchMajor.valid) {
+            mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
+        }
+        break;
+
+    case Calibration::PRESSURE_SOURCE_PRESSURE:
+        if (! mRawAxes.pressure.valid) {
+            LOGW("Calibration property touch.pressure.source is 'pressure' but "
+                    "the pressure axis is not available.");
+        }
+        break;
+
+    case Calibration::PRESSURE_SOURCE_TOUCH:
+        if (! mRawAxes.touchMajor.valid) {
+            LOGW("Calibration property touch.pressure.source is 'touch' but "
+                    "the touchMajor axis is not available.");
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    switch (mCalibration.pressureCalibration) {
+    case Calibration::PRESSURE_CALIBRATION_DEFAULT:
+        if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) {
+            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
+        } else {
+            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Tool Area
+    switch (mCalibration.toolAreaCalibration) {
+    case Calibration::TOOL_AREA_CALIBRATION_DEFAULT:
+        if (mRawAxes.toolMajor.valid) {
+            mCalibration.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_LINEAR;
+        } else {
+            mCalibration.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Touch Area
+    switch (mCalibration.touchAreaCalibration) {
+    case Calibration::TOUCH_AREA_CALIBRATION_DEFAULT:
+        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE
+                && mCalibration.toolAreaCalibration != Calibration::TOOL_AREA_CALIBRATION_NONE) {
+            mCalibration.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_PRESSURE;
+        } else {
+            mCalibration.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Size
+    switch (mCalibration.sizeCalibration) {
+    case Calibration::SIZE_CALIBRATION_DEFAULT:
+        if (mRawAxes.toolMajor.valid) {
+            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
+        } else {
+            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Orientation
+    switch (mCalibration.orientationCalibration) {
+    case Calibration::ORIENTATION_CALIBRATION_DEFAULT:
+        if (mRawAxes.orientation.valid) {
+            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
+        } else {
+            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
+void TouchInputMapper::logCalibration() {
+    // Touch Area
+    switch (mCalibration.touchAreaCalibration) {
+    case Calibration::TOUCH_AREA_CALIBRATION_NONE:
+        LOGI(INDENT "  touch.touchArea.calibration: none");
+        break;
+    case Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC:
+        LOGI(INDENT "  touch.touchArea.calibration: geometric");
+        break;
+    case Calibration::TOUCH_AREA_CALIBRATION_PRESSURE:
+        LOGI(INDENT "  touch.touchArea.calibration: pressure");
+        break;
+    default:
+        assert(false);
+    }
+
+    // Tool Area
+    switch (mCalibration.toolAreaCalibration) {
+    case Calibration::TOOL_AREA_CALIBRATION_NONE:
+        LOGI(INDENT "  touch.toolArea.calibration: none");
+        break;
+    case Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC:
+        LOGI(INDENT "  touch.toolArea.calibration: geometric");
+        break;
+    case Calibration::TOOL_AREA_CALIBRATION_LINEAR:
+        LOGI(INDENT "  touch.toolArea.calibration: linear");
+        break;
+    default:
+        assert(false);
+    }
+
+    if (mCalibration.haveToolAreaLinearScale) {
+        LOGI(INDENT "  touch.toolArea.linearScale: %f", mCalibration.toolAreaLinearScale);
+    }
+
+    if (mCalibration.haveToolAreaLinearBias) {
+        LOGI(INDENT "  touch.toolArea.linearBias: %f", mCalibration.toolAreaLinearBias);
+    }
+
+    if (mCalibration.haveToolAreaIsSummed) {
+        LOGI(INDENT "  touch.toolArea.isSummed: %d", mCalibration.toolAreaIsSummed);
+    }
+
+    // Pressure
+    switch (mCalibration.pressureCalibration) {
+    case Calibration::PRESSURE_CALIBRATION_NONE:
+        LOGI(INDENT "  touch.pressure.calibration: none");
+        break;
+    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
+        LOGI(INDENT "  touch.pressure.calibration: physical");
+        break;
+    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
+        LOGI(INDENT "  touch.pressure.calibration: amplitude");
+        break;
+    default:
+        assert(false);
+    }
+
+    switch (mCalibration.pressureSource) {
+    case Calibration::PRESSURE_SOURCE_PRESSURE:
+        LOGI(INDENT "  touch.pressure.source: pressure");
+        break;
+    case Calibration::PRESSURE_SOURCE_TOUCH:
+        LOGI(INDENT "  touch.pressure.source: touch");
+        break;
+    case Calibration::PRESSURE_SOURCE_DEFAULT:
+        break;
+    default:
+        assert(false);
+    }
+
+    if (mCalibration.havePressureScale) {
+        LOGI(INDENT "  touch.pressure.scale: %f", mCalibration.pressureScale);
+    }
+
+    // Size
+    switch (mCalibration.sizeCalibration) {
+    case Calibration::SIZE_CALIBRATION_NONE:
+        LOGI(INDENT "  touch.size.calibration: none");
+        break;
+    case Calibration::SIZE_CALIBRATION_NORMALIZED:
+        LOGI(INDENT "  touch.size.calibration: normalized");
+        break;
+    default:
+        assert(false);
+    }
+
+    // Orientation
+    switch (mCalibration.orientationCalibration) {
+    case Calibration::ORIENTATION_CALIBRATION_NONE:
+        LOGI(INDENT "  touch.orientation.calibration: none");
+        break;
+    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
+        LOGI(INDENT "  touch.orientation.calibration: interpolated");
+        break;
+    default:
+        assert(false);
+    }
+}
+
 void TouchInputMapper::reset() {
     // Synthesize touch up event if touch is currently down.
     // This will also take care of finishing virtual key processing if needed.
@@ -1584,13 +2071,14 @@
         // The dispatcher takes care of batching moves so we don't have to deal with that here.
         int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE;
         dispatchTouch(when, policyFlags, & mCurrentTouch,
-                currentIdBits, -1, motionEventAction);
+                currentIdBits, -1, currentPointerCount, motionEventAction);
     } else {
         // There may be pointers going up and pointers going down at the same time when pointer
         // ids are reported by the device driver.
         BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value);
         BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value);
         BitSet32 activeIdBits(lastIdBits.value);
+        uint32_t pointerCount = lastPointerCount;
 
         while (! upIdBits.isEmpty()) {
             uint32_t upId = upIdBits.firstMarkedBit();
@@ -1606,7 +2094,8 @@
             }
 
             dispatchTouch(when, policyFlags, & mLastTouch,
-                    oldActiveIdBits, upId, motionEventAction);
+                    oldActiveIdBits, upId, pointerCount, motionEventAction);
+            pointerCount -= 1;
         }
 
         while (! downIdBits.isEmpty()) {
@@ -1623,16 +2112,16 @@
                 motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN;
             }
 
+            pointerCount += 1;
             dispatchTouch(when, policyFlags, & mCurrentTouch,
-                    activeIdBits, downId, motionEventAction);
+                    activeIdBits, downId, pointerCount, motionEventAction);
         }
     }
 }
 
 void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
-        TouchData* touch, BitSet32 idBits, uint32_t changedId,
+        TouchData* touch, BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
         int32_t motionEventAction) {
-    uint32_t pointerCount = 0;
     int32_t pointerIds[MAX_POINTERS];
     PointerCoords pointerCoords[MAX_POINTERS];
     int32_t motionEventEdgeFlags = 0;
@@ -1643,36 +2132,130 @@
 
         // Walk through the the active pointers and map touch screen coordinates (TouchData) into
         // display coordinates (PointerCoords) and adjust for display orientation.
-        while (! idBits.isEmpty()) {
+        for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) {
             uint32_t id = idBits.firstMarkedBit();
             idBits.clearBit(id);
-            uint32_t index = touch->idToIndex[id];
+            uint32_t inIndex = touch->idToIndex[id];
 
-            float x = float(touch->pointers[index].x - mLocked.xOrigin) * mLocked.xScale;
-            float y = float(touch->pointers[index].y - mLocked.yOrigin) * mLocked.yScale;
-            float pressure = float(touch->pointers[index].pressure - mLocked.pressureOrigin)
-                    * mLocked.pressureScale;
-            float size = float(touch->pointers[index].size - mLocked.sizeOrigin)
-                    * mLocked.sizeScale;
+            const PointerData& in = touch->pointers[inIndex];
 
-            float orientation = float(touch->pointers[index].orientation)
-                    * mLocked.orientationScale;
+            // X and Y
+            float x = float(in.x - mLocked.xOrigin) * mLocked.xScale;
+            float y = float(in.y - mLocked.yOrigin) * mLocked.yScale;
 
-            float touchMajor, touchMinor, toolMajor, toolMinor;
-            if (abs(orientation) <= M_PI_4) {
-                // Nominally vertical orientation: scale major axis by Y, and scale minor axis by X.
-                touchMajor = float(touch->pointers[index].touchMajor) * mLocked.yScale;
-                touchMinor = float(touch->pointers[index].touchMinor) * mLocked.xScale;
-                toolMajor = float(touch->pointers[index].toolMajor) * mLocked.yScale;
-                toolMinor = float(touch->pointers[index].toolMinor) * mLocked.xScale;
-            } else {
-                // Nominally horizontal orientation: scale major axis by X, and scale minor axis by Y.
-                touchMajor = float(touch->pointers[index].touchMajor) * mLocked.xScale;
-                touchMinor = float(touch->pointers[index].touchMinor) * mLocked.yScale;
-                toolMajor = float(touch->pointers[index].toolMajor) * mLocked.xScale;
-                toolMinor = float(touch->pointers[index].toolMinor) * mLocked.yScale;
+            // ToolMajor and ToolMinor
+            float toolMajor, toolMinor;
+            switch (mCalibration.toolAreaCalibration) {
+            case Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC:
+                toolMajor = in.toolMajor * mLocked.geometricScale;
+                if (mRawAxes.toolMinor.valid) {
+                    toolMinor = in.toolMinor * mLocked.geometricScale;
+                } else {
+                    toolMinor = toolMajor;
+                }
+                break;
+            case Calibration::TOOL_AREA_CALIBRATION_LINEAR:
+                toolMajor = in.toolMajor != 0
+                        ? in.toolMajor * mLocked.toolAreaLinearScale + mLocked.toolAreaLinearBias
+                        : 0;
+                if (mRawAxes.toolMinor.valid) {
+                    toolMinor = in.toolMinor != 0
+                            ? in.toolMinor * mLocked.toolAreaLinearScale
+                                    + mLocked.toolAreaLinearBias
+                            : 0;
+                } else {
+                    toolMinor = toolMajor;
+                }
+                break;
+            default:
+                toolMajor = 0;
+                toolMinor = 0;
+                break;
             }
 
+            if (mCalibration.haveToolAreaIsSummed && mCalibration.toolAreaIsSummed) {
+                toolMajor /= pointerCount;
+                toolMinor /= pointerCount;
+            }
+
+            // Pressure
+            float rawPressure;
+            switch (mCalibration.pressureSource) {
+            case Calibration::PRESSURE_SOURCE_PRESSURE:
+                rawPressure = in.pressure;
+                break;
+            case Calibration::PRESSURE_SOURCE_TOUCH:
+                rawPressure = in.touchMajor;
+                break;
+            default:
+                rawPressure = 0;
+            }
+
+            float pressure;
+            switch (mCalibration.pressureCalibration) {
+            case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
+            case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
+                pressure = rawPressure * mLocked.pressureScale;
+                break;
+            default:
+                pressure = 1;
+                break;
+            }
+
+            // TouchMajor and TouchMinor
+            float touchMajor, touchMinor;
+            switch (mCalibration.touchAreaCalibration) {
+            case Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC:
+                touchMajor = in.touchMajor * mLocked.geometricScale;
+                if (mRawAxes.touchMinor.valid) {
+                    touchMinor = in.touchMinor * mLocked.geometricScale;
+                } else {
+                    touchMinor = touchMajor;
+                }
+                break;
+            case Calibration::TOUCH_AREA_CALIBRATION_PRESSURE:
+                touchMajor = toolMajor * pressure;
+                touchMinor = toolMinor * pressure;
+                break;
+            default:
+                touchMajor = 0;
+                touchMinor = 0;
+                break;
+            }
+
+            if (touchMajor > toolMajor) {
+                touchMajor = toolMajor;
+            }
+            if (touchMinor > toolMinor) {
+                touchMinor = toolMinor;
+            }
+
+            // Size
+            float size;
+            switch (mCalibration.sizeCalibration) {
+            case Calibration::SIZE_CALIBRATION_NORMALIZED: {
+                float rawSize = mRawAxes.toolMinor.valid
+                        ? avg(in.toolMajor, in.toolMinor)
+                        : in.toolMajor;
+                size = rawSize * mLocked.sizeScale;
+                break;
+            }
+            default:
+                size = 0;
+                break;
+            }
+
+            // Orientation
+            float orientation;
+            switch (mCalibration.orientationCalibration) {
+            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
+                orientation = in.orientation * mLocked.orientationScale;
+                break;
+            default:
+                orientation = 0;
+            }
+
+            // Adjust coords for orientation.
             switch (mLocked.surfaceOrientation) {
             case InputReaderPolicyInterface::ROTATION_90: {
                 float xTemp = x;
@@ -1702,23 +2285,23 @@
             }
             }
 
-            pointerIds[pointerCount] = int32_t(id);
+            // Write output coords.
+            PointerCoords& out = pointerCoords[outIndex];
+            out.x = x;
+            out.y = y;
+            out.pressure = pressure;
+            out.size = size;
+            out.touchMajor = touchMajor;
+            out.touchMinor = touchMinor;
+            out.toolMajor = toolMajor;
+            out.toolMinor = toolMinor;
+            out.orientation = orientation;
 
-            pointerCoords[pointerCount].x = x;
-            pointerCoords[pointerCount].y = y;
-            pointerCoords[pointerCount].pressure = pressure;
-            pointerCoords[pointerCount].size = size;
-            pointerCoords[pointerCount].touchMajor = touchMajor;
-            pointerCoords[pointerCount].touchMinor = touchMinor;
-            pointerCoords[pointerCount].toolMajor = toolMajor;
-            pointerCoords[pointerCount].toolMinor = toolMinor;
-            pointerCoords[pointerCount].orientation = orientation;
+            pointerIds[outIndex] = int32_t(id);
 
             if (id == changedId) {
-                motionEventAction |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+                motionEventAction |= outIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
             }
-
-            pointerCount += 1;
         }
 
         // Check edge flags by looking only at the first pointer since the flags are
@@ -1747,9 +2330,9 @@
 }
 
 bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
-    if (mAxes.x.valid && mAxes.y.valid) {
-        return x >= mAxes.x.minValue && x <= mAxes.x.maxValue
-                && y >= mAxes.y.minValue && y <= mAxes.y.maxValue;
+    if (mRawAxes.x.valid && mRawAxes.y.valid) {
+        return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue
+                && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue;
     }
     return true;
 }
@@ -1960,7 +2543,7 @@
  * then drop it. */
 bool TouchInputMapper::applyBadTouchFilter() {
     // This hack requires valid axis parameters.
-    if (! mAxes.y.valid) {
+    if (! mRawAxes.y.valid) {
         return false;
     }
 
@@ -1982,7 +2565,7 @@
     // the long size of the screen to be bad.  This was a magic value
     // determined by looking at the maximum distance it is feasible
     // to actually move in one sample.
-    int32_t maxDeltaY = mAxes.y.getRange() * 7 / 16;
+    int32_t maxDeltaY = mRawAxes.y.getRange() * 7 / 16;
 
     // XXX The original code in InputDevice.java included commented out
     //     code for testing the X axis.  Note that when we drop a point
@@ -2044,7 +2627,7 @@
  */
 bool TouchInputMapper::applyJumpyTouchFilter() {
     // This hack requires valid axis parameters.
-    if (! mAxes.y.valid) {
+    if (! mRawAxes.y.valid) {
         return false;
     }
 
@@ -2104,7 +2687,7 @@
     }
 
     if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) {
-        int jumpyEpsilon = mAxes.y.getRange() / JUMPY_EPSILON_DIVISOR;
+        int jumpyEpsilon = mRawAxes.y.getRange() / JUMPY_EPSILON_DIVISOR;
 
         // We only replace the single worst jumpy point as characterized by pointer distance
         // in a single axis.
@@ -2209,7 +2792,18 @@
         uint32_t id = mCurrentTouch.pointers[currentIndex].id;
         int32_t x = mCurrentTouch.pointers[currentIndex].x;
         int32_t y = mCurrentTouch.pointers[currentIndex].y;
-        int32_t pressure = mCurrentTouch.pointers[currentIndex].pressure;
+        int32_t pressure;
+        switch (mCalibration.pressureSource) {
+        case Calibration::PRESSURE_SOURCE_PRESSURE:
+            pressure = mCurrentTouch.pointers[currentIndex].pressure;
+            break;
+        case Calibration::PRESSURE_SOURCE_TOUCH:
+            pressure = mCurrentTouch.pointers[currentIndex].touchMajor;
+            break;
+        default:
+            pressure = 1;
+            break;
+        }
 
         if (mLastTouch.idBits.hasBit(id)) {
             // Pointer was down before and is still down now.
@@ -2274,17 +2868,19 @@
                     }
                 }
 
-                averagedX /= totalPressure;
-                averagedY /= totalPressure;
+                if (totalPressure != 0) {
+                    averagedX /= totalPressure;
+                    averagedY /= totalPressure;
 
 #if DEBUG_HACKS
-                LOGD("AveragingTouchFilter: Pointer id %d - "
-                        "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure,
-                        averagedX, averagedY);
+                    LOGD("AveragingTouchFilter: Pointer id %d - "
+                            "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure,
+                            averagedX, averagedY);
 #endif
 
-                mCurrentTouch.pointers[currentIndex].x = averagedX;
-                mCurrentTouch.pointers[currentIndex].y = averagedY;
+                    mCurrentTouch.pointers[currentIndex].x = averagedX;
+                    mCurrentTouch.pointers[currentIndex].y = averagedY;
+                }
             } else {
 #if DEBUG_HACKS
                 LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id);
@@ -2382,8 +2978,8 @@
     mDown = false;
     mX = 0;
     mY = 0;
-    mPressure = 1; // default to 1 for devices that don't report pressure
-    mSize = 0; // default to 0 for devices that don't report size
+    mPressure = 0; // default to 0 for devices that don't report pressure
+    mToolWidth = 0; // default to 0 for devices that don't report tool width
 }
 
 void SingleTouchInputMapper::reset() {
@@ -2460,7 +3056,7 @@
     }
 
     if (fields & Accumulator::FIELD_ABS_TOOL_WIDTH) {
-        mSize = mAccumulator.absToolWidth;
+        mToolWidth = mAccumulator.absToolWidth;
     }
 
     mCurrentTouch.clear();
@@ -2471,11 +3067,10 @@
         mCurrentTouch.pointers[0].x = mX;
         mCurrentTouch.pointers[0].y = mY;
         mCurrentTouch.pointers[0].pressure = mPressure;
-        mCurrentTouch.pointers[0].size = mSize;
-        mCurrentTouch.pointers[0].touchMajor = mSize;
-        mCurrentTouch.pointers[0].touchMinor = mSize;
-        mCurrentTouch.pointers[0].toolMajor = mSize;
-        mCurrentTouch.pointers[0].toolMinor = mSize;
+        mCurrentTouch.pointers[0].touchMajor = 0;
+        mCurrentTouch.pointers[0].touchMinor = 0;
+        mCurrentTouch.pointers[0].toolMajor = mToolWidth;
+        mCurrentTouch.pointers[0].toolMinor = mToolWidth;
         mCurrentTouch.pointers[0].orientation = 0;
         mCurrentTouch.idToIndex[0] = 0;
         mCurrentTouch.idBits.markBit(0);
@@ -2486,20 +3081,13 @@
     mAccumulator.clear();
 }
 
-void SingleTouchInputMapper::configureAxes() {
-    TouchInputMapper::configureAxes();
+void SingleTouchInputMapper::configureRawAxes() {
+    TouchInputMapper::configureRawAxes();
 
-    // The axes are aliased to take into account the manner in which they are presented
-    // as part of the TouchData during the sync.
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mAxes.x);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mAxes.y);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mAxes.pressure);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mAxes.size);
-
-    mAxes.touchMajor = mAxes.size;
-    mAxes.touchMinor = mAxes.size;
-    mAxes.toolMajor = mAxes.size;
-    mAxes.toolMinor = mAxes.size;
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor);
 }
 
 
@@ -2562,6 +3150,10 @@
             pointer->fields |= Accumulator::FIELD_ABS_MT_TRACKING_ID;
             pointer->absMTTrackingId = rawEvent->value;
             break;
+        case ABS_MT_PRESSURE:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_PRESSURE;
+            pointer->absMTPressure = rawEvent->value;
+            break;
         }
         break;
     }
@@ -2596,8 +3188,7 @@
 
 void MultiTouchInputMapper::sync(nsecs_t when) {
     static const uint32_t REQUIRED_FIELDS =
-            Accumulator::FIELD_ABS_MT_POSITION_X
-            | Accumulator::FIELD_ABS_MT_POSITION_Y;
+            Accumulator::FIELD_ABS_MT_POSITION_X | Accumulator::FIELD_ABS_MT_POSITION_Y;
 
     uint32_t inCount = mAccumulator.pointerCount;
     uint32_t outCount = 0;
@@ -2619,60 +3210,59 @@
         outPointer.x = inPointer.absMTPositionX;
         outPointer.y = inPointer.absMTPositionY;
 
-        if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) {
-            int32_t value = inPointer.absMTTouchMajor;
-            if (value <= 0) {
-                // Some devices send sync packets with X / Y but with a 0 touch major to indicate
+        if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) {
+            if (inPointer.absMTPressure <= 0) {
+                // Some devices send sync packets with X / Y but with a 0 presure to indicate
                 // a pointer up.  Drop this finger.
                 continue;
             }
+            outPointer.pressure = inPointer.absMTPressure;
+        } else {
+            // Default pressure to 0 if absent.
+            outPointer.pressure = 0;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) {
+            if (inPointer.absMTTouchMajor <= 0) {
+                // Some devices send sync packets with X / Y but with a 0 touch major to indicate
+                // a pointer going up.  Drop this finger.
+                continue;
+            }
             outPointer.touchMajor = inPointer.absMTTouchMajor;
         } else {
+            // Default touch area to 0 if absent.
             outPointer.touchMajor = 0;
         }
 
         if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) {
             outPointer.touchMinor = inPointer.absMTTouchMinor;
         } else {
+            // Assume touch area is circular.
             outPointer.touchMinor = outPointer.touchMajor;
         }
 
         if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) {
             outPointer.toolMajor = inPointer.absMTWidthMajor;
         } else {
-            outPointer.toolMajor = outPointer.touchMajor;
+            // Default tool area to 0 if absent.
+            outPointer.toolMajor = 0;
         }
 
         if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) {
             outPointer.toolMinor = inPointer.absMTWidthMinor;
         } else {
+            // Assume tool area is circular.
             outPointer.toolMinor = outPointer.toolMajor;
         }
 
         if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) {
             outPointer.orientation = inPointer.absMTOrientation;
         } else {
+            // Default orientation to vertical if absent.
             outPointer.orientation = 0;
         }
 
-        if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) {
-            outPointer.pressure = inPointer.absMTPressure;
-        } else {
-            // Derive an approximation of pressure.
-            // FIXME Traditionally we have just passed a normalized value based on
-            //       ABS_MT_TOUCH_MAJOR as an estimate of pressure but the result is not
-            //       very meaningful, particularly on large displays.  We should probably let
-            //       pressure = touch_major / tool_major but it is unclear whether that will
-            //       break applications.
-            outPointer.pressure = outPointer.touchMajor;
-        }
-
-        // Size is an alias for a normalized tool width.
-        // FIXME Normalized tool width doesn't actually make much sense since it literally
-        //       means the approaching contact major axis is divided by its full range as
-        //       reported by the driver.  On a large display this could produce very small values.
-        outPointer.size = outPointer.toolMajor;
-
+        // Assign pointer id using tracking id if available.
         if (havePointerIds) {
             if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) {
                 uint32_t id = uint32_t(inPointer.absMTTrackingId);
@@ -2705,33 +3295,17 @@
     mAccumulator.clear();
 }
 
-void MultiTouchInputMapper::configureAxes() {
-    TouchInputMapper::configureAxes();
+void MultiTouchInputMapper::configureRawAxes() {
+    TouchInputMapper::configureRawAxes();
 
-    // The axes are aliased to take into account the manner in which they are presented
-    // as part of the TouchData during the sync.
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mAxes.x);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mAxes.y);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mAxes.touchMajor);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mAxes.touchMinor);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mAxes.toolMajor);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mAxes.toolMinor);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mAxes.orientation);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mAxes.pressure);
-
-    if (! mAxes.touchMinor.valid) {
-        mAxes.touchMinor = mAxes.touchMajor;
-    }
-
-    if (! mAxes.toolMinor.valid) {
-        mAxes.toolMinor = mAxes.toolMajor;
-    }
-
-    if (! mAxes.pressure.valid) {
-        mAxes.pressure = mAxes.touchMajor;
-    }
-
-    mAxes.size = mAxes.toolMajor;
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mRawAxes.x);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mRawAxes.y);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mRawAxes.touchMajor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mRawAxes.touchMinor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mRawAxes.toolMajor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mRawAxes.toolMinor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mRawAxes.orientation);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mRawAxes.pressure);
 }
 
 
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 4362d14..91e7df3 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1946,8 +1946,8 @@
         ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
         if (offset <= 0) {
             if (offset < 0) {
-                LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %d: 0x%08x\n",
-                        resID, t, e, (int)ip, (int)offset);
+                LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n",
+                        resID, t, e, ip, (int)offset);
                 return offset;
             }
             continue;
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 94f5c7a..ca364f5 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -72,6 +72,9 @@
 
     private String mPath;
     private FileDescriptor mFd;
+    private boolean mPrepareAuxiliaryFile = false;
+    private String mPathAux;
+    private FileDescriptor mFdAux;
     private EventHandler mEventHandler;
     private OnErrorListener mOnErrorListener;
     private OnInfoListener mOnInfoListener;
@@ -480,6 +483,38 @@
     }
 
     /**
+     * Pass in the file descriptor of the auxiliary file to be written. Call this after
+     * setOutputFormat() but before prepare().
+     *
+     * @param fd an open file descriptor to be written into.
+     * @throws IllegalStateException if it is called before
+     * setOutputFormat() or after prepare()
+     * @hide
+     */
+    public void setAuxiliaryOutputFile(FileDescriptor fd) throws IllegalStateException
+    {
+        mPrepareAuxiliaryFile = true;
+        mPathAux = null;
+        mFdAux = fd;
+    }
+
+    /**
+     * Sets the path of the auxiliary output file to be produced. Call this after
+     * setOutputFormat() but before prepare().
+     *
+     * @param path The pathname to use.
+     * @throws IllegalStateException if it is called before
+     * setOutputFormat() or after prepare()
+     * @hide
+     */
+    public void setAuxiliaryOutputFile(String path) throws IllegalStateException
+    {
+        mPrepareAuxiliaryFile = true;
+        mFdAux = null;
+        mPathAux = path;
+    }
+
+    /**
      * Pass in the file descriptor of the file to be written. Call this after
      * setOutputFormat() but before prepare().
      *
@@ -510,6 +545,8 @@
     // native implementation
     private native void _setOutputFile(FileDescriptor fd, long offset, long length)
         throws IllegalStateException, IOException;
+    private native void _setOutputFileAux(FileDescriptor fd)
+        throws IllegalStateException, IOException;
     private native void _prepare() throws IllegalStateException, IOException;
 
     /**
@@ -535,6 +572,22 @@
         } else {
             throw new IOException("No valid output file");
         }
+
+        if (mPrepareAuxiliaryFile) {
+            if (mPathAux != null) {
+                FileOutputStream fos = new FileOutputStream(mPathAux);
+                try {
+                    _setOutputFileAux(fos.getFD());
+                } finally {
+                    fos.close();
+                }
+            } else if (mFdAux != null) {
+                _setOutputFileAux(mFdAux);
+            } else {
+                throw new IOException("No valid output file");
+            }
+        }
+
         _prepare();
     }
 
diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java
index 408c64b..9016e68 100644
--- a/media/java/android/media/MtpDatabase.java
+++ b/media/java/android/media/MtpDatabase.java
@@ -19,12 +19,15 @@
 import android.content.Context;
 import android.content.ContentValues;
 import android.content.IContentProvider;
+import android.content.Intent;
 import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
 import android.net.Uri;
 import android.os.RemoteException;
 import android.provider.MediaStore.Audio;
 import android.provider.MediaStore.MediaColumns;
 import android.provider.MediaStore.MtpObjects;
+import android.provider.Mtp;
 import android.util.Log;
 
 /**
@@ -34,10 +37,18 @@
 
     private static final String TAG = "MtpDatabase";
 
+    private final Context mContext;
     private final IContentProvider mMediaProvider;
     private final String mVolumeName;
     private final Uri mObjectsUri;
 
+    // true if the database has been modified in the current MTP session
+    private boolean mDatabaseModified;
+
+    // database for writable MTP device properties
+    private SQLiteDatabase mDevicePropDb;
+    private static final int DEVICE_PROPERTIES_DATABASE_VERSION = 1;
+
     // FIXME - this should be passed in via the constructor
     private final int mStorageID = 0x00010001;
 
@@ -63,6 +74,9 @@
     private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND "
                                             + MtpObjects.ObjectColumns.FORMAT + "=?";
 
+    private static final String[] DEVICE_PROPERTY_PROJECTION = new String[] { "_id", "value" };
+    private  static final String DEVICE_PROPERTY_WHERE = "code=?";
+
     private final MediaScanner mMediaScanner;
 
     static {
@@ -72,10 +86,12 @@
     public MtpDatabase(Context context, String volumeName) {
         native_setup();
 
+        mContext = context;
         mMediaProvider = context.getContentResolver().acquireProvider("media");
         mVolumeName = volumeName;
         mObjectsUri = MtpObjects.getContentUri(volumeName);
         mMediaScanner = new MediaScanner(context);
+        openDevicePropertiesDatabase(context);
     }
 
     @Override
@@ -87,8 +103,25 @@
         }
     }
 
+    private void openDevicePropertiesDatabase(Context context) {
+        mDevicePropDb = context.openOrCreateDatabase("device-properties", Context.MODE_PRIVATE, null);
+        int version = mDevicePropDb.getVersion();
+
+        // initialize if necessary
+        if (version != DEVICE_PROPERTIES_DATABASE_VERSION) {
+            mDevicePropDb.execSQL("CREATE TABLE properties (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    "code INTEGER UNIQUE ON CONFLICT REPLACE," +
+                    "value TEXT" +
+                    ");");
+            mDevicePropDb.execSQL("CREATE INDEX property_index ON properties (code);");
+            mDevicePropDb.setVersion(DEVICE_PROPERTIES_DATABASE_VERSION);
+        }
+    }
+
     private int beginSendObject(String path, int format, int parent,
                          int storage, long size, long modified) {
+        mDatabaseModified = true;
         ContentValues values = new ContentValues();
         values.put(MtpObjects.ObjectColumns.DATA, path);
         values.put(MtpObjects.ObjectColumns.FORMAT, format);
@@ -249,8 +282,10 @@
     }
 
     private int[] getSupportedDeviceProperties() {
-        // no device properties yet
-        return null;
+        return new int[] {
+            MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,
+            MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,
+        };
     }
 
     private int getObjectProperty(int handle, int property,
@@ -334,6 +369,68 @@
         return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
     }
 
+    private int setObjectProperty(int handle, int property,
+                            long intValue, String stringValue) {
+        Log.d(TAG, "setObjectProperty: " + property);
+        return MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
+    }
+
+    private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) {
+        Log.d(TAG, "getDeviceProperty: " + property);
+
+        switch (property) {
+            case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
+            case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
+                // writable string properties kept in our device property database
+                Cursor c = null;
+                try {
+                    c = mDevicePropDb.query("properties", DEVICE_PROPERTY_PROJECTION,
+                        DEVICE_PROPERTY_WHERE, new String[] {  Integer.toString(property) },
+                        null, null, null);
+
+                    if (c != null && c.moveToNext()) {
+                        String value = c.getString(1);
+                        int length = value.length();
+                        if (length > 255) {
+                            length = 255;
+                        }
+                        value.getChars(0, length, outStringValue, 0);
+                        outStringValue[length] = 0;
+                    } else {
+                        outStringValue[0] = 0;
+                    }
+                    return MtpConstants.RESPONSE_OK;
+                } finally {
+                    if (c != null) {
+                        c.close();
+                    }
+                }
+        }
+
+        return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+    }
+
+    private int setDeviceProperty(int property, long intValue, String stringValue) {
+        Log.d(TAG, "setDeviceProperty: " + property + " : " + stringValue);
+
+        switch (property) {
+            case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
+            case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
+                // writable string properties kept in our device property database
+                try {
+                    ContentValues values = new ContentValues();
+                    values.put("code", property);
+                    values.put("value", stringValue);
+                    mDevicePropDb.insert("properties", "code", values);
+                    return MtpConstants.RESPONSE_OK;
+                } catch (Exception e) {
+                    return MtpConstants.RESPONSE_GENERAL_ERROR;
+                }
+        }
+
+        return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+    }
+
     private boolean getObjectInfo(int handle, int[] outStorageFormatParent,
                         char[] outName, long[] outSizeModified) {
         Log.d(TAG, "getObjectInfo: " + handle);
@@ -398,6 +495,7 @@
 
     private int deleteFile(int handle) {
         Log.d(TAG, "deleteFile: " + handle);
+        mDatabaseModified = true;
         Uri uri = MtpObjects.getContentUri(mVolumeName, handle);
         try {
             if (mMediaProvider.delete(uri, null, null) == 1) {
@@ -440,6 +538,7 @@
     }
 
     private int setObjectReferences(int handle, int[] references) {
+        mDatabaseModified = true;
         Uri uri = MtpObjects.getReferencesUri(mVolumeName, handle);
         int count = references.length;
         ContentValues[] valuesList = new ContentValues[count];
@@ -458,6 +557,20 @@
         return MtpConstants.RESPONSE_GENERAL_ERROR;
     }
 
+    private void sessionStarted() {
+        Log.d(TAG, "sessionStarted");
+        mDatabaseModified = false;
+    }
+
+    private void sessionEnded() {
+        Log.d(TAG, "sessionEnded");
+        if (mDatabaseModified) {
+            Log.d(TAG, "sending ACTION_MTP_SESSION_END");
+            mContext.sendBroadcast(new Intent(Mtp.ACTION_MTP_SESSION_END));
+            mDatabaseModified = false;
+        }
+    }
+
     // used by the JNI code
     private int mNativeContext;
 
diff --git a/media/java/android/media/MtpServer.java b/media/java/android/media/MtpServer.java
index dcf08e2..7f15276 100644
--- a/media/java/android/media/MtpServer.java
+++ b/media/java/android/media/MtpServer.java
@@ -59,6 +59,10 @@
         native_send_object_removed(handle);
     }
 
+    public void setPtpMode(boolean usePtp) {
+        native_set_ptp_mode(usePtp);
+    }
+
     // used by the JNI code
     private int mNativeContext;
 
@@ -68,4 +72,5 @@
     private native final void native_stop();
     private native final void native_send_object_added(int handle);
     private native final void native_send_object_removed(int handle);
+    private native final void native_set_ptp_mode(boolean usePtp);
 }
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 653532c..25d243b 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -1,10 +1,6 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-ifneq ($(BUILD_WITHOUT_PV),true)
-include external/opencore/Config.mk
-endif
-
 LOCAL_SRC_FILES:= \
     android_media_MediaPlayer.cpp \
     android_media_MediaRecorder.cpp \
@@ -32,14 +28,6 @@
     libcamera_client \
 	libsqlite
 
-ifneq ($(BUILD_WITHOUT_PV),true)
-
-LOCAL_SHARED_LIBRARIES += \
-    libopencore_player
-else
-    LOCAL_CFLAGS += -DNO_OPENCORE
-endif
-
 ifneq ($(TARGET_SIMULATOR),true)
 LOCAL_STATIC_LIBRARIES := libmtp libusbhost
 endif
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 6710db0..d4aacaf 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -792,10 +792,7 @@
 extern int register_android_media_MtpCursor(JNIEnv *env);
 extern int register_android_media_MtpDatabase(JNIEnv *env);
 extern int register_android_media_MtpServer(JNIEnv *env);
-
-#ifndef NO_OPENCORE
 extern int register_android_media_AmrInputStream(JNIEnv *env);
-#endif
 
 jint JNI_OnLoad(JavaVM* vm, void* reserved)
 {
@@ -828,12 +825,10 @@
         goto bail;
     }
 
-#ifndef NO_OPENCORE
     if (register_android_media_AmrInputStream(env) < 0) {
         LOGE("ERROR: AmrInputStream native registration failed\n");
         goto bail;
     }
-#endif
 
     if (register_android_media_ResampleInputStream(env) < 0) {
         LOGE("ERROR: ResampleInputStream native registration failed\n");
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index f69b8ad..24fe2db 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -260,6 +260,20 @@
 }
 
 static void
+android_media_MediaRecorder_setOutputFileAuxFD(JNIEnv *env, jobject thiz, jobject fileDescriptor)
+{
+    LOGV("setOutputFile");
+    if (fileDescriptor == NULL) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return;
+    }
+    int fd = getParcelFileDescriptorFD(env, fileDescriptor);
+    sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
+    status_t opStatus = mr->setOutputFileAuxiliary(fd);
+    process_media_recorder_call(env, opStatus, "java/io/IOException", "setOutputFile failed.");
+}
+
+static void
 android_media_MediaRecorder_setVideoSize(JNIEnv *env, jobject thiz, jint width, jint height)
 {
     LOGV("setVideoSize(%d, %d)", width, height);
@@ -466,6 +480,7 @@
     {"setAudioEncoder",      "(I)V",                            (void *)android_media_MediaRecorder_setAudioEncoder},
     {"setParameter",         "(Ljava/lang/String;)V",           (void *)android_media_MediaRecorder_setParameter},
     {"_setOutputFile",       "(Ljava/io/FileDescriptor;JJ)V",   (void *)android_media_MediaRecorder_setOutputFileFD},
+    {"_setOutputFileAux",    "(Ljava/io/FileDescriptor;)V",     (void *)android_media_MediaRecorder_setOutputFileAuxFD},
     {"setVideoSize",         "(II)V",                           (void *)android_media_MediaRecorder_setVideoSize},
     {"setVideoFrameRate",    "(I)V",                            (void *)android_media_MediaRecorder_setVideoFrameRate},
     {"setMaxDuration",       "(I)V",                            (void *)android_media_MediaRecorder_setMaxDuration},
diff --git a/media/jni/android_media_MtpDatabase.cpp b/media/jni/android_media_MtpDatabase.cpp
index 4ef3a9f..1842cb2 100644
--- a/media/jni/android_media_MtpDatabase.cpp
+++ b/media/jni/android_media_MtpDatabase.cpp
@@ -30,6 +30,7 @@
 #include "MtpDatabase.h"
 #include "MtpDataPacket.h"
 #include "MtpProperty.h"
+#include "MtpStringBuffer.h"
 #include "MtpUtils.h"
 #include "mtp.h"
 
@@ -47,11 +48,16 @@
 static jmethodID method_getSupportedDeviceProperties;
 static jmethodID method_getObjectProperty;
 static jmethodID method_setObjectProperty;
+static jmethodID method_getDeviceProperty;
+static jmethodID method_setDeviceProperty;
 static jmethodID method_getObjectInfo;
 static jmethodID method_getObjectFilePath;
 static jmethodID method_deleteFile;
 static jmethodID method_getObjectReferences;
 static jmethodID method_setObjectReferences;
+static jmethodID method_sessionStarted;
+static jmethodID method_sessionEnded;
+
 static jfieldID field_context;
 
 MtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) {
@@ -124,7 +130,8 @@
                                             int64_t& fileLength);
     virtual MtpResponseCode         deleteFile(MtpObjectHandle handle);
 
-    bool                            getPropertyInfo(MtpObjectProperty property, int& type);
+    bool                            getObjectPropertyInfo(MtpObjectProperty property, int& type);
+    bool                            getDevicePropertyInfo(MtpDeviceProperty property, int& type);
 
     virtual MtpObjectHandleList*    getObjectReferences(MtpObjectHandle handle);
 
@@ -135,6 +142,10 @@
                                             MtpObjectFormat format);
 
     virtual MtpProperty*            getDevicePropertyDesc(MtpDeviceProperty property);
+
+    virtual void                    sessionStarted();
+
+    virtual void                    sessionEnded();
 };
 
 // ----------------------------------------------------------------------------
@@ -316,14 +327,16 @@
                                             MtpDataPacket& packet) {
     int         type;
 
-    if (!getPropertyInfo(property, type))
-        return MTP_RESPONSE_INVALID_OBJECT_PROP_CODE;
+    if (!getObjectPropertyInfo(property, type))
+        return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
 
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     jint result = env->CallIntMethod(mDatabase, method_getObjectProperty,
                 (jint)handle, (jint)property, mLongBuffer, mStringBuffer);
-    if (result != MTP_RESPONSE_OK)
+    if (result != MTP_RESPONSE_OK) {
+        checkAndClearExceptionFromCallback(env, __FUNCTION__);
         return result;
+    }
 
     jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
     jlong longValue = longValues[0];
@@ -377,8 +390,8 @@
             break;
          }
         default:
-            LOGE("unsupported object type\n");
-            return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
+            LOGE("unsupported type in getObjectPropertyValue\n");
+            return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
     }
 
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
@@ -388,17 +401,179 @@
 MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
                                             MtpObjectProperty property,
                                             MtpDataPacket& packet) {
-    return -1;
+    int         type;
+
+    if (!getObjectPropertyInfo(property, type))
+        return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jlong longValue = 0;
+    jstring stringValue = NULL;
+
+    switch (type) {
+        case MTP_TYPE_INT8:
+            longValue = packet.getInt8();
+            break;
+        case MTP_TYPE_UINT8:
+            longValue = packet.getUInt8();
+            break;
+        case MTP_TYPE_INT16:
+            longValue = packet.getInt16();
+            break;
+        case MTP_TYPE_UINT16:
+            longValue = packet.getUInt16();
+            break;
+        case MTP_TYPE_INT32:
+            longValue = packet.getInt32();
+            break;
+        case MTP_TYPE_UINT32:
+            longValue = packet.getUInt32();
+            break;
+        case MTP_TYPE_INT64:
+            longValue = packet.getInt64();
+            break;
+        case MTP_TYPE_UINT64:
+            longValue = packet.getUInt64();
+            break;
+        case MTP_TYPE_STR:
+        {
+            MtpStringBuffer buffer;
+            packet.getString(buffer);
+            stringValue = env->NewStringUTF((const char *)buffer);
+            break;
+         }
+        default:
+            LOGE("unsupported type in getObjectPropertyValue\n");
+            return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
+    }
+
+    jint result = env->CallIntMethod(mDatabase, method_setObjectProperty,
+                (jint)handle, (jint)property, longValue, stringValue);
+
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return result;
 }
 
 MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
                                             MtpDataPacket& packet) {
-    return -1;
+
+    int         type;
+
+    if (!getDevicePropertyInfo(property, type))
+        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
+                (jint)property, mLongBuffer, mStringBuffer);
+    if (result != MTP_RESPONSE_OK) {
+        checkAndClearExceptionFromCallback(env, __FUNCTION__);
+        return result;
+    }
+
+    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
+    jlong longValue = longValues[0];
+    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
+
+    switch (type) {
+        case MTP_TYPE_INT8:
+            packet.putInt8(longValue);
+            break;
+        case MTP_TYPE_UINT8:
+            packet.putUInt8(longValue);
+            break;
+        case MTP_TYPE_INT16:
+            packet.putInt16(longValue);
+            break;
+        case MTP_TYPE_UINT16:
+            packet.putUInt16(longValue);
+            break;
+        case MTP_TYPE_INT32:
+            packet.putInt32(longValue);
+            break;
+        case MTP_TYPE_UINT32:
+            packet.putUInt32(longValue);
+            break;
+        case MTP_TYPE_INT64:
+            packet.putInt64(longValue);
+            break;
+        case MTP_TYPE_UINT64:
+            packet.putUInt64(longValue);
+            break;
+        case MTP_TYPE_INT128:
+            packet.putInt128(longValue);
+            break;
+        case MTP_TYPE_UINT128:
+            packet.putInt128(longValue);
+            break;
+        case MTP_TYPE_STR:
+        {
+            jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
+            packet.putString(str);
+            env->ReleaseCharArrayElements(mStringBuffer, str, 0);
+            break;
+         }
+        default:
+            LOGE("unsupported type in getDevicePropertyValue\n");
+            return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
+    }
+
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return MTP_RESPONSE_OK;
 }
 
 MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
                                             MtpDataPacket& packet) {
-    return -1;
+    int         type;
+
+    if (!getDevicePropertyInfo(property, type))
+        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jlong longValue = 0;
+    jstring stringValue = NULL;
+
+    switch (type) {
+        case MTP_TYPE_INT8:
+            longValue = packet.getInt8();
+            break;
+        case MTP_TYPE_UINT8:
+            longValue = packet.getUInt8();
+            break;
+        case MTP_TYPE_INT16:
+            longValue = packet.getInt16();
+            break;
+        case MTP_TYPE_UINT16:
+            longValue = packet.getUInt16();
+            break;
+        case MTP_TYPE_INT32:
+            longValue = packet.getInt32();
+            break;
+        case MTP_TYPE_UINT32:
+            longValue = packet.getUInt32();
+            break;
+        case MTP_TYPE_INT64:
+            longValue = packet.getInt64();
+            break;
+        case MTP_TYPE_UINT64:
+            longValue = packet.getUInt64();
+            break;
+        case MTP_TYPE_STR:
+        {
+            MtpStringBuffer buffer;
+            packet.getString(buffer);
+            stringValue = env->NewStringUTF((const char *)buffer);
+            break;
+         }
+        default:
+            LOGE("unsupported type in setDevicePropertyValue\n");
+            return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
+    }
+
+    jint result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
+                (jint)property, longValue, stringValue);
+
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return result;
 }
 
 MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) {
@@ -466,8 +641,10 @@
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     jint result = env->CallIntMethod(mDatabase, method_getObjectFilePath,
                 (jint)handle, mStringBuffer, mLongBuffer);
-    if (result != MTP_RESPONSE_OK)
+    if (result != MTP_RESPONSE_OK) {
+        checkAndClearExceptionFromCallback(env, __FUNCTION__);
         return result;
+    }
 
     jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
     filePath.setTo(str, strlen16(str));
@@ -494,7 +671,7 @@
     int                 type;
 };
 
-static const PropertyTableEntry   kPropertyTable[] = {
+static const PropertyTableEntry   kObjectPropertyTable[] = {
     {   MTP_PROPERTY_PARENT_OBJECT,     MTP_TYPE_UINT32 },
     {   MTP_PROPERTY_STORAGE_ID,        MTP_TYPE_UINT32 },
     {   MTP_PROPERTY_OBJECT_FORMAT,     MTP_TYPE_UINT16 },
@@ -503,9 +680,26 @@
     {   MTP_PROPERTY_DATE_MODIFIED,     MTP_TYPE_STR    },
 };
 
-bool MyMtpDatabase::getPropertyInfo(MtpObjectProperty property, int& type) {
-    int count = sizeof(kPropertyTable) / sizeof(kPropertyTable[0]);
-    const PropertyTableEntry* entry = kPropertyTable;
+static const PropertyTableEntry   kDevicePropertyTable[] = {
+    {   MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,     MTP_TYPE_STR },
+    {   MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,        MTP_TYPE_STR },
+};
+
+bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
+    int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
+    const PropertyTableEntry* entry = kObjectPropertyTable;
+    for (int i = 0; i < count; i++, entry++) {
+        if (entry->property == property) {
+            type = entry->type;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) {
+    int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]);
+    const PropertyTableEntry* entry = kDevicePropertyTable;
     for (int i = 0; i < count; i++, entry++) {
         if (entry->property == property) {
             type = entry->type;
@@ -580,7 +774,28 @@
 }
 
 MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
-    return NULL;
+    MtpProperty* result = NULL;
+    switch (property) {
+        case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
+        case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
+            // writeable string properties
+            result = new MtpProperty(property, MTP_TYPE_STR, true);
+            break;
+    }
+
+    return result;
+}
+
+void MyMtpDatabase::sessionStarted() {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->CallVoidMethod(mDatabase, method_sessionStarted);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+}
+
+void MyMtpDatabase::sessionEnded() {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->CallVoidMethod(mDatabase, method_sessionEnded);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
 }
 
 #endif // HAVE_ANDROID_OS
@@ -676,6 +891,21 @@
         LOGE("Can't find getObjectProperty");
         return -1;
     }
+    method_setObjectProperty = env->GetMethodID(clazz, "setObjectProperty", "(IIJLjava/lang/String;)I");
+    if (method_setObjectProperty == NULL) {
+        LOGE("Can't find setObjectProperty");
+        return -1;
+    }
+    method_getDeviceProperty = env->GetMethodID(clazz, "getDeviceProperty", "(I[J[C)I");
+    if (method_getDeviceProperty == NULL) {
+        LOGE("Can't find getDeviceProperty");
+        return -1;
+    }
+    method_setDeviceProperty = env->GetMethodID(clazz, "setDeviceProperty", "(IJLjava/lang/String;)I");
+    if (method_setDeviceProperty == NULL) {
+        LOGE("Can't find setDeviceProperty");
+        return -1;
+    }
     method_getObjectInfo = env->GetMethodID(clazz, "getObjectInfo", "(I[I[C[J)Z");
     if (method_getObjectInfo == NULL) {
         LOGE("Can't find getObjectInfo");
@@ -701,6 +931,17 @@
         LOGE("Can't find setObjectReferences");
         return -1;
     }
+    method_sessionStarted = env->GetMethodID(clazz, "sessionStarted", "()V");
+    if (method_sessionStarted == NULL) {
+        LOGE("Can't find sessionStarted");
+        return -1;
+    }
+    method_sessionEnded = env->GetMethodID(clazz, "sessionEnded", "()V");
+    if (method_sessionEnded == NULL) {
+        LOGE("Can't find sessionEnded");
+        return -1;
+    }
+
     field_context = env->GetFieldID(clazz, "mNativeContext", "I");
     if (field_context == NULL) {
         LOGE("Can't find MtpDatabase.mNativeContext");
diff --git a/media/jni/android_media_MtpServer.cpp b/media/jni/android_media_MtpServer.cpp
index 3305136..4567965 100644
--- a/media/jni/android_media_MtpServer.cpp
+++ b/media/jni/android_media_MtpServer.cpp
@@ -22,8 +22,13 @@
 #include <limits.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
 #include <utils/threads.h>
 
+#ifdef HAVE_ANDROID_OS
+#include <linux/usb/f_mtp.h>
+#endif
+
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
@@ -56,34 +61,54 @@
     MtpServer*      mServer;
     String8         mStoragePath;
     jobject         mJavaServer;
+    int             mFd;
 
 public:
     MtpThread(MtpDatabase* database, const char* storagePath, jobject javaServer)
-        : mDatabase(database),
+        :   mDatabase(database),
             mServer(NULL),
             mStoragePath(storagePath),
-            mJavaServer(javaServer)
+            mJavaServer(javaServer),
+            mFd(-1)
     {
     }
 
+    void setPtpMode(bool usePtp) {
+        sMutex.lock();
+        if (mFd >= 0) {
+            ioctl(mFd, MTP_SET_INTERFACE_MODE,
+                    (usePtp ? MTP_INTERFACE_MODE_PTP : MTP_INTERFACE_MODE_MTP));
+        } else {
+            int fd = open("/dev/mtp_usb", O_RDWR);
+            if (fd >= 0) {
+                ioctl(fd, MTP_SET_INTERFACE_MODE,
+                        (usePtp ? MTP_INTERFACE_MODE_PTP : MTP_INTERFACE_MODE_MTP));
+                close(fd);
+            }
+        }
+        sMutex.unlock();
+    }
+
     virtual bool threadLoop() {
-        int fd = open("/dev/mtp_usb", O_RDWR);
-        printf("open returned %d\n", fd);
-        if (fd < 0) {
+        sMutex.lock();
+        mFd = open("/dev/mtp_usb", O_RDWR);
+        printf("open returned %d\n", mFd);
+        if (mFd < 0) {
             LOGE("could not open MTP driver\n");
+            sMutex.unlock();
             return false;
         }
 
-        sMutex.lock();
-        mServer = new MtpServer(fd, mDatabase, AID_SDCARD_RW, 0664, 0775);
+        mServer = new MtpServer(mFd, mDatabase, AID_SDCARD_RW, 0664, 0775);
         mServer->addStorage(mStoragePath);
         sMutex.unlock();
 
         LOGD("MtpThread mServer->run");
         mServer->run();
-        close(fd);
 
         sMutex.lock();
+        close(mFd);
+        mFd = -1;
         delete mServer;
         mServer = NULL;
 
@@ -184,6 +209,17 @@
 #endif
 }
 
+static void
+android_media_MtpServer_set_ptp_mode(JNIEnv *env, jobject thiz, jboolean usePtp)
+{
+#ifdef HAVE_ANDROID_OS
+    LOGD("set_ptp_mode\n");
+    MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
+    if (thread)
+        thread->setPtpMode(usePtp);
+ #endif
+}
+
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gMethods[] = {
@@ -194,6 +230,7 @@
     {"native_stop",                 "()V",  (void *)android_media_MtpServer_stop},
     {"native_send_object_added",    "(I)V", (void *)android_media_MtpServer_send_object_added},
     {"native_send_object_removed",  "(I)V", (void *)android_media_MtpServer_send_object_removed},
+    {"native_set_ptp_mode",         "(Z)V", (void *)android_media_MtpServer_set_ptp_mode},
 };
 
 static const char* const kClassPathName = "android/media/MtpServer";
diff --git a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
old mode 100755
new mode 100644
index 48731df..228977d
--- a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
+++ b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1081 $
-     $Date: 2010-07-05 11:48:44 +0200 (Mon, 05 Jul 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*    Header file for the application layer interface of Dynamic Bass Enhancement       */
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
old mode 100755
new mode 100644
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
old mode 100755
new mode 100644
index 4a9dc72..ab2a832
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Control.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: beq06068 $
-     $Revision: 1401 $
-     $Date: 2010-08-03 09:52:22 +0200 (Tue, 03 Aug 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*    Includes                                                                          */
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
old mode 100755
new mode 100644
index 95c421d..3b3c07c
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: beq06068 $
-     $Revision: 1399 $
-     $Date: 2010-08-03 08:16:00 +0200 (Tue, 03 Aug 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*    Includes                                                                          */
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
old mode 100755
new mode 100644
index df32873..495b38f
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Private.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: beq06068 $
-     $Revision: 1399 $
-     $Date: 2010-08-03 08:16:00 +0200 (Tue, 03 Aug 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*    Header file for the private layer interface of Dynamic Bass Enhancement module    */
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
old mode 100755
new mode 100644
index 04032c0..69d79d2
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: beq06068 $
-     $Revision: 1400 $
-     $Date: 2010-08-03 09:22:37 +0200 (Tue, 03 Aug 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*    Includes                                                                          */
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
old mode 100755
new mode 100644
index da8ca5a..f5d229e
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
@@ -14,13 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1009 $
-     $Date: 2010-06-28 14:14:15 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
 
 
 /************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h
old mode 100755
new mode 100644
index 4cb6d21..476e6a0
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1009 $
-     $Date: 2010-06-28 14:14:15 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 
 /************************************************************************************/
 /*                                                                                  */
diff --git a/media/libeffects/lvm/lib/Bundle/lib/LVM.h b/media/libeffects/lvm/lib/Bundle/lib/LVM.h
old mode 100755
new mode 100644
index d472182..1ff2a2c
--- a/media/libeffects/lvm/lib/Bundle/lib/LVM.h
+++ b/media/libeffects/lvm/lib/Bundle/lib/LVM.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/*****************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1002 $
-     $Date: 2010-06-28 13:40:09 +0200 (Mon, 28 Jun 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*  Header file for the application layer interface of Concert Sound, Bass Enhancement, */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_API_Specials.c b/media/libeffects/lvm/lib/Bundle/src/LVM_API_Specials.c
old mode 100755
new mode 100644
index 2f6fa4c..07b7f0e
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_API_Specials.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_API_Specials.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1002 $
-     $Date: 2010-06-28 13:40:09 +0200 (Mon, 28 Jun 2010) $
-
-*****************************************************************************************/
-
 
 /****************************************************************************************/
 /*                                                                                      */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
old mode 100755
new mode 100644
index 7273400..6cbee7d
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
@@ -16,14 +16,6 @@
  */
 
 
-/****************************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1316 $
-     $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                        */
 /*    Includes                                                                              */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
old mode 100755
new mode 100644
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
old mode 100755
new mode 100644
index cec7501..72564d4
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1331 $
-     $Date: 2010-07-27 12:26:23 +0200 (Tue, 27 Jul 2010) $
-
-*****************************************************************************************/
-
 
 /****************************************************************************************/
 /*                                                                                      */
@@ -201,7 +193,6 @@
     * the copy to NewParams then one frame may have mixed parameters, some old and some new.
     */
     pInstance->ControlPending = LVM_TRUE;
-    pInstance->NoSmoothVolume = LVM_FALSE;
 
     return(LVM_SUCCESS);
 }
@@ -830,6 +821,7 @@
     /*
      * Update the parameters and clear the flag
      */
+    pInstance->NoSmoothVolume = LVM_FALSE;
     pInstance->Params =  LocalParams;
 
 
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
old mode 100755
new mode 100644
index 323a2a3..20370b7
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1316 $
-     $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $
-
-*************************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /*  Includes                                                                        */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
old mode 100755
new mode 100644
index f70e473..2d1cf42
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Private.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1082 $
-     $Date: 2010-07-05 12:44:39 +0200 (Mon, 05 Jul 2010) $
-
-***********************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /*  Header file for the private layer interface of concert sound bundle             */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
old mode 100755
new mode 100644
index bad9450..794271b
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1002 $
-     $Date: 2010-06-28 13:40:09 +0200 (Mon, 28 Jun 2010) $
-
-*****************************************************************************************/
-
 
 /****************************************************************************************/
 /*                                                                                      */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
old mode 100755
new mode 100644
index cb33541..e14f909
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1002 $
-     $Date: 2010-06-28 13:40:09 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /*    Includes                                                                      */
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h
old mode 100755
new mode 100644
index 574f641..a7601ff
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1002 $
-     $Date: 2010-06-28 13:40:09 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 #ifndef __LVM_TABLES_H__
 #define __LVM_TABLES_H__
 
diff --git a/media/libeffects/lvm/lib/Common/lib/AGC.h b/media/libeffects/lvm/lib/Common/lib/AGC.h
old mode 100755
new mode 100644
index 980a8e3..2080d64
--- a/media/libeffects/lvm/lib/Common/lib/AGC.h
+++ b/media/libeffects/lvm/lib/Common/lib/AGC.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef __AGC_H__
 #define __AGC_H__
 
diff --git a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
old mode 100755
new mode 100644
index 08e5a6f..7ac7fbd
--- a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
+++ b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 722 $
-     $Date: 2010-06-10 15:12:34 +0200 (Thu, 10 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef _BIQUAD_H_
 #define _BIQUAD_H_
 
diff --git a/media/libeffects/lvm/lib/Common/lib/CompLim.h b/media/libeffects/lvm/lib/Common/lib/CompLim.h
old mode 100755
new mode 100644
index df9b583..4cb8aa2
--- a/media/libeffects/lvm/lib/Common/lib/CompLim.h
+++ b/media/libeffects/lvm/lib/Common/lib/CompLim.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: nxp27078 $
-     $Revision: 672 $
-     $Date: 2010-06-08 19:39:38 +0200 (Tue, 08 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef _COMP_LIM_H
 #define _COMP_LIM_H
 
diff --git a/media/libeffects/lvm/lib/Common/lib/Filter.h b/media/libeffects/lvm/lib/Common/lib/Filter.h
old mode 100755
new mode 100644
index 93ccbcb..229701a
--- a/media/libeffects/lvm/lib/Common/lib/Filter.h
+++ b/media/libeffects/lvm/lib/Common/lib/Filter.h
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 771 $*/
-/*     $Date: 2010-06-14 10:41:36 +0200 (Mon, 14 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #ifndef _FILTER_H_
 #define _FILTER_H_
 
diff --git a/media/libeffects/lvm/lib/Common/lib/InstAlloc.h b/media/libeffects/lvm/lib/Common/lib/InstAlloc.h
old mode 100755
new mode 100644
index 31409bf..c6954f2
--- a/media/libeffects/lvm/lib/Common/lib/InstAlloc.h
+++ b/media/libeffects/lvm/lib/Common/lib/InstAlloc.h
@@ -15,13 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #ifndef __INSTALLOC_H__
 #define __INSTALLOC_H__
 
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Common.h b/media/libeffects/lvm/lib/Common/lib/LVM_Common.h
old mode 100755
new mode 100644
index f0f893d..ceccd7b
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Common.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Common.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/*****************************************************************************************
-
-     $Author: nxp27078 $
-     $Revision: 672 $
-     $Date: 2010-06-08 19:39:38 +0200 (Tue, 08 Jun 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*  Header file for the common definitions used within the bundle and its algorithms.   */
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Macros.h b/media/libeffects/lvm/lib/Common/lib/LVM_Macros.h
old mode 100755
new mode 100644
index 8bd363d..97d13a5
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Macros.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Macros.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef _LVM_MACROS_H_
 #define _LVM_MACROS_H_
 
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Timer.h b/media/libeffects/lvm/lib/Common/lib/LVM_Timer.h
old mode 100755
new mode 100644
index 22a16d6..81e288c
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Timer.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Timer.h
@@ -17,14 +17,7 @@
 
 #ifndef __LVM_TIMER_H__
 #define __LVM_TIMER_H__
-/************************************************************************/
-/*                                                                      */
-/*     Project::   My Project                                           */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
+
 #include "LVM_Types.h"
 
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
old mode 100755
new mode 100644
index e4649ba..81655dd
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*  Header file defining the standard LifeVibes types for use in the application layer  */
diff --git a/media/libeffects/lvm/lib/Common/lib/Mixer.h b/media/libeffects/lvm/lib/Common/lib/Mixer.h
old mode 100755
new mode 100644
index d741980..89deb0d
--- a/media/libeffects/lvm/lib/Common/lib/Mixer.h
+++ b/media/libeffects/lvm/lib/Common/lib/Mixer.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef __MIXER_H__
 #define __MIXER_H__
 
diff --git a/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h b/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
old mode 100755
new mode 100644
index c66e201..3d62704
--- a/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #ifndef __SCALARARITHMETIC_H__
 #define __SCALARARITHMETIC_H__
 
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
old mode 100755
new mode 100644
index 290a996..2b791bd
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 853 $
-     $Date: 2010-06-16 15:10:28 +0200 (Wed, 16 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef _VECTOR_ARITHMETIC_H_
 #define _VECTOR_ARITHMETIC_H_
 
diff --git a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
old mode 100755
new mode 100644
index 40e0dbf..920b515
--- a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1070 $
-     $Date: 2010-07-02 11:22:18 +0200 (Fri, 02 Jul 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*    Includes                                                                          */
diff --git a/media/libeffects/lvm/lib/Common/src/Abs_32.c b/media/libeffects/lvm/lib/Common/src/Abs_32.c
old mode 100755
new mode 100644
index 635315d..9128b82
--- a/media/libeffects/lvm/lib/Common/src/Abs_32.c
+++ b/media/libeffects/lvm/lib/Common/src/Abs_32.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /*######################################################################################*/
 /*  Include files                                                                       */
 /*######################################################################################*/
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.c b/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.c
old mode 100755
new mode 100644
index 18026c5..6978fe7
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
old mode 100755
new mode 100644
index 96fc7e6..69d357e
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
+++ b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c
old mode 100755
new mode 100644
index 76d8e42..f4c5757
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BP_1I_D16F16Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index 9338eb2..88914ad
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.c
@@ -15,11 +15,6 @@
  * limitations under the License.
  */
 
-/*                                                                      */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
 /*-------------------------------------------------------------------------*/
 #include "BIQUAD.h"
 #include "BP_1I_D16F16Css_TRC_WRA_01_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index 2a0d7d5..980539c
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -16,14 +16,6 @@
  */
 #ifndef _BP_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 #define _BP_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c
old mode 100755
new mode 100644
index f52d3db..ba1a42f4
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BP_1I_D16F32Cll_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index c560085..e833218
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.c
@@ -15,11 +15,6 @@
  * limitations under the License.
  */
 
-/*                                                            */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                            */
 /*-------------------------------------------------------------------------*/
 #include "BIQUAD.h"
 #include "BP_1I_D16F32Cll_TRC_WRA_01_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index 76777f6e..9cca627
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
@@ -16,14 +16,6 @@
  */
 #ifndef _BP_1I_D16F32CLL_TRC_WRA_01_PRIVATE_H_
 #define _BP_1I_D16F32CLL_TRC_WRA_01_PRIVATE_H_
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c
old mode 100755
new mode 100644
index 2b3555f..b09c1aa
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BP_1I_D32F32Cll_TRC_WRA_02_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c
old mode 100755
new mode 100644
index f3f4571..9367912
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.c
@@ -15,11 +15,6 @@
  * limitations under the License.
  */
 
-/*                                                                      */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                         */
 /*-------------------------------------------------------------------------*/
 #include "BIQUAD.h"
 #include "BP_1I_D32F32Cll_TRC_WRA_02_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
old mode 100755
new mode 100644
index 8884537..5cc1ce2
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
@@ -16,14 +16,6 @@
  */
 #ifndef _BP_1I_D32F32CLL_TRC_WRA_02_PRIVATE_H_
 #define _BP_1I_D32F32CLL_TRC_WRA_02_PRIVATE_H_
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c
old mode 100755
new mode 100644
index 00e3b52..f2f8c6b
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BQ_1I_D16F16Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index 3fedc45..baf0c1a
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.c
@@ -15,11 +15,6 @@
  * limitations under the License.
  */
 
-/*                                                                                                          */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                                                          */
 /*-------------------------------------------------------------------------*/
 #include "BIQUAD.h"
 #include "BQ_1I_D16F16Css_TRC_WRA_01_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index 18dacd3..909c699
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -16,14 +16,6 @@
  */
 #ifndef _BQ_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 #define _BQ_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c
old mode 100755
new mode 100644
index cdff1d9..92f6caf
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BQ_1I_D16F32Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index bc88847..aea10f0
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
@@ -16,14 +16,6 @@
  */
 #ifndef _BQ_1I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
 #define _BQ_1I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c
old mode 100755
new mode 100644
index 520c969..1d6be4e1
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.c
@@ -15,11 +15,6 @@
  * limitations under the License.
  */
 
-/*                                                                      */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
 /*-------------------------------------------------------------------------*/
 #include "BIQUAD.h"
 #include "BQ_1I_D16F32Css_TRC_WRA_01_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c
old mode 100755
new mode 100644
index c267a90..972e704
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BQ_2I_D16F16Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c
old mode 100755
new mode 100644
index ded2bb3..e056373
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BQ_2I_D16F16Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index b0cd1b9..0a8ac35
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.c
@@ -15,11 +15,6 @@
  * limitations under the License.
  */
 
-/*                                                                                                          */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                                                          */
 /*-------------------------------------------------------------------------*/
 #include "BIQUAD.h"
 #include "BQ_2I_D16F16Css_TRC_WRA_01_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index bcb0093..7d42ced
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
@@ -18,15 +18,6 @@
 #ifndef _BQ_2I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 #define _BQ_2I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
 typedef struct _Filter_State_
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c
old mode 100755
new mode 100644
index ae743f2..4a0cce4
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c
old mode 100755
new mode 100644
index a0ca2cc..052e2a0
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c
old mode 100755
new mode 100644
index f1ab815..8c741e1
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index 3cbb58b..4f0cf67
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
@@ -18,15 +18,6 @@
 #ifndef _BQ_2I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
 #define _BQ_2I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
 typedef struct _Filter_State_
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c
old mode 100755
new mode 100644
index 0c6b33e..4591ee0
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.c
@@ -15,12 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #include "BIQUAD.h"
 #include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
 
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
old mode 100755
new mode 100644
index 51278cf..fd8212e
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "BQ_2I_D32F32Cll_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index 7c460d3..1709f71
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.c
@@ -15,11 +15,6 @@
  * limitations under the License.
  */
 
-/*                                                                                                          */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                                                          */
 /*-------------------------------------------------------------------------*/
 #include "BIQUAD.h"
 #include "BQ_2I_D32F32Cll_TRC_WRA_01_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index fb4f2dd..747af6a5
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
@@ -19,15 +19,6 @@
 #define _BQ_2I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
 
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
 typedef struct _Filter_State_
diff --git a/media/libeffects/lvm/lib/Common/src/CompLim_private.h b/media/libeffects/lvm/lib/Common/src/CompLim_private.h
old mode 100755
new mode 100644
index 07a8833..06a21c3
--- a/media/libeffects/lvm/lib/Common/src/CompLim_private.h
+++ b/media/libeffects/lvm/lib/Common/src/CompLim_private.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef _COMP_LIM_PRIVATE_
 #define _COMP_LIM_PRIVATE_
 
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.c b/media/libeffects/lvm/lib/Common/src/Copy_16.c
old mode 100755
new mode 100644
index 6ee1ff6..20404ad
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.c
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c
old mode 100755
new mode 100644
index adac24f..bf69e35
--- a/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixHard_2St_D32C31_SAT.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c
old mode 100755
new mode 100644
index d557f6e..3471f05
--- a/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c b/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c
old mode 100755
new mode 100644
index 7b4e66db8..709c304
--- a/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixSoft_1St_D32C31_WRA.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
old mode 100755
new mode 100644
index 187fe68..49fa184
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "DC_2I_D16_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index 292641b..468a88d
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "DC_2I_D16_TRC_WRA_01_Private.h"
 
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index 2514a77..89a4e68
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Private.h
@@ -20,15 +20,6 @@
 
 #define DC_D16_STEP     0x200;
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.*/
diff --git a/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.c b/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.c
old mode 100755
new mode 100644
index cda72ac..2e20d79
--- a/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.c
+++ b/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c
old mode 100755
new mode 100644
index ee41701..7e3182d
--- a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/DelayWrite_32.c b/media/libeffects/lvm/lib/Common/src/DelayWrite_32.c
old mode 100755
new mode 100644
index 0ae4c42e..809cddc4
--- a/media/libeffects/lvm/lib/Common/src/DelayWrite_32.c
+++ b/media/libeffects/lvm/lib/Common/src/DelayWrite_32.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c
old mode 100755
new mode 100644
index 831a115..de77361
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "FO_1I_D16F16Css_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index 4675084..96252cc3
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.c
@@ -15,11 +15,6 @@
  * limitations under the License.
  */
 
-/*                                                                      */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
 /*-------------------------------------------------------------------------*/
 #include "BIQUAD.h"
 #include "FO_1I_D16F16Css_TRC_WRA_01_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index e1a818c4..516ca83
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -18,15 +18,6 @@
 #ifndef _FO_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 #define _FO_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $             */
-/*                                                                      */
-/************************************************************************/
-
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
 typedef struct _Filter_State_
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c
old mode 100755
new mode 100644
index 9bdc5b4..0f1d5bc
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "FO_1I_D32F32Cll_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index eea0b64..136e4f6
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "FO_1I_D32F32Cll_TRC_WRA_01_Private.h"
 
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index 9329150..94ad48c
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #ifndef _FO_1I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
 #define _FO_1I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
 
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
old mode 100755
new mode 100644
index 4b219a2..8388050
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index 7f212f5..a19c32c
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c
@@ -15,11 +15,6 @@
  * limitations under the License.
  */
 
-/*                                                                      */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
 /*-------------------------------------------------------------------------*/
 #include "BIQUAD.h"
 #include "FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index 6a4564a..4640743
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
@@ -18,15 +18,6 @@
 #ifndef _FO_2I_D16F32CSS_LSHX_TRC_WRA_01_PRIVATE_H_
 #define _FO_2I_D16F32CSS_LSHX_TRC_WRA_01_PRIVATE_H_
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
 typedef struct _Filter_State_
diff --git a/media/libeffects/lvm/lib/Common/src/Filters.h b/media/libeffects/lvm/lib/Common/src/Filters.h
old mode 100755
new mode 100644
index a274f32..4d32df1
--- a/media/libeffects/lvm/lib/Common/src/Filters.h
+++ b/media/libeffects/lvm/lib/Common/src/Filters.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1001 $
-     $Date: 2010-06-28 13:23:02 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 #ifndef FILTERS_H
 #define FILTERS_H
 
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c
old mode 100755
new mode 100644
index fb00768..7975e8b
--- a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_16.c b/media/libeffects/lvm/lib/Common/src/From2iToMono_16.c
old mode 100755
new mode 100644
index 0ebb4ae..b758ee7
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_16.c
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMono_16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
old mode 100755
new mode 100644
index 5181368..8bb292f
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/InstAlloc.c b/media/libeffects/lvm/lib/Common/src/InstAlloc.c
old mode 100755
new mode 100644
index ff900e0..481df84
--- a/media/libeffects/lvm/lib/Common/src/InstAlloc.c
+++ b/media/libeffects/lvm/lib/Common/src/InstAlloc.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "InstAlloc.h"
 
 /****************************************************************************************
diff --git a/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.c b/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.c
old mode 100755
new mode 100644
index e6be756..9f09e4d
--- a/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.c
+++ b/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.c b/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.c
old mode 100755
new mode 100644
index b21eef5..8c9980d
--- a/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.c
+++ b/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c
old mode 100755
new mode 100644
index e04f1c3..9b938bd
--- a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c
+++ b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
old mode 100755
new mode 100644
index c1d2b2c..3d39b93
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c
old mode 100755
new mode 100644
index 2bb212c..2daf74a
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
old mode 100755
new mode 100644
index 0408f42..caa0951
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
old mode 100755
new mode 100644
index 2847d47..09ec427
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
old mode 100755
new mode 100644
index 78f0122..f1a9ca3
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
old mode 100755
new mode 100644
index 52be129..0052dd7
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixInSoft_D16C31_SAT.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
old mode 100755
new mode 100644
index d832e06..f443c8f
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
old mode 100755
new mode 100644
index cfb1239..c8dcad7
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_D16C31_SAT.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
old mode 100755
new mode 100644
index 6184736..7240705
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_2St_D16C31_SAT.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
old mode 100755
new mode 100644
index 3b32e21..980c783
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef __LVC_MIXER_H__
 #define __LVC_MIXER_H__
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c
old mode 100755
new mode 100644
index 09658ba..b5ae264
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetCurrent.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 839 $*/
-/*     $Date: 2010-06-16 14:15:52 +0200 (Wed, 16 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "LVC_Mixer_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
old mode 100755
new mode 100644
index ed2cf94..dc2f8e9
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_GetTarget.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 839 $*/
-/*     $Date: 2010-06-16 14:15:52 +0200 (Wed, 16 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "LVC_Mixer_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c
old mode 100755
new mode 100644
index c61e468..449e7b1
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Init.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "LVC_Mixer_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
old mode 100755
new mode 100644
index d61d670..294e05c
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef __LVC_MIXER_PRIVATE_H__
 #define __LVC_MIXER_PRIVATE_H__
 
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c
old mode 100755
new mode 100644
index 4d3fe0c..5efa501
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTarget.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "LVC_Mixer_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
old mode 100755
new mode 100644
index df0fd37..4c1c8b2
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_SetTimeConstant.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "LVC_Mixer_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
old mode 100755
new mode 100644
index 420af9a..8d5304e
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_VarSlope_SetTimeConstant.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "LVC_Mixer_Private.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c b/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c
old mode 100755
new mode 100644
index 37c199e..6d8fe46
--- a/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_FO_HPF.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: nxp27078 $*/
-/*     $Revision: 762 $*/
-/*     $Date: 2010-06-11 14:50:33 +0200 (vr, 11 jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "ScalarArithmetic.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c b/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c
old mode 100755
new mode 100644
index 6c73d59..86ec951
--- a/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_FO_LPF.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: nxp27078 $*/
-/*     $Revision: 762 $*/
-/*     $Date: 2010-06-11 14:50:33 +0200 (vr, 11 jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "ScalarArithmetic.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c b/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
old mode 100755
new mode 100644
index 1cc10db..f3b9b3c
--- a/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_GetOmega.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: nxp27078 $*/
-/*     $Revision: 762 $*/
-/*     $Date: 2010-06-11 14:50:33 +0200 (vr, 11 jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "Filter.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h
old mode 100755
new mode 100644
index 00235e0d..6846d49
--- a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_FilterCoeffs.h
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /* Mixer library tables                                                             */
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c
old mode 100755
new mode 100644
index db6975a..809d904
--- a/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Mixer_TimeConstant.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "Mixer.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c b/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c
old mode 100755
new mode 100644
index b8cf4b4..a6d7db2
--- a/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Polynomial.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "ScalarArithmetic.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Power10.c b/media/libeffects/lvm/lib/Common/src/LVM_Power10.c
old mode 100755
new mode 100644
index 9a3f632..6ca1077
--- a/media/libeffects/lvm/lib/Common/src/LVM_Power10.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Power10.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "LVM_Types.h"
 #include "LVM_Macros.h"
 #include "ScalarArithmetic.h"
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Timer.c b/media/libeffects/lvm/lib/Common/src/LVM_Timer.c
old mode 100755
new mode 100644
index d49aadc..5995f54
--- a/media/libeffects/lvm/lib/Common/src/LVM_Timer.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Timer.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   My Project                                           */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /****************************************************************************************/
 /*  INCLUDE FILES                                                                       */
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Timer_Init.c b/media/libeffects/lvm/lib/Common/src/LVM_Timer_Init.c
old mode 100755
new mode 100644
index e473038..a935cfe
--- a/media/libeffects/lvm/lib/Common/src/LVM_Timer_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Timer_Init.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   My Project                                           */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /****************************************************************************************/
 /*  INCLUDE FILES                                                                       */
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVM_Timer_Private.h b/media/libeffects/lvm/lib/Common/src/LVM_Timer_Private.h
old mode 100755
new mode 100644
index 04d5af6..480944f
--- a/media/libeffects/lvm/lib/Common/src/LVM_Timer_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/LVM_Timer_Private.h
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   My Project                                           */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #ifndef LVM_TIMER_PRIVATE_H
 #define LVM_TIMER_PRIVATE_H
 
diff --git a/media/libeffects/lvm/lib/Common/src/LoadConst_16.c b/media/libeffects/lvm/lib/Common/src/LoadConst_16.c
old mode 100755
new mode 100644
index bc2735f..f88ca0e
--- a/media/libeffects/lvm/lib/Common/src/LoadConst_16.c
+++ b/media/libeffects/lvm/lib/Common/src/LoadConst_16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/LoadConst_32.c b/media/libeffects/lvm/lib/Common/src/LoadConst_32.c
old mode 100755
new mode 100644
index 19d5d4e..2f1e591
--- a/media/libeffects/lvm/lib/Common/src/LoadConst_32.c
+++ b/media/libeffects/lvm/lib/Common/src/LoadConst_32.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c
old mode 100755
new mode 100644
index 1949f3c..26297e7
--- a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.c b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.c
old mode 100755
new mode 100644
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
old mode 100755
new mode 100644
index 746a273..f28f366
--- a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
+++ b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c
old mode 100755
new mode 100644
index 36de6c1..73c26ed
--- a/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/MixInSoft_D32C31_SAT.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c b/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c
old mode 100755
new mode 100644
index 5cf1a29..ca88b04
--- a/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c
+++ b/media/libeffects/lvm/lib/Common/src/MixSoft_1St_D32C31_WRA.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c b/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c
old mode 100755
new mode 100644
index 83f95ac..2e0a099
--- a/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c
+++ b/media/libeffects/lvm/lib/Common/src/MixSoft_2St_D32C31_SAT.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: nxp007753 $*/
-/*     $Revision: 1316 $*/
-/*     $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mixer_private.h b/media/libeffects/lvm/lib/Common/src/Mixer_private.h
old mode 100755
new mode 100644
index d012548..607073c
--- a/media/libeffects/lvm/lib/Common/src/Mixer_private.h
+++ b/media/libeffects/lvm/lib/Common/src/Mixer_private.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef __MIXER_PRIVATE_H__
 #define __MIXER_PRIVATE_H__
 
diff --git a/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.c b/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.c
old mode 100755
new mode 100644
index b053e556..ead798d
--- a/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.c
+++ b/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c
old mode 100755
new mode 100644
index e8164bb..c09ec0f
--- a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c
+++ b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c
old mode 100755
new mode 100644
index ee83524..a5dc50f
--- a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c
+++ b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c
old mode 100755
new mode 100644
index 1428777..73343cd
--- a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c
+++ b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*    Includes                                                                          */
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
old mode 100755
new mode 100644
index 06cfe88..c8c1527
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "PK_2I_D32F32CssGss_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c
old mode 100755
new mode 100644
index 5b78f62..67a570b
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C30G11_TRC_WRA_01.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "PK_2I_D32F32CllGss_TRC_WRA_01_Private.h"
 #include "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index e7bcd0c..1d6142c
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "PK_2I_D32F32CllGss_TRC_WRA_01_Private.h"
 
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index 741f504..c5f9c7c
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h
@@ -18,15 +18,6 @@
 #ifndef _PK_2I_D32F32CLLGSS_TRC_WRA_01_PRIVATE_H_
 #define _PK_2I_D32F32CLLGSS_TRC_WRA_01_PRIVATE_H_
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
 typedef struct _Filter_State_
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c
old mode 100755
new mode 100644
index f02305e..b9f64e6
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 #include "BIQUAD.h"
 #include "PK_2I_D32F32CssGss_TRC_WRA_01_Private.h"
 
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
old mode 100755
new mode 100644
index ca31669..e2050e0
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
@@ -18,15 +18,6 @@
 #ifndef _PK_2I_D32F32CSSGSS_TRC_WRA_01_PRIVATE_H_
 #define _PK_2I_D32F32CSSGSS_TRC_WRA_01_PRIVATE_H_
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 
 /* The internal state variables are implemented in a (for the user)  hidden structure */
 /* In this (private) file, the internal structure is declared fro private use.        */
diff --git a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c
old mode 100755
new mode 100644
index e449a7f..8363270
--- a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c
+++ b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v16xv16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c
old mode 100755
new mode 100644
index 0ab98ea..fbd132e
--- a/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c
+++ b/media/libeffects/lvm/lib/Common/src/Shift_Sat_v32xv32.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1000 $*/
-/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/dB_to_Lin32.c b/media/libeffects/lvm/lib/Common/src/dB_to_Lin32.c
old mode 100755
new mode 100644
diff --git a/media/libeffects/lvm/lib/Common/src/mult3s_16x16.c b/media/libeffects/lvm/lib/Common/src/mult3s_16x16.c
old mode 100755
new mode 100644
index b500979..4092560
--- a/media/libeffects/lvm/lib/Common/src/mult3s_16x16.c
+++ b/media/libeffects/lvm/lib/Common/src/mult3s_16x16.c
@@ -16,14 +16,6 @@
  */
 
 /**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1000 $
-     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
-/**********************************************************************************
    INCLUDE FILES
 ***********************************************************************************/
 
diff --git a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
old mode 100755
new mode 100644
index 7ba583f..db6aabe
--- a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
+++ b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1005 $
-     $Date: 2010-06-28 13:58:28 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*  Header file for the application layer interface of the N-Band equaliser.            */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c
old mode 100755
new mode 100644
index 4881049..fddedb9
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_CalcCoef.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1005 $
-     $Date: 2010-06-28 13:58:28 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*    Includes                                                                          */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
old mode 100755
new mode 100644
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c
old mode 100755
new mode 100644
index dac2449..10e7d74
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1316 $
-     $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $
-
-***********************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*  Includes                                                                            */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
old mode 100755
new mode 100644
index a29fe05..e83e515
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1005 $
-     $Date: 2010-06-28 13:58:28 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 
 /****************************************************************************************/
 /*                                                                                      */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
old mode 100755
new mode 100644
index 0ae84af..9df980c
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1005 $
-     $Date: 2010-06-28 13:58:28 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 #ifndef __LVEQNB_PRIVATE_H__
 #define __LVEQNB_PRIVATE_H__
 
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
old mode 100755
new mode 100644
index e29e881..ac3c740
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/**********************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1005 $
-     $Date: 2010-06-28 13:58:28 +0200 (Mon, 28 Jun 2010) $
-
-***********************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*  Includes                                                                            */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
old mode 100755
new mode 100644
index 33c07da..8e2e0e8
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1005 $
-     $Date: 2010-06-28 13:58:28 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 
 /************************************************************************************/
 /*                                                                                  */
diff --git a/media/libeffects/lvm/lib/Reverb/lib/LVREV.h b/media/libeffects/lvm/lib/Reverb/lib/LVREV.h
old mode 100755
new mode 100644
index 4c32db0..28e3369
--- a/media/libeffects/lvm/lib/Reverb/lib/LVREV.h
+++ b/media/libeffects/lvm/lib/Reverb/lib/LVREV.h
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::                                                        */
-/*     $Author: beq03888 $*/
-/*     $Revision: 1204 $*/
-/*     $Date: 2010-07-14 08:55:43 +0200 (Wed, 14 Jul 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*  Header file for the application layer interface of the LVREV module                 */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c
old mode 100755
new mode 100644
index 0026652..6a8b39b
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.c
@@ -17,15 +17,6 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/*     Project::                                                                        */
-/*     $Author: nxp007753 $ */
-/*     $Revision: 1316 $ */
-/*     $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $ */
-/*                                                                                      */
-/****************************************************************************************/
-
-/****************************************************************************************/
-/*                                                                                      */
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c
old mode 100755
new mode 100644
index b02b1a7..6bb1e88
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.c
@@ -17,15 +17,6 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/*     Project::                                                                        */
-/*     $Author: nxp007753 $ */
-/*     $Revision: 1316 $ */
-/*     $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $ */
-/*                                                                                      */
-/****************************************************************************************/
-
-/****************************************************************************************/
-/*                                                                                      */
 /* Includes                                                                             */
 /*                                                                                      */
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetControlParameters.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetControlParameters.c
old mode 100755
new mode 100644
index ebf145e..7cee26d
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetControlParameters.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetControlParameters.c
@@ -17,15 +17,6 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/*     Project::                                                                        */
-/*     $Author: nxp27078 $*/
-/*     $Revision: 762 $*/
-/*     $Date: 2010-06-11 14:50:33 +0200 (Fri, 11 Jun 2010) $*/
-/*                                                                                      */
-/****************************************************************************************/
-
-/****************************************************************************************/
-/*                                                                                      */
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c
old mode 100755
new mode 100644
index ca1c84d..c2b266a
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.c
@@ -17,15 +17,6 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/*     Project::                                                                        */
-/*     $Author: nxp007753 $ */
-/*     $Revision: 1316 $ */
-/*     $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $ */
-/*                                                                                      */
-/****************************************************************************************/
-
-/****************************************************************************************/
-/*                                                                                      */
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c
old mode 100755
new mode 100644
index e16a3d3..2012432
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.c
@@ -17,15 +17,6 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/*     Project::                                                                        */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1007 $*/
-/*     $Date: 2010-06-28 14:06:36 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                                      */
-/****************************************************************************************/
-
-/****************************************************************************************/
-/*                                                                                      */
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
old mode 100755
new mode 100644
index 896b051..fbfa437
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************/
-/*                                                                                      */
-/*     Project::                                                                        */
-/*     $Author: nxp007753 $ */
-/*     $Revision: 1316 $ */
-/*     $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $ */
-/*                                                                                      */
-/****************************************************************************************/
-
 #ifndef __LVREV_PRIVATE_H__
 #define __LVREV_PRIVATE_H__
 
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
old mode 100755
new mode 100644
index 822ac8f..81521ba
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.c
@@ -17,15 +17,6 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/*     Project::                                                                        */
-/*     $Author: nxp007753 $ */
-/*     $Revision: 1316 $ */
-/*     $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $ */
-/*                                                                                      */
-/****************************************************************************************/
-
-/****************************************************************************************/
-/*                                                                                      */
 /* Includes                                                                             */
 /*                                                                                      */
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
old mode 100755
new mode 100644
index 124fd3b..f5895a7
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
@@ -17,15 +17,6 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/*     Project::                                                                        */
-/*     $Author: nxp007753 $ */
-/*     $Revision: 1316 $ */
-/*     $Date: 2010-07-23 11:53:24 +0200 (Fri, 23 Jul 2010) $ */
-/*                                                                                      */
-/****************************************************************************************/
-
-/****************************************************************************************/
-/*                                                                                      */
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
old mode 100755
new mode 100644
index 9249a31..5a6d43d
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
@@ -17,15 +17,6 @@
 
 /****************************************************************************************/
 /*                                                                                      */
-/*     Project::                                                                        */
-/*     $Author: beq07716 $ */
-/*     $Revision: 1011 $ */
-/*     $Date: 2010-06-28 15:07:08 +0200 (Mon, 28 Jun 2010) $ */
-/*                                                                                      */
-/****************************************************************************************/
-
-/****************************************************************************************/
-/*                                                                                      */
 /*  Includes                                                                            */
 /*                                                                                      */
 /****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
old mode 100755
new mode 100644
index 98471be..5f993bd
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************/
-/*                                                                                      */
-/*     Project::                                                                        */
-/*     $Author: beq07716 $ */
-/*     $Revision: 773 $ */
-/*     $Date: 2010-06-14 10:43:54 +0200 (Mon, 14 Jun 2010) $ */
-/*                                                                                      */
-/****************************************************************************************/
-
 
 #ifndef _LVREV_TABLES_H_
 #define _LVREV_TABLES_H_
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
old mode 100755
new mode 100644
index b9903b2..a675cb2
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/lib/LVPSA.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   PSA_01_ARMC_01                                       */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1006 $*/
-/*     $Date: 2010-06-28 14:01:47 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #ifndef _LVPSA_H_
 #define _LVPSA_H_
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c
old mode 100755
new mode 100644
index 1be8ff0..cd5f69c
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   PSA_01_ARMC_01                                       */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1006 $*/
-/*     $Date: 2010-06-28 14:01:47 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #include    "LVPSA.h"
 #include    "LVPSA_Private.h"
 #include    "VectorArithmetic.h"
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c
old mode 100755
new mode 100644
index ab45678..27a4bc3
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   PSA_01_ARMC_01                                       */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1006 $*/
-/*     $Date: 2010-06-28 14:01:47 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #include    "LVPSA.h"
 #include    "LVPSA_Private.h"
 #include    "InstAlloc.h"
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c
old mode 100755
new mode 100644
index 059cb4e..0984b10
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Memory.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   PSA_01_ARMC_01                                       */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1006 $*/
-/*     $Date: 2010-06-28 14:01:47 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #include    "LVPSA.h"
 #include    "LVPSA_Private.h"
 #include    "InstAlloc.h"
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
old mode 100755
new mode 100644
index eb9fa8f..1d8bedd
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   PSA_01_ARMC_01                                       */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1006 $*/
-/*     $Date: 2010-06-28 14:01:47 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #ifndef _LVPSA_PRIVATE_H_
 #define _LVPSA_PRIVATE_H_
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
old mode 100755
new mode 100644
index d88a751..9e29f68
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   PSA_01_ARMC_01                                       */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1006 $*/
-/*     $Date: 2010-06-28 14:01:47 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #include    "LVPSA.h"
 #include    "LVPSA_Private.h"
 #include    "LVM_Macros.h"
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h
old mode 100755
new mode 100644
index 641357e..836bfd7
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   PSA_01_ARMC_01                                       */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1006 $*/
-/*     $Date: 2010-06-28 14:01:47 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #ifndef _LVPSA_QPD_H_
 #define _LVPSA_QPD_H_
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c
old mode 100755
new mode 100644
index 37abe40..50e0a80
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Init.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   PSA_01_ARMC_01                                       */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1006 $*/
-/*     $Date: 2010-06-28 14:01:47 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #include "LVPSA_QPD.h"
 
 /************************************************************************************/
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c
old mode 100755
new mode 100644
index 7087475..67197c1
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_QPD_Process.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   PSA_01_ARMC_01                                       */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1006 $*/
-/*     $Date: 2010-06-28 14:01:47 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
 #include "LVPSA_QPD.h"
 #include "LVPSA_Private.h"
 
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
old mode 100755
new mode 100644
index f4a35c5..21a5d8d
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
@@ -15,15 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************/
-/*                                                                      */
-/*     Project::   PSA_01_ARMC_01                                       */
-/*     $Author: beq07716 $*/
-/*     $Revision: 1006 $*/
-/*     $Date: 2010-06-28 14:01:47 +0200 (Mon, 28 Jun 2010) $*/
-/*                                                                      */
-/************************************************************************/
-
 
 /************************************************************************************/
 /*                                                                                  */
diff --git a/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h b/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
old mode 100755
new mode 100644
index 1ab45cc..0d62274
--- a/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
+++ b/media/libeffects/lvm/lib/StereoWidening/lib/LVCS.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/****************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1001 $
-     $Date: 2010-06-28 13:23:02 +0200 (Mon, 28 Jun 2010) $
-
-*****************************************************************************************/
-
 /****************************************************************************************/
 /*                                                                                      */
 /*  Header file for the application layer interface of Concert Sound and Concert        */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c
old mode 100755
new mode 100644
index b1d9408..3e48c7e
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq06068 $
-     $Revision: 1307 $
-     $Date: 2010-07-22 17:41:25 +0200 (Thu, 22 Jul 2010) $
-
-*************************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /*  Includes                                                                        */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h
old mode 100755
new mode 100644
index 79dff41..d1ef70a
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_BypassMix.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1001 $
-     $Date: 2010-06-28 13:23:02 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 #ifndef __LVCS_BYPASSMIX_H__
 #define __LVCS_BYPASSMIX_H__
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c
old mode 100755
new mode 100644
index 668b151..a3ba42b
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Control.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1331 $
-     $Date: 2010-07-27 12:26:23 +0200 (Tue, 27 Jul 2010) $
-
-*************************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /*  Includes                                                                        */
@@ -127,6 +119,8 @@
 
         pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset];
 
+        pInstance->CompressGain = pInstance->VolCorrect.CompMin;
+
         LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],0,0);
 
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c
old mode 100755
new mode 100644
index d8023d64..25b0d86
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1331 $
-     $Date: 2010-07-27 12:26:23 +0200 (Tue, 27 Jul 2010) $
-
-*************************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /*  Includes                                                                        */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
old mode 100755
new mode 100644
index 10b02cc..cf96f5b
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1001 $
-     $Date: 2010-06-28 13:23:02 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 #ifndef __LVCS_EQUALISER_H__
 #define __LVCS_EQUALISER_H__
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
old mode 100755
new mode 100644
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c
old mode 100755
new mode 100644
index 82a8db2..1904e46
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Init.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1331 $
-     $Date: 2010-07-27 12:26:23 +0200 (Tue, 27 Jul 2010) $
-
-*************************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /*  Includes                                                                        */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
old mode 100755
new mode 100644
index a977690..f3adb8d
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq06068 $
-     $Revision: 1307 $
-     $Date: 2010-07-22 17:41:25 +0200 (Thu, 22 Jul 2010) $
-
-*************************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /*  Header file for the private layer interface of concert sound.                   */
@@ -65,6 +57,7 @@
 #define LVCS_REVERBSWITCH           0x0002      /* Reverberation enable control */
 #define LVCS_EQUALISERSWITCH        0x0004      /* Equaliser enable control */
 #define LVCS_BYPASSMIXSWITCH        0x0008      /* Bypass mixer enable control */
+#define LVCS_COMPGAINFRAME          64          /* Compressor gain update interval */
 
 /* Memory */
 #define LVCS_SCRATCHBUFFERS              6      /* Number of buffers required for inplace processing */
@@ -120,6 +113,7 @@
     LVCS_OutputDevice_en    OutputDevice;       /* Selected output device type */
     LVCS_VolCorrect_t       VolCorrect;         /* Volume correction settings */
     LVM_INT16               TransitionGain;     /* Transition gain */
+    LVM_INT16               CompressGain;       /* Last used compressor gain*/
 
     /* Sub-block configurations */
     LVCS_StereoEnhancer_t   StereoEnhancer;     /* Stereo enhancer configuration */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
old mode 100755
new mode 100644
index 999b8bb..5d99461
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1001 $
-     $Date: 2010-06-28 13:23:02 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 
 /************************************************************************************/
 /*                                                                                  */
@@ -213,10 +205,80 @@
                                - (((LVM_INT32)pInstance->VolCorrect.CompMin  * (Current1)) >> 15)
                                + (((LVM_INT32)pInstance->VolCorrect.CompFull * (Current1)) >> 15) );
 
-            NonLinComp_D16(Gain,                    /* Compressor gain setting */
-                           pOutData,
-                           pOutData,
-                           (LVM_INT32)(2*NumSamples));
+            if(NumSamples < LVCS_COMPGAINFRAME)
+            {
+                NonLinComp_D16(Gain,                    /* Compressor gain setting */
+                    pOutData,
+                    pOutData,
+                    (LVM_INT32)(2*NumSamples));
+            }
+            else
+            {
+                LVM_INT16  GainStep;
+                LVM_INT16  FinalGain;
+                LVM_INT16  SampleToProcess = NumSamples;
+                LVM_INT16  *pOutPtr;
+
+                /* Large changes in Gain can cause clicks in output
+                   Split data into small blocks and use interpolated gain values */
+
+                GainStep = (LVM_INT16)(((Gain-pInstance->CompressGain) * LVCS_COMPGAINFRAME)/NumSamples);
+
+                if((GainStep ==0)&&(pInstance->CompressGain < Gain))
+                {
+                    GainStep=1;
+                }
+                else
+                {
+                    if((GainStep ==0)&&(pInstance->CompressGain > Gain))
+                    {
+                        GainStep=-1;
+                    }
+                }
+
+                FinalGain = Gain;
+                Gain = pInstance->CompressGain;
+                pOutPtr = pOutData;
+
+                while(SampleToProcess > 0)
+                {
+                    Gain = (LVM_INT16)(Gain + GainStep);
+                    if((GainStep > 0)&& (FinalGain <= Gain))
+                    {
+                        Gain = FinalGain;
+                        GainStep =0;
+                    }
+
+                    if((GainStep < 0)&& (FinalGain > Gain))
+                    {
+                        Gain = FinalGain;
+                        GainStep =0;
+                    }
+
+                    if(SampleToProcess > LVCS_COMPGAINFRAME)
+                    {
+                        NonLinComp_D16(Gain,                    /* Compressor gain setting */
+                            pOutPtr,
+                            pOutPtr,
+                            (LVM_INT32)(2*LVCS_COMPGAINFRAME));
+                        pOutPtr +=(2*LVCS_COMPGAINFRAME);
+                        SampleToProcess = (LVM_INT16)(SampleToProcess-LVCS_COMPGAINFRAME);
+                    }
+                    else
+                    {
+                        NonLinComp_D16(Gain,                    /* Compressor gain setting */
+                            pOutPtr,
+                            pOutPtr,
+                            (LVM_INT32)(2*SampleToProcess));
+
+                        SampleToProcess = 0;
+                    }
+
+                }
+            }
+
+            /* Store gain value*/
+            pInstance->CompressGain = Gain;
         }
 
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c
old mode 100755
new mode 100644
index 861bde6..ee257b8
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1315 $
-     $Date: 2010-07-23 11:52:08 +0200 (Fri, 23 Jul 2010) $
-
-*************************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /*  Includes                                                                        */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
old mode 100755
new mode 100644
index 1164bce..6e026ff
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1001 $
-     $Date: 2010-06-28 13:23:02 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 #ifndef __LVCS_REVERBGENERATOR_H__
 #define __LVCS_REVERBGENERATOR_H__
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c
old mode 100755
new mode 100644
index 83748e6..b9b8b05
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: nxp007753 $
-     $Revision: 1331 $
-     $Date: 2010-07-27 12:26:23 +0200 (Tue, 27 Jul 2010) $
-
-*************************************************************************************/
-
 /************************************************************************************/
 /*                                                                                  */
 /*  Includes                                                                        */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
old mode 100755
new mode 100644
index c3f6296..15bc407
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1001 $
-     $Date: 2010-06-28 13:23:02 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 #ifndef __LVCS_STEREOENHANCER_H__
 #define __LVCS_STEREOENHANCER_H__
 
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
old mode 100755
new mode 100644
index ad4eb1e..974de21
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
@@ -15,14 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: beq07716 $
-     $Revision: 1001 $
-     $Date: 2010-06-28 13:23:02 +0200 (Mon, 28 Jun 2010) $
-
-*************************************************************************************/
-
 
 /************************************************************************************/
 /*                                                                                  */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.h
old mode 100755
new mode 100644
index 72d6855..3f6c4c8
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.h
@@ -15,13 +15,6 @@
  * limitations under the License.
  */
 
-/************************************************************************************
-
-     $Author: nxp27078 $
-     $Revision: 672 $
-     $Date: 2010-06-08 19:39:38 +0200 (Tue, 08 Jun 2010) $
-
-*************************************************************************************/
 #ifndef __LVCS_TABLES_H__
 #define __LVCS_TABLES_H__
 
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index d856eb4..7297811 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -26,9 +26,6 @@
 #include <new>
 #include <EffectBundle.h>
 
-#define LVM_MAX_SESSIONS        32
-#define MAX_NUM_BANDS           5
-#define MAX_CALL_SIZE           256
 
 // effect_interface_t interface implementation for bass boost
 extern "C" const struct effect_interface_s gLvmEffectInterface;
@@ -77,8 +74,8 @@
         EFFECT_API_VERSION,
         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND
         | EFFECT_FLAG_VOLUME_CTRL),
-        0, // TODO
-        1,
+        BASS_BOOST_CUP_LOAD_ARM9E,
+        BUNDLE_MEM_USAGE,
         "Dynamic Bass Boost",
         "NXP Software Ltd.",
 };
@@ -90,8 +87,8 @@
         EFFECT_API_VERSION,
         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND
         | EFFECT_FLAG_VOLUME_CTRL),
-        0, // TODO
-        1,
+        VIRTUALIZER_CUP_LOAD_ARM9E,
+        BUNDLE_MEM_USAGE,
         "Virtualizer",
         "NXP Software Ltd.",
 };
@@ -102,8 +99,8 @@
         {0xce772f20, 0x847d, 0x11df, 0xbb17, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid Eq NXP
         EFFECT_API_VERSION,
         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL),
-        0, // TODO
-        1,
+        EQUALIZER_CUP_LOAD_ARM9E,
+        BUNDLE_MEM_USAGE,
         "Equalizer",
         "NXP Software Ltd.",
 };
@@ -114,8 +111,8 @@
         {0x119341a0, 0x8469, 0x11df, 0x81f9, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }}, //uuid VOL NXP
         EFFECT_API_VERSION,
         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL),
-        0, // TODO
-        1,
+        VOLUME_CUP_LOAD_ARM9E,
+        BUNDLE_MEM_USAGE,
         "Volume",
         "NXP Software Ltd.",
 };
@@ -258,18 +255,27 @@
         pContext->pBundledContext->NumberEffectsEnabled     = 0;
         pContext->pBundledContext->NumberEffectsCalled      = 0;
         pContext->pBundledContext->frameCount               = 0;
+        pContext->pBundledContext->firstVolume              = LVM_TRUE;
 
         #ifdef LVM_PCM
-        pContext->pBundledContext->PcmInPtr  = NULL;
-        pContext->pBundledContext->PcmOutPtr = NULL;
 
-        pContext->pBundledContext->PcmInPtr  = fopen("/data/tmp/bundle_pcm_in.pcm", "w");
-        pContext->pBundledContext->PcmOutPtr = fopen("/data/tmp/bundle_pcm_out.pcm", "w");
-
-        if((pContext->pBundledContext->PcmInPtr  == NULL)||
-           (pContext->pBundledContext->PcmOutPtr == NULL)){
+        char fileName[256];
+        snprintf(fileName, 256, "/data/tmp/bundle_%p_pcm_in.pcm", pContext->pBundledContext);
+        pContext->pBundledContext->PcmInPtr = fopen(fileName, "w");
+        if (pContext->pBundledContext->PcmInPtr == NULL) {
+            LOGV("cannot open %s", fileName);
            return -EINVAL;
         }
+
+        snprintf(fileName, 256, "/data/tmp/bundle_%p_pcm_out.pcm", pContext->pBundledContext);
+        pContext->pBundledContext->PcmOutPtr = fopen(fileName, "w");
+        if (pContext->pBundledContext->PcmOutPtr == NULL) {
+            LOGV("cannot open %s", fileName);
+            fclose(pContext->pBundledContext->PcmInPtr);
+           pContext->pBundledContext->PcmInPtr = NULL;
+           return -EINVAL;
+        }
+
         #endif
 
         /* Saved strength is used to return the exact strength that was used in the set to the get
@@ -377,8 +383,14 @@
     (GlobalSessionMemory[pContext->pBundledContext->SessionNo].bVirtualizerInstantiated==LVM_FALSE))
     {
         #ifdef LVM_PCM
-        fclose(pContext->pBundledContext->PcmInPtr);
-        fclose(pContext->pBundledContext->PcmOutPtr);
+        if (pContext->pBundledContext->PcmInPtr != NULL) {
+            fclose(pContext->pBundledContext->PcmInPtr);
+            pContext->pBundledContext->PcmInPtr = NULL;
+        }
+        if (pContext->pBundledContext->PcmOutPtr != NULL) {
+            fclose(pContext->pBundledContext->PcmOutPtr);
+            pContext->pBundledContext->PcmOutPtr = NULL;
+        }
         #endif
 
         LvmSessionsActive--;
@@ -503,8 +515,8 @@
             MemTab.Region[i].pBaseAddress = malloc(MemTab.Region[i].Size);
 
             if (MemTab.Region[i].pBaseAddress == LVM_NULL){
-                LOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate %ld bytes for region %u\n",
-                        MemTab.Region[i].Size, i );
+                LOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate %ld bytes "
+                        "for region %u\n", MemTab.Region[i].Size, i );
                 bMallocFailure = LVM_TRUE;
             }else{
                 LOGV("\tLvmBundle_init CreateInstance allocated %ld bytes for region %u at %p\n",
@@ -519,8 +531,8 @@
     if(bMallocFailure == LVM_TRUE){
         for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
             if (MemTab.Region[i].pBaseAddress == LVM_NULL){
-                LOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate %ld bytes for region %u - +"
-                     "Not freeing\n", MemTab.Region[i].Size, i );
+                LOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate %ld bytes "
+                        "for region %u Not freeing\n", MemTab.Region[i].Size, i );
             }else{
                 LOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed: but allocated %ld bytes "
                      "for region %u at %p- free\n",
@@ -561,7 +573,7 @@
     params.VirtualizerOperatingMode   = LVM_MODE_OFF;
     params.VirtualizerType            = LVM_CONCERTSOUND;
     params.VirtualizerReverbLevel     = 100;
-    params.CS_EffectLevel             = LVM_CS_EFFECT_HIGH;
+    params.CS_EffectLevel             = LVM_CS_EFFECT_NONE;
 
     /* N-Band Equaliser parameters */
     params.EQNB_OperatingMode     = LVM_EQNB_OFF;
@@ -597,6 +609,10 @@
     params.PSA_Enable             = LVM_PSA_OFF;
     params.PSA_PeakDecayRate      = LVM_PSA_SPEED_MEDIUM;
 
+    /* TE Control parameters */
+    params.TE_OperatingMode       = LVM_TE_OFF;
+    params.TE_EffectLevel         = 0;
+
     /* Activate the initial settings */
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance,
                                          &params);
@@ -691,6 +707,8 @@
     fflush(pContext->pBundledContext->PcmInPtr);
     #endif
 
+    //LOGV("Calling LVM_Process");
+
     /* Process the samples */
     LvmStatus = LVM_Process(pContext->pBundledContext->hInstance, /* Instance handle */
                             pIn,                                  /* Input buffer */
@@ -1056,7 +1074,7 @@
 
     //LOGV("\tVirtualizerGetStrength Succesfully returned from LVM_GetControlParameters\n");
     //LOGV("\tVirtualizerGetStrength() (0-100)   -> %d\n", ActiveParams.VirtualizerReverbLevel*10);
-    return ActiveParams.VirtualizerReverbLevel*10;
+    return pContext->pBundledContext->VirtStrengthSaved;
 }    /* end getStrength */
 
 //----------------------------------------------------------------------------
@@ -1085,15 +1103,15 @@
     //LOGV("\tVirtualizerSetStrength Succesfully returned from LVM_GetControlParameters\n");
 
     /* Virtualizer parameters */
-    ActiveParams.VirtualizerReverbLevel    = (LVM_INT16)(strength/10);
+    ActiveParams.CS_EffectLevel             = (int)((strength*32767)/1000);
 
     //LOGV("\tVirtualizerSetStrength() (0-1000)   -> %d\n", strength );
-    //LOGV("\tVirtualizerSetStrength() (0- 100)   -> %d\n", ActiveParams.VirtualizerReverbLevel );
+    //LOGV("\tVirtualizerSetStrength() (0- 100)   -> %d\n", ActiveParams.CS_EffectLevel );
 
     /* Activate the initial settings */
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VirtualizerSetStrength")
-    //LOGV("\tVirtualizerSetStrength Succesfully called LVM_SetControlParameters\n");
+    //LOGV("\tVirtualizerSetStrength Succesfully called LVM_SetControlParameters\n\n");
 }    /* end setStrength */
 
 //----------------------------------------------------------------------------
@@ -1142,7 +1160,7 @@
 // Outputs:
 //
 //---------------------------------------------------------------------------
-void EqualizerSetBandLevel(EffectContext *pContext, int band, int Gain){
+void EqualizerSetBandLevel(EffectContext *pContext, int band, short Gain){
     int gainRounded;
     if(Gain > 0){
         gainRounded = (int)((Gain+50)/100);
@@ -1160,7 +1178,7 @@
     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "EqualizerSetBandLevel")
     //LOGV("\tEqualizerSetBandLevel Succesfully returned from LVM_GetControlParameters\n");
-    //LOGV("\tEqualizerSetBandLevel just Got -> %d\n", ActiveParams.pEQNB_BandDefinition[band].Gain);
+    //LOGV("\tEqualizerSetBandLevel just Got -> %d\n",ActiveParams.pEQNB_BandDefinition[band].Gain);
 
     /* Set local EQ parameters */
     BandDef = ActiveParams.pEQNB_BandDefinition;
@@ -1169,7 +1187,7 @@
     /* Activate the initial settings */
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "EqualizerSetBandLevel")
-    //LOGV("\tEqualizerSetBandLevel just Set -> %d\n", ActiveParams.pEQNB_BandDefinition[band].Gain);
+    //LOGV("\tEqualizerSetBandLevel just Set -> %d\n",ActiveParams.pEQNB_BandDefinition[band].Gain);
 
     pContext->pBundledContext->CurPreset = PRESET_CUSTOM;
     return;
@@ -1389,7 +1407,13 @@
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeSetVolumeLevel")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-    //LOGV("\tVolumeSetVolumeLevel just set (-96dB -> 0dB)   -> %d\n", ActiveParams.VC_EffectLevel );
+    //LOGV("\tVolumeSetVolumeLevel just set (-96dB -> 0dB)   -> %d\n",ActiveParams.VC_EffectLevel );
+    if(pContext->pBundledContext->firstVolume == LVM_TRUE){
+        LvmStatus = LVM_SetVolumeNoSmoothing(pContext->pBundledContext->hInstance, &ActiveParams);
+        LVM_ERROR_CHECK(LvmStatus, "LVM_SetVolumeNoSmoothing", "LvmBundle_process")
+        LOGV("\tLVM_VOLUME: Disabling Smoothing for first volume change to remove spikes/clicks");
+        pContext->pBundledContext->firstVolume = LVM_FALSE;
+    }
     return 0;
 }    /* end setVolumeLevel */
 
@@ -1524,7 +1548,8 @@
     pContext->pBundledContext->positionSaved = position;
     Balance = VolumeConvertStereoPosition(pContext->pBundledContext->positionSaved);
 
-    //LOGV("\tVolumeSetStereoPosition start pContext->pBundledContext->positionSaved = %d", pContext->pBundledContext->positionSaved);
+    //LOGV("\tVolumeSetStereoPosition start pContext->pBundledContext->positionSaved = %d",
+    //pContext->pBundledContext->positionSaved);
 
     if(pContext->pBundledContext->bStereoPositionEnabled == LVM_TRUE){
 
@@ -1559,7 +1584,8 @@
         //LOGV("\tVolumeSetStereoPosition Position attempting to set, but not enabled %d %d\n",
         //position, Balance);
     }
-    //LOGV("\tVolumeSetStereoPosition end pContext->pBundledContext->positionSaved = %d\n", pContext->pBundledContext->positionSaved);
+    //LOGV("\tVolumeSetStereoPosition end pContext->pBundledContext->positionSaved = %d\n",
+    //pContext->pBundledContext->positionSaved);
     return 0;
 }    /* end VolumeSetStereoPosition */
 
@@ -1583,7 +1609,8 @@
     LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
     LVM_INT16               balance;
 
-    //LOGV("\tVolumeGetStereoPosition start pContext->pBundledContext->positionSaved = %d", pContext->pBundledContext->positionSaved);
+    //LOGV("\tVolumeGetStereoPosition start pContext->pBundledContext->positionSaved = %d",
+    //pContext->pBundledContext->positionSaved);
 
     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeGetStereoPosition")
@@ -1600,7 +1627,8 @@
         }
     }
     *position = (LVM_INT16)pContext->pBundledContext->positionSaved;     // Convert dB to millibels
-    //LOGV("\tVolumeGetStereoPosition end returning pContext->pBundledContext->positionSaved = %d\n", pContext->pBundledContext->positionSaved);
+    //LOGV("\tVolumeGetStereoPosition end returning pContext->pBundledContext->positionSaved =%d\n",
+    //pContext->pBundledContext->positionSaved);
     return 0;
 }    /* end VolumeGetStereoPosition */
 
@@ -1686,14 +1714,14 @@
     switch (param){
         case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
             if (*pValueSize != sizeof(uint32_t)){
-                LOGV("\tLVM_ERROR : BassBoost_getParameter() invalid pValueSize %d", *pValueSize);
+                LOGV("\tLVM_ERROR : BassBoost_getParameter() invalid pValueSize1 %d", *pValueSize);
                 return -EINVAL;
             }
             *pValueSize = sizeof(uint32_t);
             break;
         case BASSBOOST_PARAM_STRENGTH:
             if (*pValueSize != sizeof(int16_t)){
-                LOGV("\tLVM_ERROR : BassBoost_getParameter() invalid pValueSize %d", *pValueSize);
+                LOGV("\tLVM_ERROR : BassBoost_getParameter() invalid pValueSize2 %d", *pValueSize);
                 return -EINVAL;
             }
             *pValueSize = sizeof(int16_t);
@@ -1809,10 +1837,9 @@
             }
             *pValueSize = sizeof(uint32_t);
             break;
-
         case VIRTUALIZER_PARAM_STRENGTH:
             if (*pValueSize != sizeof(int16_t)){
-                LOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize %d",*pValueSize);
+                LOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize2 %d",*pValueSize);
                 return -EINVAL;
             }
             *pValueSize = sizeof(int16_t);
@@ -1941,10 +1968,9 @@
         }
         *pValueSize = 2 * sizeof(int16_t);
         break;
-
     case EQ_PARAM_BAND_FREQ_RANGE:
         if (*pValueSize < 2 * sizeof(int32_t)) {
-            LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 2  %d", *pValueSize);
+            LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 3  %d", *pValueSize);
             return -EINVAL;
         }
         *pValueSize = 2 * sizeof(int32_t);
@@ -1952,7 +1978,7 @@
 
     case EQ_PARAM_CENTER_FREQ:
         if (*pValueSize < sizeof(int32_t)) {
-            LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 1  %d", *pValueSize);
+            LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 5  %d", *pValueSize);
             return -EINVAL;
         }
         *pValueSize = sizeof(int32_t);
@@ -1984,7 +2010,7 @@
         *(int16_t *)pValue = -1500;
         *((int16_t *)pValue + 1) = 1500;
         //LOGV("\tEqualizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d",
-        //      *(int32_t *)pValue, *((int32_t *)pValue + 1));
+        //      *(int16_t *)pValue, *((int16_t *)pValue + 1));
         break;
 
     case EQ_PARAM_BAND_LEVEL:
@@ -2024,7 +2050,7 @@
         param2 = *pParamTemp;
         *(uint16_t *)pValue = (uint16_t)EqualizerGetBand(pContext, param2);
         //LOGV("\tEqualizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d",
-        //      param2, *(int32_t *)pValue);
+        //      param2, *(uint16_t *)pValue);
         break;
 
     case EQ_PARAM_CUR_PRESET:
@@ -2068,7 +2094,7 @@
         break;
     }
 
-    //LOGV("\tEqualizer_getParameter end");
+    //GV("\tEqualizer_getParameter end\n");
     return status;
 } /* end Equalizer_getParameter */
 
@@ -2137,7 +2163,7 @@
         }
     } break;
     default:
-        LOGV("\tLVM_ERROR : setParameter() invalid param %d", param);
+        LOGV("\tLVM_ERROR : Equalizer_setParameter() invalid param %d", param);
         status = -EINVAL;
         break;
     }
@@ -2177,7 +2203,7 @@
     int32_t param = *pParamTemp++;;
     char *name;
 
-    LOGV("\tVolume_getParameter start");
+    //LOGV("\tVolume_getParameter start");
 
     switch (param){
         case VOLUME_PARAM_LEVEL:
@@ -2207,20 +2233,20 @@
     switch (param){
         case VOLUME_PARAM_LEVEL:
             status = VolumeGetVolumeLevel(pContext, (int16_t *)(pValue));
-            LOGV("\tVolume_getParameter() VOLUME_PARAM_LEVEL Value is %d",
-                    *(int16_t *)pValue);
+            //LOGV("\tVolume_getParameter() VOLUME_PARAM_LEVEL Value is %d",
+            //        *(int16_t *)pValue);
             break;
 
         case VOLUME_PARAM_MAXLEVEL:
             *(int16_t *)pValue = 0;
-            LOGV("\tVolume_getParameter() VOLUME_PARAM_MAXLEVEL Value is %d",
-                    *(int16_t *)pValue);
+            //LOGV("\tVolume_getParameter() VOLUME_PARAM_MAXLEVEL Value is %d",
+            //        *(int16_t *)pValue);
             break;
 
         case VOLUME_PARAM_STEREOPOSITION:
             VolumeGetStereoPosition(pContext, (int16_t *)pValue);
-            LOGV("\tVolume_getParameter() VOLUME_PARAM_STEREOPOSITION Value is %d",
-                    *(int16_t *)pValue);
+            //LOGV("\tVolume_getParameter() VOLUME_PARAM_STEREOPOSITION Value is %d",
+            //        *(int16_t *)pValue);
             break;
 
         case VOLUME_PARAM_MUTE:
@@ -2231,8 +2257,8 @@
 
         case VOLUME_PARAM_ENABLESTEREOPOSITION:
             *(int32_t *)pValue = pContext->pBundledContext->bStereoPositionEnabled;
-            LOGV("\tVolume_getParameter() VOLUME_PARAM_ENABLESTEREOPOSITION Value is %d",
-                    *(uint32_t *)pValue);
+            //LOGV("\tVolume_getParameter() VOLUME_PARAM_ENABLESTEREOPOSITION Value is %d",
+            //        *(uint32_t *)pValue);
             break;
 
         default:
@@ -2270,38 +2296,38 @@
     int32_t *pParamTemp = (int32_t *)pParam;
     int32_t param = *pParamTemp++;
 
-    LOGV("\tVolume_setParameter start");
+    //LOGV("\tVolume_setParameter start");
 
     switch (param){
         case VOLUME_PARAM_LEVEL:
             level = *(int16_t *)pValue;
-            LOGV("\tVolume_setParameter() VOLUME_PARAM_LEVEL value is %d", level);
-            LOGV("\tVolume_setParameter() Calling pVolume->setVolumeLevel");
+            //LOGV("\tVolume_setParameter() VOLUME_PARAM_LEVEL value is %d", level);
+            //LOGV("\tVolume_setParameter() Calling pVolume->setVolumeLevel");
             status = VolumeSetVolumeLevel(pContext, (int16_t)level);
-            LOGV("\tVolume_setParameter() Called pVolume->setVolumeLevel");
+            //LOGV("\tVolume_setParameter() Called pVolume->setVolumeLevel");
             break;
 
         case VOLUME_PARAM_MUTE:
             mute = *(uint32_t *)pValue;
-            LOGV("\tVolume_setParameter() Calling pVolume->setMute, mute is %d", mute);
-            LOGV("\tVolume_setParameter() Calling pVolume->setMute");
+            //LOGV("\tVolume_setParameter() Calling pVolume->setMute, mute is %d", mute);
+            //LOGV("\tVolume_setParameter() Calling pVolume->setMute");
             status = VolumeSetMute(pContext, mute);
-            LOGV("\tVolume_setParameter() Called pVolume->setMute");
+            //LOGV("\tVolume_setParameter() Called pVolume->setMute");
             break;
 
         case VOLUME_PARAM_ENABLESTEREOPOSITION:
             positionEnabled = *(uint32_t *)pValue;
             status = VolumeEnableStereoPosition(pContext, positionEnabled);
             status = VolumeSetStereoPosition(pContext, pContext->pBundledContext->positionSaved);
-            LOGV("\tVolume_setParameter() VOLUME_PARAM_ENABLESTEREOPOSITION called");
+            //LOGV("\tVolume_setParameter() VOLUME_PARAM_ENABLESTEREOPOSITION called");
             break;
 
         case VOLUME_PARAM_STEREOPOSITION:
             position = *(int16_t *)pValue;
-            LOGV("\tVolume_setParameter() VOLUME_PARAM_STEREOPOSITION value is %d", position);
-            LOGV("\tVolume_setParameter() Calling pVolume->VolumeSetStereoPosition");
+            //LOGV("\tVolume_setParameter() VOLUME_PARAM_STEREOPOSITION value is %d", position);
+            //LOGV("\tVolume_setParameter() Calling pVolume->VolumeSetStereoPosition");
             status = VolumeSetStereoPosition(pContext, (int16_t)position);
-            LOGV("\tVolume_setParameter() Called pVolume->VolumeSetStereoPosition");
+            //LOGV("\tVolume_setParameter() Called pVolume->VolumeSetStereoPosition");
             break;
 
         default:
@@ -2375,8 +2401,8 @@
     LVM_INT16   *in  = (LVM_INT16 *)inBuffer->raw;
     LVM_INT16   *out = (LVM_INT16 *)outBuffer->raw;
 
-    //LOGV("\tEffect_process Start : Enabled = %d     Called = %d",
-    //pContext->pBundledContext->NumberEffectsEnabled,pContext->pBundledContext->NumberEffectsCalled);
+//LOGV("\tEffect_process Start : Enabled = %d     Called = %d",
+//pContext->pBundledContext->NumberEffectsEnabled,pContext->pBundledContext->NumberEffectsCalled);
 //    LOGV("\tEffect_process Start : Samples left %d %d %d",
 //    pContext->pBundledContext->SamplesToExitCountBb,
 //    pContext->pBundledContext->SamplesToExitCountVirt,
@@ -2552,8 +2578,7 @@
                 android::EqualizerSetPreset(pContext, 0);
             }
             if(pContext->EffectType == LVM_VOLUME){
-                //LOGV("\tEffect_command cmdCode Case: "
-                //        "EFFECT_CMD_INIT start");
+                //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_VOLUME");
                 *(int *) pReplyData = android::VolumeSetVolumeLevel(pContext, 0);
             }
             break;
@@ -2676,8 +2701,7 @@
                 //        sizeof(int32_t)));
             }
             if(pContext->EffectType == LVM_VOLUME){
-                //LOGV("\tVolume_command cmdCode Case: "
-                //        "EFFECT_CMD_GET_PARAM start");
+                //LOGV("\tVolume_command cmdCode Case: EFFECT_CMD_GET_PARAM start");
                 if (pCmdData == NULL ||
                         cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
                         pReplyData == NULL ||
@@ -2745,10 +2769,10 @@
                                                                     p->data + p->psize);
             }
             if(pContext->EffectType == LVM_VIRTUALIZER){
-                //LOGV("\tVirtualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d",
-                //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
-                //        *replySize,
-                //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
+              //LOGV("\tVirtualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d",
+              //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
+              //        *replySize,
+              //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
 
                 if (pCmdData   == NULL||
                     cmdSize    != (int)(sizeof(effect_param_t) + sizeof(int32_t) +sizeof(int16_t))||
@@ -2778,12 +2802,12 @@
                                                                        p->data + p->psize);
             }
             if(pContext->EffectType == LVM_EQUALIZER){
-                //LOGV("\tEqualizer_command cmdCode Case: "
-                //        "EFFECT_CMD_SET_PARAM start");
-                //LOGV("\tEqualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
-                //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
-                //        *replySize,
-                //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
+               //LOGV("\tEqualizer_command cmdCode Case: "
+               //        "EFFECT_CMD_SET_PARAM start");
+               //LOGV("\tEqualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
+               //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
+               //        *replySize,
+               //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
 
                 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
                     pReplyData == NULL || *replySize != sizeof(int32_t)) {
@@ -2798,12 +2822,11 @@
                                                                      p->data + p->psize);
             }
             if(pContext->EffectType == LVM_VOLUME){
-                //LOGV("\tVolume_command cmdCode Case: "
-                //        "EFFECT_CMD_SET_PARAM start");
+                //LOGV("\tVolume_command cmdCode Case: EFFECT_CMD_SET_PARAM start");
                 //LOGV("\tVolume_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
                 //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
                 //        *replySize,
-                //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
+                //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) +sizeof(int32_t)));
 
                 if (    pCmdData   == NULL||
                         cmdSize    < (int)(sizeof(effect_param_t) + sizeof(int32_t))||
@@ -2836,7 +2859,7 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bBassEnabled = LVM_TRUE;
-                    //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_BASS_BOOST enabled");
+                    //LOGV("\tEffect_command cmdCode Case:EFFECT_CMD_ENABLE LVM_BASS_BOOSTenabled");
                     break;
                 case LVM_EQUALIZER:
                     if(pContext->pBundledContext->bEqualizerEnabled == LVM_TRUE){
@@ -2845,7 +2868,7 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bEqualizerEnabled = LVM_TRUE;
-                    //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_EQUALIZER enabled");
+                    //LOGV("\tEffect_command cmdCode Case:EFFECT_CMD_ENABLE LVM_EQUALIZER enabled");
                     break;
                 case LVM_VIRTUALIZER:
                     if(pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE){
@@ -2854,7 +2877,7 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bVirtualizerEnabled = LVM_TRUE;
-                    //LOGV("\tEffect_command cmdCode Case:EFFECT_CMD_ENABLE LVM_VIRTUALIZER enabled");
+                    //LOGV("\tEffect_command cmdCode :EFFECT_CMD_ENABLE LVM_VIRTUALIZER enabled");
                     break;
                 case LVM_VOLUME:
                     if(pContext->pBundledContext->bVolumeEnabled == LVM_TRUE){
@@ -2863,7 +2886,7 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bVolumeEnabled = LVM_TRUE;
-                    //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_VOLUME enabled");
+                    LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_VOLUME enabled");
                     break;
                 default:
                     LOGV("\tLVM_ERROR : Effect_command cmdCode Case: "
@@ -3036,8 +3059,11 @@
             dB = (dB +8)>>4;
             dB = (dB <-96) ? -96 : dB ;
 
-            //LOGV("\tSession: %d, VOLUME is %d dB (%d), effect is %d",
-            //pContext->pBundledContext->SessionNo, (int32_t)dB, vol<<7, pContext->EffectType);
+            LOGV("\tEFFECT_CMD_SET_VOLUME Session: %d, SessionID: %d VOLUME is %d dB (%d), "
+                  "effect is %d",
+            pContext->pBundledContext->SessionNo, pContext->pBundledContext->SessionId,
+            (int32_t)dB, vol<<7, pContext->EffectType);
+
             memcpy(pReplyData, vol_ret, sizeof(int32_t)*2);
             android::VolumeSetVolumeLevel(pContext, (int16_t)(dB*100));
             break;
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index 1bee974..35e1114 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -26,9 +26,15 @@
 extern "C" {
 #endif
 
-#define FIVEBAND_NUMBANDS       5
-#define MAX_NUM_BANDS           5
-#define MAX_CALL_SIZE           256
+#define FIVEBAND_NUMBANDS          5
+#define MAX_NUM_BANDS              5
+#define MAX_CALL_SIZE              256
+#define LVM_MAX_SESSIONS           32
+#define BASS_BOOST_CUP_LOAD_ARM9E  150    // Expressed in 0.1 MIPS
+#define VIRTUALIZER_CUP_LOAD_ARM9E 120    // Expressed in 0.1 MIPS
+#define EQUALIZER_CUP_LOAD_ARM9E   220    // Expressed in 0.1 MIPS
+#define VOLUME_CUP_LOAD_ARM9E      0      // Expressed in 0.1 MIPS
+#define BUNDLE_MEM_USAGE           25     // Expressed in kB
 //#define LVM_PCM
 
 #ifndef OPENSL_ES_H_
@@ -67,6 +73,7 @@
     bool                            bVirtualizerTempDisabled; /* Flag for effect to be re-enabled */
     int                             NumberEffectsEnabled;     /* Effects in this session */
     int                             NumberEffectsCalled;      /* Effects called so far */
+    bool                            firstVolume;              /* No smoothing on first Vol change */
     // Saved parameters for each effect */
     // Bass Boost
     int                             BassStrengthSaved;        /* Conversion between Get/Set */
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 03f1409..10c3e92 100755
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -27,13 +27,6 @@
 #include <EffectReverb.h>
 #include <LVREV.h>
 
-#define MAX_NUM_BANDS           5
-#define MAX_CALL_SIZE           256
-#define LVREV_MAX_T60           7000
-#define LVREV_MAX_REVERB_LEVEL  2000
-
-//#define LVM_PCM
-
 // effect_interface_t interface implementation for reverb
 extern "C" const struct effect_interface_s gReverbInterface;
 
@@ -86,8 +79,8 @@
         { 0x4a387fc0, 0x8ab3, 0x11df, 0x8bad, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
         EFFECT_API_VERSION,
         EFFECT_FLAG_TYPE_AUXILIARY,
-        0, // TODO
-        1,
+        LVREV_CUP_LOAD_ARM9E,
+        LVREV_MEM_USAGE,
         "Auxiliary Environmental Reverb",
         "NXP Software Ltd.",
 };
@@ -98,8 +91,8 @@
         {0xc7a511a0, 0xa3bb, 0x11df, 0x860e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
         EFFECT_API_VERSION,
         EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
-        0, // TODO
-        1,
+        LVREV_CUP_LOAD_ARM9E,
+        LVREV_MEM_USAGE,
         "Insert Environmental Reverb",
         "NXP Software Ltd.",
 };
@@ -110,8 +103,8 @@
         {0xf29a1400, 0xa3bb, 0x11df, 0x8ddc, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
         EFFECT_API_VERSION,
         EFFECT_FLAG_TYPE_AUXILIARY,
-        0, // TODO
-        1,
+        LVREV_CUP_LOAD_ARM9E,
+        LVREV_MEM_USAGE,
         "Auxiliary Preset Reverb",
         "NXP Software Ltd.",
 };
@@ -122,8 +115,8 @@
         {0x172cdf00, 0xa3bc, 0x11df, 0xa72f, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
         EFFECT_API_VERSION,
         EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
-        0, // TODO
-        1,
+        LVREV_CUP_LOAD_ARM9E,
+        LVREV_MEM_USAGE,
         "Insert Preset Reverb",
         "NXP Software Ltd.",
 };
@@ -153,6 +146,8 @@
     FILE                            *PcmOutPtr;
     #endif
     LVM_Fs_en                       SampleRate;
+    LVM_INT32                       *InFrames32;
+    LVM_INT32                       *OutFrames32;
     bool                            auxiliary;
     bool                            preset;
     uint16_t                        curPreset;
@@ -267,6 +262,11 @@
     }
     #endif
 
+
+    // Allocate memory for reverb process (*2 is for STEREO)
+    pContext->InFrames32  = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2);
+    pContext->OutFrames32 = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2);
+
     LOGV("\tEffectCreate %p, size %d", pContext, sizeof(ReverbContext));
     LOGV("\tEffectCreate end\n");
     return 0;
@@ -285,6 +285,8 @@
     fclose(pContext->PcmInPtr);
     fclose(pContext->PcmOutPtr);
     #endif
+    free(pContext->InFrames32);
+    free(pContext->OutFrames32);
     Reverb_free(pContext);
     delete pContext;
     return 0;
@@ -389,9 +391,6 @@
 
     LVM_INT16               samplesPerFrame = 0;
     LVREV_ReturnStatus_en   LvmStatus = LVREV_SUCCESS;              /* Function call status */
-
-    LVM_INT32 *InFrames32;
-    LVM_INT32 *OutFrames32;
     LVM_INT16 *OutFrames16;
 
 
@@ -405,12 +404,11 @@
         return -EINVAL;
     }
 
-    InFrames32  = (LVM_INT32 *)malloc(frameCount * sizeof(LVM_INT32) * 2);
-    OutFrames32 = (LVM_INT32 *)malloc(frameCount * sizeof(LVM_INT32) * 2);
-    OutFrames16 = (LVM_INT16 *)OutFrames32;
+
+    OutFrames16 = (LVM_INT16 *)pContext->OutFrames32;
 
     // Check for NULL pointers
-    if((InFrames32 == NULL)||(OutFrames32 == NULL)){
+    if((pContext->InFrames32 == NULL)||(pContext->OutFrames32 == NULL)){
         LOGV("\tLVREV_ERROR : process failed to allocate memory for temporary buffers ");
         return -EINVAL;
     }
@@ -425,13 +423,13 @@
     }
     // Convert to Input 32 bits
     for(int i=0; i<frameCount*samplesPerFrame; i++){
-        InFrames32[i] = (LVM_INT32)pIn[i]<<8;
+        pContext->InFrames32[i] = (LVM_INT32)pIn[i]<<8;
     }
 
      // If the input was MONO, convert to STEREO
     if(pContext->config.inputCfg.channels == CHANNEL_MONO){
         //LOGV("\tConverting Output from MONO to STEREO");
-        MonoTo2I_32(InFrames32, InFrames32, frameCount);
+        MonoTo2I_32(pContext->InFrames32, pContext->InFrames32, frameCount);
     }
 
     //LOGV("\tProcess, frames: %d, InFormat: %d(MONO=%d), OutFormat: %d(STEREO=%d)",
@@ -439,18 +437,18 @@
     //pContext->config.outputCfg.channels, CHANNEL_STEREO);
 
     if (pContext->preset && pContext->curPreset == REVERB_PRESET_NONE) {
-        memset(OutFrames32, 0, frameCount * sizeof(LVM_INT32) * 2);
+        memset(pContext->OutFrames32, 0, frameCount * sizeof(LVM_INT32) * 2);
     } else {
     /* Process the samples */
     LvmStatus = LVREV_Process(pContext->hInstance,      /* Instance handle */
-                              InFrames32,               /* Input buffer */
-                              OutFrames32,              /* Output buffer */
+                              pContext->InFrames32,     /* Input buffer */
+                              pContext->OutFrames32,    /* Output buffer */
                               frameCount);              /* Number of samples to read */
     }
 
     if (!pContext->auxiliary) {
         for (int i=0; i<frameCount*2; i++){
-            OutFrames32[i] += InFrames32[i];
+            pContext->OutFrames32[i] += pContext->InFrames32[i];
         }
     }
 
@@ -459,7 +457,7 @@
 
     // Convert to 16 bits
     for(int i=0; i<frameCount*2; i++){  // Always stereo
-        OutFrames16[i] = clamp16(OutFrames32[i]>>8);
+        OutFrames16[i] = clamp16(pContext->OutFrames32[i]>>8);
     }
 
     #ifdef LVM_PCM
@@ -478,9 +476,6 @@
         memcpy(pOut, OutFrames16, frameCount*sizeof(LVM_INT16)*2); // 2 is for stereo output
     }
 
-    free(InFrames32);
-    free(OutFrames32);
-
     return 0;
 }    /* end process */
 
@@ -689,8 +684,8 @@
             MemTab.Region[i].pBaseAddress = malloc(MemTab.Region[i].Size);
 
             if (MemTab.Region[i].pBaseAddress == LVM_NULL){
-                LOGV("\tLVREV_ERROR :Reverb_init CreateInstance Failed to allocate %ld bytes for region %u\n",
-                        MemTab.Region[i].Size, i );
+                LOGV("\tLVREV_ERROR :Reverb_init CreateInstance Failed to allocate %ld "
+                        "bytes for region %u\n", MemTab.Region[i].Size, i );
                 bMallocFailure = LVM_TRUE;
             }else{
                 LOGV("\tReverb_init CreateInstance allocate %ld bytes for region %u at %p\n",
@@ -705,11 +700,12 @@
     if(bMallocFailure == LVM_TRUE){
         for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
             if (MemTab.Region[i].pBaseAddress == LVM_NULL){
-                LOGV("\tLVM_ERROR :Reverb_init CreateInstance Failed to allocate %ld bytes for region %u"
-                     " - Not freeing\n", MemTab.Region[i].Size, i );
+                LOGV("\tLVM_ERROR :Reverb_init CreateInstance Failed to allocate %ld bytes "
+                        "for region %u - Not freeing\n", MemTab.Region[i].Size, i );
             }else{
-                LOGV("\tLVM_ERROR :Reverb_init CreateInstance Failed: but allocated %ld bytes for region %u "
-                       "at %p- free\n", MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
+                LOGV("\tLVM_ERROR :Reverb_init CreateInstance Failed: but allocated %ld bytes "
+                        "for region %u at %p- free\n",
+                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
                 free(MemTab.Region[i].pBaseAddress);
             }
         }
@@ -753,7 +749,7 @@
     pContext->SavedHfLevel      = 0;
     pContext->bEnabled          = LVM_FALSE;
     pContext->SavedDecayTime    = params.T60;
-    pContext->SavedDecayHfRatio = params.Damping*10;
+    pContext->SavedDecayHfRatio = params.Damping*20;
     pContext->SavedDensity      = params.RoomSize*10;
     pContext->SavedDiffusion    = params.Density*10;
     pContext->SavedReverbLevel  = -6000;
@@ -1195,7 +1191,7 @@
     //LOGV("\tReverbSetDecayHfRatio Succesfully returned from LVM_GetControlParameters\n");
     //LOGV("\tReverbSetDecayHfRatio() just Got -> %d\n", ActiveParams.Damping);
 
-    ActiveParams.Damping = (LVM_INT16)(ratio/10);
+    ActiveParams.Damping = (LVM_INT16)(ratio/20);
 
     /* Activate the initial settings */
     LvmStatus = LVREV_SetControlParameters(pContext->hInstance, &ActiveParams);
@@ -1230,7 +1226,7 @@
     //LOGV("\tReverbGetDecayHfRatio Succesfully returned from LVM_GetControlParameters\n");
     //LOGV("\tReverbGetDecayHfRatio() just Got -> %d\n", ActiveParams.Damping);
 
-    if(ActiveParams.Damping != (LVM_INT16)(pContext->SavedDecayHfRatio / 10)){
+    if(ActiveParams.Damping != (LVM_INT16)(pContext->SavedDecayHfRatio / 20)){
         LOGV("\tLVM_ERROR : ReverbGetDecayHfRatio() has wrong level -> %d %d\n",
          ActiveParams.Damping, pContext->SavedDecayHfRatio);
     }
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h
old mode 100755
new mode 100644
index 1ab423f..093992b
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.h
@@ -24,6 +24,14 @@
 extern "C" {
 #endif
 
+#define MAX_NUM_BANDS           5
+#define MAX_CALL_SIZE           256
+#define LVREV_MAX_T60           7000
+#define LVREV_MAX_REVERB_LEVEL  2000
+#define LVREV_MAX_FRAME_SIZE    2560
+#define LVREV_CUP_LOAD_ARM9E    470    // Expressed in 0.1 MIPS
+#define LVREV_MEM_USAGE         71+(LVREV_MAX_FRAME_SIZE>>7)     // Expressed in kB
+//#define LVM_PCM
 
 typedef struct _LPFPair_t
 {
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index f55a01e..59cd1b7 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -43,6 +43,7 @@
     SET_AUDIO_ENCODER,
     SET_OUTPUT_FILE_PATH,
     SET_OUTPUT_FILE_FD,
+    SET_OUTPUT_FILE_AUXILIARY_FD,
     SET_VIDEO_SIZE,
     SET_VIDEO_FRAMERATE,
     SET_PARAMETERS,
@@ -159,6 +160,15 @@
         return reply.readInt32();
     }
 
+    status_t setOutputFileAuxiliary(int fd) {
+        LOGV("setOutputFileAuxiliary(%d)", fd);
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+        data.writeFileDescriptor(fd);
+        remote()->transact(SET_OUTPUT_FILE_AUXILIARY_FD, data, &reply);
+        return reply.readInt32();
+    }
+
     status_t setVideoSize(int width, int height)
     {
         LOGV("setVideoSize(%dx%d)", width, height);
@@ -377,6 +387,13 @@
             ::close(fd);
             return NO_ERROR;
         } break;
+        case SET_OUTPUT_FILE_AUXILIARY_FD: {
+            LOGV("SET_OUTPUT_FILE_AUXILIARY_FD");
+            CHECK_INTERFACE(IMediaRecorder, data, reply);
+            int fd = dup(data.readFileDescriptor());
+            reply->writeInt32(setOutputFileAuxiliary(fd));
+            return NO_ERROR;
+        } break;
         case SET_VIDEO_SIZE: {
             LOGV("SET_VIDEO_SIZE");
             CHECK_INTERFACE(IMediaRecorder, data, reply);
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index f3804b8..40801a2 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -21,7 +21,9 @@
     SET_PARAMETER,
     GET_CONFIG,
     SET_CONFIG,
+    ENABLE_GRAPHIC_BUFFERS,
     USE_BUFFER,
+    USE_GRAPHIC_BUFFER,
     ALLOC_BUFFER,
     ALLOC_BUFFER_WITH_BACKUP,
     FREE_BUFFER,
@@ -216,6 +218,19 @@
         return reply.readInt32();
     }
 
+    virtual status_t enableGraphicBuffers(
+            node_id node, OMX_U32 port_index, OMX_BOOL enable) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+        data.writeIntPtr((intptr_t)node);
+        data.writeInt32(port_index);
+        data.writeInt32((uint32_t)enable);
+        remote()->transact(ENABLE_GRAPHIC_BUFFERS, data, &reply);
+
+        status_t err = reply.readInt32();
+        return err;
+    }
+
     virtual status_t useBuffer(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer) {
@@ -238,6 +253,29 @@
         return err;
     }
 
+
+    virtual status_t useGraphicBuffer(
+            node_id node, OMX_U32 port_index,
+            const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+        data.writeIntPtr((intptr_t)node);
+        data.writeInt32(port_index);
+        data.write(*graphicBuffer);
+        remote()->transact(USE_GRAPHIC_BUFFER, data, &reply);
+
+        status_t err = reply.readInt32();
+        if (err != OK) {
+            *buffer = 0;
+
+            return err;
+        }
+
+        *buffer = (void*)reply.readIntPtr();
+
+        return err;
+    }
+
     virtual status_t allocateBuffer(
             node_id node, OMX_U32 port_index, size_t size,
             buffer_id *buffer, void **buffer_data) {
@@ -541,6 +579,20 @@
             return NO_ERROR;
         }
 
+        case ENABLE_GRAPHIC_BUFFERS:
+        {
+            CHECK_INTERFACE(IOMX, data, reply);
+
+            node_id node = (void*)data.readIntPtr();
+            OMX_U32 port_index = data.readInt32();
+            OMX_BOOL enable = (OMX_BOOL)data.readInt32();
+
+            status_t err = enableGraphicBuffers(node, port_index, enable);
+            reply->writeInt32(err);
+
+            return NO_ERROR;
+        }
+
         case USE_BUFFER:
         {
             CHECK_INTERFACE(IOMX, data, reply);
@@ -561,6 +613,27 @@
             return NO_ERROR;
         }
 
+        case USE_GRAPHIC_BUFFER:
+        {
+            CHECK_INTERFACE(IOMX, data, reply);
+
+            node_id node = (void*)data.readIntPtr();
+            OMX_U32 port_index = data.readInt32();
+            sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
+            data.read(*graphicBuffer);
+
+            buffer_id buffer;
+            status_t err = useGraphicBuffer(
+                    node, port_index, graphicBuffer, &buffer);
+            reply->writeInt32(err);
+
+            if (err == OK) {
+                reply->writeIntPtr((intptr_t)buffer);
+            }
+
+            return NO_ERROR;
+        }
+
         case ALLOC_BUFFER:
         {
             CHECK_INTERFACE(IOMX, data, reply);
diff --git a/media/libmedia/fixedfft.cpp b/media/libmedia/fixedfft.cpp
index 9cf05ba..2b495e6 100644
--- a/media/libmedia/fixedfft.cpp
+++ b/media/libmedia/fixedfft.cpp
@@ -26,7 +26,7 @@
 
 #include <stdio.h>
 #include <stdint.h>
-#ifdef __ARM_ARCH__
+#ifdef __arm__
 #include <machine/cpu-features.h>
 #endif
 
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 7f25359..51d91fe 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -308,6 +308,32 @@
     return ret;
 }
 
+status_t MediaRecorder::setOutputFileAuxiliary(int fd)
+{
+    LOGV("setOutputFileAuxiliary(%d)", fd);
+    if(mMediaRecorder == NULL) {
+        LOGE("media recorder is not initialized yet");
+        return INVALID_OPERATION;
+    }
+    if (mIsAuxiliaryOutputFileSet) {
+        LOGE("output file has already been set");
+        return INVALID_OPERATION;
+    }
+    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
+        LOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
+        return INVALID_OPERATION;
+    }
+
+    status_t ret = mMediaRecorder->setOutputFileAuxiliary(fd);
+    if (OK != ret) {
+        LOGV("setOutputFileAuxiliary failed: %d", ret);
+        mCurrentState = MEDIA_RECORDER_ERROR;
+        return ret;
+    }
+    mIsAuxiliaryOutputFileSet = true;
+    return ret;
+}
+
 status_t MediaRecorder::setVideoSize(int width, int height)
 {
     LOGV("setVideoSize(%d, %d)", width, height);
@@ -571,6 +597,7 @@
     mIsAudioEncoderSet = false;
     mIsVideoEncoderSet = false;
     mIsOutputFileSet   = false;
+    mIsAuxiliaryOutputFileSet = false;
 }
 
 // Release should be OK in any state
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index d9b0c69..ffe1983 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -737,8 +737,8 @@
 
     if (!strncasecmp(url, "rtsp://", 7)) {
         char value[PROPERTY_VALUE_MAX];
-        if (!property_get("media.stagefright.enable-rtsp", value, NULL)
-            || (strcmp(value, "1") && strcasecmp(value, "true"))) {
+        if (property_get("media.stagefright.enable-rtsp", value, NULL)
+            && (strcmp(value, "1") && strcasecmp(value, "true"))) {
             // For now, we're going to use PV for rtsp-based playback
             // by default until we can clear up a few more issues.
             return PV_PLAYER;
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 7e05043..be6a8be 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -164,6 +164,17 @@
     return mRecorder->setOutputFile(fd, offset, length);
 }
 
+status_t MediaRecorderClient::setOutputFileAuxiliary(int fd)
+{
+    LOGV("setOutputFileAuxiliary(%d)", fd);
+    Mutex::Autolock lock(mLock);
+    if (mRecorder == NULL) {
+        LOGE("recorder is not initialized");
+        return NO_INIT;
+    }
+    return mRecorder->setOutputFileAuxiliary(fd);
+}
+
 status_t MediaRecorderClient::setVideoSize(int width, int height)
 {
     LOGV("setVideoSize(%dx%d)", width, height);
@@ -295,8 +306,8 @@
     mPid = pid;
 
     char value[PROPERTY_VALUE_MAX];
-    if (property_get("media.stagefright.enable-record", value, NULL)
-        && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
+    if (!property_get("media.stagefright.enable-record", value, NULL)
+        || !strcmp(value, "1") || !strcasecmp(value, "true")) {
         mRecorder = new StagefrightRecorder;
     } else
 #ifndef NO_OPENCORE
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index 6c17217..fded98e 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -37,6 +37,7 @@
     virtual     status_t        setAudioEncoder(int ae);
     virtual     status_t        setOutputFile(const char* path);
     virtual     status_t        setOutputFile(int fd, int64_t offset, int64_t length);
+    virtual     status_t        setOutputFileAuxiliary(int fd);
     virtual     status_t        setVideoSize(int width, int height);
     virtual     status_t        setVideoFrameRate(int frames_per_second);
     virtual     status_t        setParameters(const String8& params);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index a24e56c..f1b8334 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -24,7 +24,9 @@
 #include <media/stagefright/AudioSource.h>
 #include <media/stagefright/AMRWriter.h>
 #include <media/stagefright/CameraSource.h>
+#include <media/stagefright/VideoSourceDownSampler.h>
 #include <media/stagefright/CameraSourceTimeLapse.h>
+#include <media/stagefright/MediaSourceSplitter.h>
 #include <media/stagefright/MPEG4Writer.h>
 #include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/MediaDefs.h>
@@ -46,8 +48,8 @@
 namespace android {
 
 StagefrightRecorder::StagefrightRecorder()
-    : mWriter(NULL),
-      mOutputFd(-1) {
+    : mWriter(NULL), mWriterAux(NULL),
+      mOutputFd(-1), mOutputFdAux(-1) {
 
     LOGV("Constructor");
     reset();
@@ -235,6 +237,24 @@
     return OK;
 }
 
+status_t StagefrightRecorder::setOutputFileAuxiliary(int fd) {
+    LOGV("setOutputFileAuxiliary: %d", fd);
+
+    if (fd < 0) {
+        LOGE("Invalid file descriptor: %d", fd);
+        return -EBADF;
+    }
+
+    mCaptureAuxVideo = true;
+
+    if (mOutputFdAux >= 0) {
+        ::close(mOutputFdAux);
+    }
+    mOutputFdAux = dup(fd);
+
+    return OK;
+}
+
 // Attempt to parse an int64 literal optionally surrounded by whitespace,
 // returns true on success, false otherwise.
 static bool safe_strtoi64(const char *s, int64_t *val) {
@@ -513,6 +533,42 @@
     return OK;
 }
 
+status_t StagefrightRecorder::setParamAuxVideoWidth(int32_t width) {
+    LOGV("setParamAuxVideoWidth : %d", width);
+
+    if (width <= 0) {
+        LOGE("Width (%d) is not positive", width);
+        return BAD_VALUE;
+    }
+
+    mAuxVideoWidth = width;
+    return OK;
+}
+
+status_t StagefrightRecorder::setParamAuxVideoHeight(int32_t height) {
+    LOGV("setParamAuxVideoHeight : %d", height);
+
+    if (height <= 0) {
+        LOGE("Height (%d) is not positive", height);
+        return BAD_VALUE;
+    }
+
+    mAuxVideoHeight = height;
+    return OK;
+}
+
+status_t StagefrightRecorder::setParamAuxVideoEncodingBitRate(int32_t bitRate) {
+    LOGV("StagefrightRecorder::setParamAuxVideoEncodingBitRate: %d", bitRate);
+
+    if (bitRate <= 0) {
+        LOGE("Invalid video encoding bit rate: %d", bitRate);
+        return BAD_VALUE;
+    }
+
+    mAuxVideoBitRate = bitRate;
+    return OK;
+}
+
 status_t StagefrightRecorder::setParameter(
         const String8 &key, const String8 &value) {
     LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
@@ -612,6 +668,21 @@
             return setParamTimeBetweenTimeLapseFrameCapture(
                     1000LL * timeBetweenTimeLapseFrameCaptureMs);
         }
+    } else if (key == "video-aux-param-width") {
+        int32_t auxWidth;
+        if (safe_strtoi32(value.string(), &auxWidth)) {
+            return setParamAuxVideoWidth(auxWidth);
+        }
+    } else if (key == "video-aux-param-height") {
+        int32_t auxHeight;
+        if (safe_strtoi32(value.string(), &auxHeight)) {
+            return setParamAuxVideoHeight(auxHeight);
+        }
+    } else if (key == "video-aux-param-encoding-bitrate") {
+        int32_t auxVideoBitRate;
+        if (safe_strtoi32(value.string(), &auxVideoBitRate)) {
+            return setParamAuxVideoEncodingBitRate(auxVideoBitRate);
+        }
     } else {
         LOGE("setParameter: failed to find key %s", key.string());
     }
@@ -842,7 +913,14 @@
     if (mAudioSource != AUDIO_SOURCE_LIST_END) {
         source = createAudioSource();
     } else {
-        status_t err = setupVideoEncoder(&source);
+
+        sp<CameraSource> cameraSource;
+        status_t err = setupCameraSource(&cameraSource);
+        if (err != OK) {
+            return err;
+        }
+
+        err = setupVideoEncoder(cameraSource, mVideoBitRate, &source);
         if (err != OK) {
             return err;
         }
@@ -906,7 +984,7 @@
     }
 }
 
-status_t StagefrightRecorder::setupCameraSource() {
+status_t StagefrightRecorder::setupCamera() {
     if (!mCaptureTimeLapse) {
         // Dont clip for time lapse capture as encoder will have enough
         // time to encode because of slow capture rate of time lapse.
@@ -989,20 +1067,27 @@
     }
 }
 
-status_t StagefrightRecorder::setupVideoEncoder(sp<MediaSource> *source) {
-    source->clear();
-
-    status_t err = setupCameraSource();
+status_t StagefrightRecorder::setupCameraSource(sp<CameraSource> *cameraSource) {
+    status_t err = setupCamera();
     if (err != OK) return err;
 
-    sp<CameraSource> cameraSource = (mCaptureTimeLapse) ?
+    *cameraSource = (mCaptureTimeLapse) ?
         CameraSourceTimeLapse::CreateFromCamera(mCamera, mUseStillCameraForTimeLapse,
                 mTimeBetweenTimeLapseFrameCaptureUs, mVideoWidth, mVideoHeight, mFrameRate):
         CameraSource::CreateFromCamera(mCamera);
-    CHECK(cameraSource != NULL);
+    CHECK(*cameraSource != NULL);
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setupVideoEncoder(
+        sp<MediaSource> cameraSource,
+        int32_t videoBitRate,
+        sp<MediaSource> *source) {
+    source->clear();
 
     sp<MetaData> enc_meta = new MetaData;
-    enc_meta->setInt32(kKeyBitRate, mVideoBitRate);
+    enc_meta->setInt32(kKeyBitRate, videoBitRate);
     enc_meta->setInt32(kKeySampleRate, mFrameRate);
 
     switch (mVideoEncoder) {
@@ -1046,6 +1131,13 @@
     }
     if (mVideoEncoderLevel != -1) {
         enc_meta->setInt32(kKeyVideoLevel, mVideoEncoderLevel);
+    } else if (mCaptureTimeLapse) {
+        // Check if we are using high resolution and/or high bitrate and
+        // set appropriate level for the software AVCEncoder.
+        if ((width * height >= 921600) // 720p
+                || (videoBitRate >= 20000000)) {
+            enc_meta->setInt32(kKeyVideoLevel, 50);
+        }
     }
 
     OMXClient client;
@@ -1087,51 +1179,139 @@
     return OK;
 }
 
-status_t StagefrightRecorder::startMPEG4Recording() {
-    int32_t totalBitRate = 0;
+status_t StagefrightRecorder::setupMPEG4Recording(
+        bool useSplitCameraSource,
+        int outputFd,
+        int32_t videoWidth, int32_t videoHeight,
+        int32_t videoBitRate,
+        int32_t *totalBitRate,
+        sp<MediaWriter> *mediaWriter) {
+    mediaWriter->clear();
+    *totalBitRate = 0;
     status_t err = OK;
-    sp<MediaWriter> writer = new MPEG4Writer(dup(mOutputFd));
+    sp<MediaWriter> writer = new MPEG4Writer(dup(outputFd));
 
     // Add audio source first if it exists
     if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) {
         err = setupAudioEncoder(writer);
         if (err != OK) return err;
-        totalBitRate += mAudioBitRate;
+        *totalBitRate += mAudioBitRate;
     }
     if (mVideoSource == VIDEO_SOURCE_DEFAULT
             || mVideoSource == VIDEO_SOURCE_CAMERA) {
+
+        sp<MediaSource> cameraMediaSource;
+        if (useSplitCameraSource) {
+            LOGV("Using Split camera source");
+            cameraMediaSource = mCameraSourceSplitter->createClient();
+        } else {
+            sp<CameraSource> cameraSource;
+            err = setupCameraSource(&cameraSource);
+            cameraMediaSource = cameraSource;
+        }
+        if ((videoWidth != mVideoWidth) || (videoHeight != mVideoHeight)) {
+            // Use downsampling from the original source.
+            CHECK(videoWidth <= mVideoWidth);
+            CHECK(videoHeight <= mVideoHeight);
+            cameraMediaSource =
+                new VideoSourceDownSampler(cameraMediaSource, videoWidth, videoHeight);
+        }
+        if (err != OK) {
+            return err;
+        }
+
         sp<MediaSource> encoder;
-        err = setupVideoEncoder(&encoder);
-        if (err != OK) return err;
+        err = setupVideoEncoder(cameraMediaSource, videoBitRate, &encoder);
+        if (err != OK) {
+            return err;
+        }
+
         writer->addSource(encoder);
-        totalBitRate += mVideoBitRate;
+        *totalBitRate += videoBitRate;
     }
 
     if (mInterleaveDurationUs > 0) {
         reinterpret_cast<MPEG4Writer *>(writer.get())->
             setInterleaveDuration(mInterleaveDurationUs);
     }
-
     if (mMaxFileDurationUs != 0) {
         writer->setMaxFileDuration(mMaxFileDurationUs);
     }
     if (mMaxFileSizeBytes != 0) {
         writer->setMaxFileSize(mMaxFileSizeBytes);
     }
-    sp<MetaData> meta = new MetaData;
-    meta->setInt64(kKeyTime, systemTime() / 1000);
-    meta->setInt32(kKeyFileType, mOutputFormat);
-    meta->setInt32(kKeyBitRate, totalBitRate);
-    meta->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
+
+    writer->setListener(mListener);
+    *mediaWriter = writer;
+    return OK;
+}
+
+void StagefrightRecorder::setupMPEG4MetaData(int64_t startTimeUs, int32_t totalBitRate,
+        sp<MetaData> *meta) {
+    (*meta)->setInt64(kKeyTime, startTimeUs);
+    (*meta)->setInt32(kKeyFileType, mOutputFormat);
+    (*meta)->setInt32(kKeyBitRate, totalBitRate);
+    (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
     if (mMovieTimeScale > 0) {
-        meta->setInt32(kKeyTimeScale, mMovieTimeScale);
+        (*meta)->setInt32(kKeyTimeScale, mMovieTimeScale);
     }
     if (mTrackEveryTimeDurationUs > 0) {
-        meta->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
+        (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
     }
-    writer->setListener(mListener);
-    mWriter = writer;
-    return mWriter->start(meta.get());
+}
+
+status_t StagefrightRecorder::startMPEG4Recording() {
+    if (mCaptureAuxVideo) {
+        LOGV("Creating MediaSourceSplitter");
+        sp<CameraSource> cameraSource;
+        status_t err = setupCameraSource(&cameraSource);
+        if (err != OK) {
+            return err;
+        }
+        mCameraSourceSplitter = new MediaSourceSplitter(cameraSource);
+    } else {
+        mCameraSourceSplitter = NULL;
+    }
+
+    int32_t totalBitRate;
+    status_t err = setupMPEG4Recording(mCaptureAuxVideo,
+            mOutputFd, mVideoWidth, mVideoHeight,
+            mVideoBitRate, &totalBitRate, &mWriter);
+    if (err != OK) {
+        return err;
+    }
+
+    int64_t startTimeUs = systemTime() / 1000;
+    sp<MetaData> meta = new MetaData;
+    setupMPEG4MetaData(startTimeUs, totalBitRate, &meta);
+
+    err = mWriter->start(meta.get());
+    if (err != OK) {
+        return err;
+    }
+
+    if (mCaptureAuxVideo) {
+        CHECK(mOutputFdAux >= 0);
+        if (mWriterAux != NULL) {
+            LOGE("Auxiliary File writer is not avaialble");
+            return UNKNOWN_ERROR;
+        }
+
+        int32_t totalBitrateAux;
+        err = setupMPEG4Recording(mCaptureAuxVideo,
+                mOutputFdAux, mAuxVideoWidth, mAuxVideoHeight,
+                mAuxVideoBitRate, &totalBitrateAux, &mWriterAux);
+        if (err != OK) {
+            return err;
+        }
+
+        sp<MetaData> metaAux = new MetaData;
+        setupMPEG4MetaData(startTimeUs, totalBitrateAux, &metaAux);
+
+        return mWriterAux->start(metaAux.get());
+    }
+
+    return OK;
 }
 
 status_t StagefrightRecorder::pause() {
@@ -1140,12 +1320,28 @@
         return UNKNOWN_ERROR;
     }
     mWriter->pause();
+
+    if (mCaptureAuxVideo) {
+        if (mWriterAux == NULL) {
+            return UNKNOWN_ERROR;
+        }
+        mWriterAux->pause();
+    }
+
     return OK;
 }
 
 status_t StagefrightRecorder::stop() {
     LOGV("stop");
     status_t err = OK;
+
+    if (mCaptureAuxVideo) {
+        if (mWriterAux != NULL) {
+            mWriterAux->stop();
+            mWriterAux.clear();
+        }
+    }
+
     if (mWriter != NULL) {
         err = mWriter->stop();
         mWriter.clear();
@@ -1169,6 +1365,13 @@
         mOutputFd = -1;
     }
 
+    if (mCaptureAuxVideo) {
+        if (mOutputFdAux >= 0) {
+            ::close(mOutputFdAux);
+            mOutputFdAux = -1;
+        }
+    }
+
     return err;
 }
 
@@ -1193,8 +1396,11 @@
     mVideoEncoder  = VIDEO_ENCODER_H263;
     mVideoWidth    = 176;
     mVideoHeight   = 144;
+    mAuxVideoWidth    = 176;
+    mAuxVideoHeight   = 144;
     mFrameRate     = 20;
     mVideoBitRate  = 192000;
+    mAuxVideoBitRate = 192000;
     mSampleRate    = 8000;
     mAudioChannels = 1;
     mAudioBitRate  = 12200;
@@ -1214,9 +1420,12 @@
     mCaptureTimeLapse = false;
     mUseStillCameraForTimeLapse = true;
     mTimeBetweenTimeLapseFrameCaptureUs = -1;
+    mCaptureAuxVideo = false;
+    mCameraSourceSplitter = NULL;
     mEncoderProfiles = MediaProfiles::getInstance();
 
     mOutputFd = -1;
+    mOutputFdAux = -1;
     mFlags = 0;
 
     return OK;
@@ -1254,6 +1463,8 @@
     snprintf(buffer, SIZE, "   Recorder: %p\n", this);
     snprintf(buffer, SIZE, "   Output file (fd %d):\n", mOutputFd);
     result.append(buffer);
+    snprintf(buffer, SIZE, "   Output file Auxiliary (fd %d):\n", mOutputFdAux);
+    result.append(buffer);
     snprintf(buffer, SIZE, "     File format: %d\n", mOutputFormat);
     result.append(buffer);
     snprintf(buffer, SIZE, "     Max file size (bytes): %lld\n", mMaxFileSizeBytes);
@@ -1298,10 +1509,14 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "     Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight);
     result.append(buffer);
+    snprintf(buffer, SIZE, "     Aux Frame size (pixels): %dx%d\n", mAuxVideoWidth, mAuxVideoHeight);
+    result.append(buffer);
     snprintf(buffer, SIZE, "     Frame rate (fps): %d\n", mFrameRate);
     result.append(buffer);
     snprintf(buffer, SIZE, "     Bit rate (bps): %d\n", mVideoBitRate);
     result.append(buffer);
+    snprintf(buffer, SIZE, "     Aux Bit rate (bps): %d\n", mAuxVideoBitRate);
+    result.append(buffer);
     ::write(fd, result.string(), result.size());
     return OK;
 }
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 628e19b..d50a393 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -24,8 +24,11 @@
 namespace android {
 
 class Camera;
+class CameraSource;
+class MediaSourceSplitter;
 struct MediaSource;
 struct MediaWriter;
+class MetaData;
 struct AudioSource;
 class MediaProfiles;
 
@@ -45,6 +48,7 @@
     virtual status_t setPreviewSurface(const sp<Surface>& surface);
     virtual status_t setOutputFile(const char *path);
     virtual status_t setOutputFile(int fd, int64_t offset, int64_t length);
+    virtual status_t setOutputFileAuxiliary(int fd);
     virtual status_t setParameters(const String8& params);
     virtual status_t setListener(const sp<IMediaRecorderClient>& listener);
     virtual status_t prepare();
@@ -65,7 +69,7 @@
     sp<Camera> mCamera;
     sp<Surface> mPreviewSurface;
     sp<IMediaRecorderClient> mListener;
-    sp<MediaWriter> mWriter;
+    sp<MediaWriter> mWriter, mWriterAux;
     sp<AudioSource> mAudioSourceNode;
 
     audio_source mAudioSource;
@@ -75,8 +79,9 @@
     video_encoder mVideoEncoder;
     bool mUse64BitFileOffset;
     int32_t mVideoWidth, mVideoHeight;
+    int32_t mAuxVideoWidth, mAuxVideoHeight;
     int32_t mFrameRate;
-    int32_t mVideoBitRate;
+    int32_t mVideoBitRate, mAuxVideoBitRate;
     int32_t mAudioBitRate;
     int32_t mAudioChannels;
     int32_t mSampleRate;
@@ -95,21 +100,36 @@
     bool mCaptureTimeLapse;
     bool mUseStillCameraForTimeLapse;
     int64_t mTimeBetweenTimeLapseFrameCaptureUs;
+    bool mCaptureAuxVideo;
+    sp<MediaSourceSplitter> mCameraSourceSplitter;
 
     String8 mParams;
-    int mOutputFd;
+    int mOutputFd, mOutputFdAux;
     int32_t mFlags;
 
     MediaProfiles *mEncoderProfiles;
 
+    status_t setupMPEG4Recording(
+        bool useSplitCameraSource,
+        int outputFd,
+        int32_t videoWidth, int32_t videoHeight,
+        int32_t videoBitRate,
+        int32_t *totalBitRate,
+        sp<MediaWriter> *mediaWriter);
+    void setupMPEG4MetaData(int64_t startTimeUs, int32_t totalBitRate,
+        sp<MetaData> *meta);
     status_t startMPEG4Recording();
     status_t startAMRRecording();
     status_t startAACRecording();
     status_t startRTPRecording();
     sp<MediaSource> createAudioSource();
-    status_t setupCameraSource();
+    status_t setupCamera();
+    status_t setupCameraSource(sp<CameraSource> *cameraSource);
     status_t setupAudioEncoder(const sp<MediaWriter>& writer);
-    status_t setupVideoEncoder(sp<MediaSource> *source);
+    status_t setupVideoEncoder(
+            sp<MediaSource> cameraSource,
+            int32_t videoBitRate,
+            sp<MediaSource> *source);
 
     // Encoding parameter handling utilities
     status_t setParameter(const String8 &key, const String8 &value);
@@ -120,6 +140,9 @@
     status_t setParamTimeLapseEnable(int32_t timeLapseEnable);
     status_t setParamUseStillCameraForTimeLapse(int32_t useStillCamera);
     status_t setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs);
+    status_t setParamAuxVideoHeight(int32_t height);
+    status_t setParamAuxVideoWidth(int32_t width);
+    status_t setParamAuxVideoEncodingBitRate(int32_t bitRate);
     status_t setParamVideoEncodingBitRate(int32_t bitRate);
     status_t setParamVideoIFramesInterval(int32_t seconds);
     status_t setParamVideoEncoderProfile(int32_t profile);
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index b5a6327..0d11b33 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -10,7 +10,8 @@
         AudioSource.cpp                   \
         AwesomePlayer.cpp                 \
         CameraSource.cpp                  \
-        CameraSourceTimeLapse.cpp                  \
+        CameraSourceTimeLapse.cpp         \
+        VideoSourceDownSampler.cpp        \
         DataSource.cpp                    \
         ESDS.cpp                          \
         FileSource.cpp                    \
@@ -24,6 +25,7 @@
         MediaDefs.cpp                     \
         MediaExtractor.cpp                \
         MediaSource.cpp                   \
+        MediaSourceSplitter.cpp           \
         MetaData.cpp                      \
         NuCachedSource2.cpp               \
         NuHTTPDataSource.cpp              \
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 4c729e4..c2f79e8 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -72,6 +72,10 @@
         return UNKNOWN_ERROR;
     }
 
+    if (mInitCheck != OK) {
+        return NO_INIT;
+    }
+
     char value[PROPERTY_VALUE_MAX];
     if (property_get("media.stagefright.record-stats", value, NULL)
         && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
@@ -80,6 +84,7 @@
 
     mTrackMaxAmplitude = false;
     mMaxAmplitude = 0;
+    mInitialReadTimeUs = 0;
     mStartTimeUs = 0;
     int64_t startTimeUs;
     if (params && params->findInt64(kKeyTime, &startTimeUs)) {
@@ -102,6 +107,10 @@
         return UNKNOWN_ERROR;
     }
 
+    if (mInitCheck != OK) {
+        return NO_INIT;
+    }
+
     mRecord->stop();
 
     delete mGroup;
@@ -118,6 +127,10 @@
 }
 
 sp<MetaData> AudioSource::getFormat() {
+    if (mInitCheck != OK) {
+        return 0;
+    }
+
     sp<MetaData> meta = new MetaData;
     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
     meta->setInt32(kKeySampleRate, mRecord->getSampleRate());
@@ -193,6 +206,12 @@
 
 status_t AudioSource::read(
         MediaBuffer **out, const ReadOptions *options) {
+
+    if (mInitCheck != OK) {
+        return NO_INIT;
+    }
+
+    int64_t readTimeUs = systemTime() / 1000;
     *out = NULL;
 
     MediaBuffer *buffer;
@@ -206,9 +225,10 @@
 
 
         if (numFramesRecorded == 0 && mPrevSampleTimeUs == 0) {
+            mInitialReadTimeUs = readTimeUs;
             // Initial delay
             if (mStartTimeUs > 0) {
-                mStartTimeUs = systemTime() / 1000 - mStartTimeUs;
+                mStartTimeUs = readTimeUs - mStartTimeUs;
             } else {
                 // Assume latency is constant.
                 mStartTimeUs += mRecord->latency() * 1000;
@@ -254,7 +274,10 @@
             }
             memset(buffer->data(), 0, numLostBytes);
             buffer->set_range(0, numLostBytes);
-            buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
+            if (numFramesRecorded == 0) {
+                buffer->meta_data()->setInt64(kKeyTime, mStartTimeUs);
+            }
+            buffer->meta_data()->setInt64(kKeyDriftTime, readTimeUs - mInitialReadTimeUs);
             mPrevSampleTimeUs = timestampUs;
             *out = buffer;
             return OK;
@@ -292,12 +315,11 @@
             trackMaxAmplitude((int16_t *) buffer->data(), n >> 1);
         }
 
-        buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
-        CHECK(timestampUs > mPrevSampleTimeUs);
-        if (mTotalLostFrames == 0) {
-            CHECK_EQ(mPrevSampleTimeUs,
-                mStartTimeUs + (1000000LL * numFramesRecorded) / sampleRate);
+        if (numFramesRecorded == 0) {
+            buffer->meta_data()->setInt64(kKeyTime, mStartTimeUs);
         }
+        buffer->meta_data()->setInt64(kKeyDriftTime, readTimeUs - mInitialReadTimeUs);
+        CHECK(timestampUs > mPrevSampleTimeUs);
         mPrevSampleTimeUs = timestampUs;
         LOGV("initial delay: %lld, sample rate: %d, timestamp: %lld",
                 mStartTimeUs, sampleRate, timestampUs);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index f0fa5f9..fd5f30b 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -50,6 +50,9 @@
 
 namespace android {
 
+static int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
+static int64_t kHighWaterMarkUs = 10000000ll;  // 10secs
+
 struct AwesomeEvent : public TimedEventQueue::Event {
     AwesomeEvent(
             AwesomePlayer *player,
@@ -274,9 +277,13 @@
 status_t AwesomePlayer::setDataSource(
         int fd, int64_t offset, int64_t length) {
 #if 0
+    // return setDataSource("httplive://qthttp.apple.com.edgesuite.net/1009qpeijrfn/sl.m3u8");
+    return setDataSource("httplive://qthttp.apple.com.edgesuite.net/1009qpeijrfn/0440.m3u8");
+    // return setDataSource("httplive://qthttp.apple.com.edgesuite.net/1009qpeijrfn/0640.m3u8");
+    // return setDataSource("httplive://qthttp.apple.com.edgesuite.net/1009qpeijrfn/1240_vod.m3u8");
     // return setDataSource("httplive://iphoned5.akamai.com.edgesuite.net/mhbarron/nasatv/nasatv_96.m3u8");
     // return setDataSource("httplive://iphoned5.akamai.com.edgesuite.net/mhbarron/nasatv/nasatv_1500.m3u8");
-    return setDataSource("httplive://iphone.video.hsn.com/iPhone_high.m3u8");
+    // return setDataSource("httplive://iphone.video.hsn.com/iPhone_high.m3u8");
     // return setDataSource("httplive://iphoned5.akamai.com.edgesuite.net/mhbarron/iphonewebcast/webcast090209_all/webcast090209_all.m3u8");
     // return setDataSource("httplive://qthttp.akamai.com.edgesuite.net/iphone_demo/Video_Content/usat/tt_062209_iphone/hi/prog_index.m3u8");
     // return setDataSource("httplive://qthttp.akamai.com.edgesuite.net/iphone_demo/Video_Content/usat/tt_googmaps/hi/prog_index.m3u8");
@@ -326,6 +333,13 @@
         } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
             setAudioSource(extractor->getTrack(i));
             haveAudio = true;
+
+            sp<MetaData> fileMeta = extractor->getMetaData();
+            int32_t loop;
+            if (fileMeta != NULL
+                    && fileMeta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
+                mFlags |= AUTO_LOOPING;
+            }
         }
 
         if (haveAudio && haveVideo) {
@@ -449,6 +463,25 @@
     }
 }
 
+// Returns true iff cached duration is available/applicable.
+bool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
+    off_t totalSize;
+
+    if (mRTSPController != NULL) {
+        *durationUs = mRTSPController->getQueueDurationUs(eos);
+        return true;
+    } else if (mCachedSource != NULL && mDurationUs >= 0
+            && mCachedSource->getSize(&totalSize) == OK) {
+        int64_t bitrate = totalSize * 8000000ll / mDurationUs;  // in bits/sec
+
+        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(eos);
+        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
+        return true;
+    }
+
+    return false;
+}
+
 void AwesomePlayer::onBufferingUpdate() {
     Mutex::Autolock autoLock(mLock);
     if (!mBufferingEventPending) {
@@ -456,49 +489,80 @@
     }
     mBufferingEventPending = false;
 
-    if (mCachedSource == NULL) {
-        return;
-    }
+    if (mCachedSource != NULL) {
+        bool eos;
+        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&eos);
 
-    bool eos;
-    size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&eos);
+        if (eos) {
+            notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
+        } else {
+            off_t size;
+            if (mDurationUs >= 0 && mCachedSource->getSize(&size) == OK) {
+                int64_t bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
 
-    size_t lowWatermark = 400000;
-    size_t highWatermark = 1000000;
+                size_t cachedSize = mCachedSource->cachedSize();
+                int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
 
-    if (eos) {
-        notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
-    } else {
-        off_t size;
-        if (mDurationUs >= 0 && mCachedSource->getSize(&size) == OK) {
-            int64_t bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
+                int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
+                if (percentage > 100) {
+                    percentage = 100;
+                }
 
-            size_t cachedSize = mCachedSource->cachedSize();
-            int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
+                notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
+            } else {
+                // We don't know the bitrate of the stream, use absolute size
+                // limits to maintain the cache.
 
-            int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
-            if (percentage > 100) {
-                percentage = 100;
+                const size_t kLowWaterMarkBytes = 400000;
+                const size_t kHighWaterMarkBytes = 1000000;
+
+                if ((mFlags & PLAYING) && !eos
+                        && (cachedDataRemaining < kLowWaterMarkBytes)) {
+                    LOGI("cache is running low (< %d) , pausing.",
+                         kLowWaterMarkBytes);
+                    mFlags |= CACHE_UNDERRUN;
+                    pause_l();
+                    notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
+                } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
+                    if (mFlags & CACHE_UNDERRUN) {
+                        LOGI("cache has filled up (> %d), resuming.",
+                             kHighWaterMarkBytes);
+                        mFlags &= ~CACHE_UNDERRUN;
+                        play_l();
+                        notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
+                    } else if (mFlags & PREPARING) {
+                        LOGV("cache has filled up (> %d), prepare is done",
+                             kHighWaterMarkBytes);
+                        finishAsyncPrepare_l();
+                    }
+                }
             }
-
-            notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
-
-            lowWatermark = 2 * bitrate / 8;  // 2 secs
-            highWatermark = 10 * bitrate / 8;  // 10 secs
         }
     }
 
-    if ((mFlags & PLAYING) && !eos && (cachedDataRemaining < lowWatermark)) {
-        LOGI("cache is running low (< %d) , pausing.", lowWatermark);
-        mFlags |= CACHE_UNDERRUN;
-        pause_l();
-        notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
-    } else if ((mFlags & CACHE_UNDERRUN)
-            && (eos || cachedDataRemaining > highWatermark)) {
-        LOGI("cache has filled up (> %d), resuming.", highWatermark);
-        mFlags &= ~CACHE_UNDERRUN;
-        play_l();
-        notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
+    int64_t cachedDurationUs;
+    bool eos;
+    if (getCachedDuration_l(&cachedDurationUs, &eos)) {
+        if ((mFlags & PLAYING) && !eos
+                && (cachedDurationUs < kLowWaterMarkUs)) {
+            LOGI("cache is running low (%.2f secs) , pausing.",
+                 cachedDurationUs / 1E6);
+            mFlags |= CACHE_UNDERRUN;
+            pause_l();
+            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
+        } else if (eos || cachedDurationUs > kHighWaterMarkUs) {
+            if (mFlags & CACHE_UNDERRUN) {
+                LOGI("cache has filled up (%.2f secs), resuming.",
+                     cachedDurationUs / 1E6);
+                mFlags &= ~CACHE_UNDERRUN;
+                play_l();
+                notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
+            } else if (mFlags & PREPARING) {
+                LOGV("cache has filled up (%.2f secs), prepare is done",
+                     cachedDurationUs / 1E6);
+                finishAsyncPrepare_l();
+            }
+        }
     }
 
     postBufferingEvent_l();
@@ -533,7 +597,7 @@
         return;
     }
 
-    if (mFlags & LOOPING) {
+    if (mFlags & (LOOPING | AUTO_LOOPING)) {
         seekTo_l(0);
 
         if (mVideoSource != NULL) {
@@ -1263,6 +1327,7 @@
     } else if (!strncmp("rtsp://gtalk/", mUri.string(), 13)) {
         if (mLooper == NULL) {
             mLooper = new ALooper;
+            mLooper->setName("gtalk rtp");
             mLooper->start(
                     false /* runOnCallingThread */,
                     false /* canCallJava */,
@@ -1374,6 +1439,7 @@
     } else if (!strncasecmp("rtsp://", mUri.string(), 7)) {
         if (mLooper == NULL) {
             mLooper = new ALooper;
+            mLooper->setName("rtsp");
             mLooper->start();
         }
         mRTSPController = new ARTSPController(mLooper);
@@ -1426,45 +1492,49 @@
 }
 
 void AwesomePlayer::onPrepareAsyncEvent() {
-    {
-        Mutex::Autolock autoLock(mLock);
+    Mutex::Autolock autoLock(mLock);
 
-        if (mFlags & PREPARE_CANCELLED) {
-            LOGI("prepare was cancelled before doing anything");
-            abortPrepare(UNKNOWN_ERROR);
+    if (mFlags & PREPARE_CANCELLED) {
+        LOGI("prepare was cancelled before doing anything");
+        abortPrepare(UNKNOWN_ERROR);
+        return;
+    }
+
+    if (mUri.size() > 0) {
+        status_t err = finishSetDataSource_l();
+
+        if (err != OK) {
+            abortPrepare(err);
             return;
         }
-
-        if (mUri.size() > 0) {
-            status_t err = finishSetDataSource_l();
-
-            if (err != OK) {
-                abortPrepare(err);
-                return;
-            }
-        }
-
-        if (mVideoTrack != NULL && mVideoSource == NULL) {
-            status_t err = initVideoDecoder();
-
-            if (err != OK) {
-                abortPrepare(err);
-                return;
-            }
-        }
-
-        if (mAudioTrack != NULL && mAudioSource == NULL) {
-            status_t err = initAudioDecoder();
-
-            if (err != OK) {
-                abortPrepare(err);
-                return;
-            }
-        }
     }
 
-    Mutex::Autolock autoLock(mLock);
+    if (mVideoTrack != NULL && mVideoSource == NULL) {
+        status_t err = initVideoDecoder();
 
+        if (err != OK) {
+            abortPrepare(err);
+            return;
+        }
+    }
+
+    if (mAudioTrack != NULL && mAudioSource == NULL) {
+        status_t err = initAudioDecoder();
+
+        if (err != OK) {
+            abortPrepare(err);
+            return;
+        }
+    }
+
+    if (mCachedSource != NULL || mRTSPController != NULL) {
+        postBufferingEvent_l();
+    } else {
+        finishAsyncPrepare_l();
+    }
+}
+
+void AwesomePlayer::finishAsyncPrepare_l() {
     if (mIsAsyncPrepare) {
         if (mVideoSource == NULL) {
             notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
@@ -1480,8 +1550,6 @@
     mFlags |= PREPARED;
     mAsyncPrepareEvent = NULL;
     mPreparedCondition.broadcast();
-
-    postBufferingEvent_l();
 }
 
 status_t AwesomePlayer::suspend() {
@@ -1521,7 +1589,7 @@
     state->mUriHeaders = mUriHeaders;
     state->mFileSource = mFileSource;
 
-    state->mFlags = mFlags & (PLAYING | LOOPING | AT_EOS);
+    state->mFlags = mFlags & (PLAYING | AUTO_LOOPING | LOOPING | AT_EOS);
     getPosition(&state->mPositionUs);
 
     if (mLastVideoBuffer) {
@@ -1582,7 +1650,7 @@
 
     seekTo_l(state->mPositionUs);
 
-    mFlags = state->mFlags & (LOOPING | AT_EOS);
+    mFlags = state->mFlags & (AUTO_LOOPING | LOOPING | AT_EOS);
 
     if (state->mLastVideoFrame && (mSurface != NULL || mISurface != NULL)) {
         mVideoRenderer =
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index a15b84e..806836d 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -32,12 +32,12 @@
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/Utils.h>
 #include <media/mediarecorder.h>
-#include <cutils/properties.h>
 
 #include "include/ESDS.h"
 
 namespace android {
 
+static const int64_t kMax32BitFileSize = 0x007fffffffLL;
 static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
 static const uint8_t kNalUnitTypePicParamSet = 0x08;
 
@@ -59,7 +59,7 @@
     bool isAvc() const { return mIsAvc; }
     bool isAudio() const { return mIsAudio; }
     bool isMPEG4() const { return mIsMPEG4; }
-    void addChunkOffset(off_t offset) { mChunkOffsets.push_back(offset); }
+    void addChunkOffset(off_t offset);
     status_t dump(int fd, const Vector<String16>& args) const;
 
 private:
@@ -79,7 +79,7 @@
     bool mIsRealTimeRecording;
     int64_t mMaxTimeStampUs;
     int64_t mEstimatedTrackSizeBytes;
-    int64_t mMaxWriteTimeUs;
+    int64_t mMdatSizeBytes;
     int32_t mTimeScale;
 
     pthread_t mThread;
@@ -92,8 +92,11 @@
     bool                mSamplesHaveSameSize;
 
     List<MediaBuffer *> mChunkSamples;
+
+    size_t              mNumStcoTableEntries;
     List<off_t>         mChunkOffsets;
 
+    size_t              mNumStscTableEntries;
     struct StscTableEntry {
 
         StscTableEntry(uint32_t chunk, uint32_t samples, uint32_t id)
@@ -107,9 +110,10 @@
     };
     List<StscTableEntry> mStscTableEntries;
 
+    size_t        mNumStssTableEntries;
     List<int32_t> mStssTableEntries;
-    List<int64_t> mChunkDurations;
 
+    size_t        mNumSttsTableEntries;
     struct SttsTableEntry {
 
         SttsTableEntry(uint32_t count, uint32_t durationUs)
@@ -161,12 +165,6 @@
     void trackProgressStatus(int64_t timeUs, status_t err = OK);
     void initTrackingProgressStatus(MetaData *params);
 
-    // Utilities for collecting statistical data
-    void logStatisticalData(bool isAudio);
-    void findMinAvgMaxSampleDurationMs(
-            int32_t *min, int32_t *avg, int32_t *max);
-    void findMinMaxChunkDurations(int64_t *min, int64_t *max);
-
     void getCodecSpecificDataFromInputFormatIfPossible();
 
     // Determine the track time scale
@@ -178,14 +176,18 @@
     // Simple validation on the codec specific data
     status_t checkCodecSpecificData() const;
 
+    void updateTrackSizeEstimate();
+    void addOneStscTableEntry(size_t chunkId, size_t sampleId);
+    void addOneStssTableEntry(size_t sampleId);
+    void addOneSttsTableEntry(size_t sampleCount, int64_t durationUs);
+
     Track(const Track &);
     Track &operator=(const Track &);
 };
 
-#define USE_NALLEN_FOUR         1
-
 MPEG4Writer::MPEG4Writer(const char *filename)
     : mFile(fopen(filename, "wb")),
+      mUse4ByteNalLength(true),
       mUse32BitOffset(true),
       mPaused(false),
       mStarted(false),
@@ -198,6 +200,7 @@
 
 MPEG4Writer::MPEG4Writer(int fd)
     : mFile(fdopen(fd, "wb")),
+      mUse4ByteNalLength(true),
       mUse32BitOffset(true),
       mPaused(false),
       mStarted(false),
@@ -211,9 +214,11 @@
 MPEG4Writer::~MPEG4Writer() {
     stop();
 
-    for (List<Track *>::iterator it = mTracks.begin();
-         it != mTracks.end(); ++it) {
+    while (!mTracks.empty()) {
+        List<Track *>::iterator it = mTracks.begin();
         delete *it;
+        (*it) = NULL;
+        mTracks.erase(it);
     }
     mTracks.clear();
 }
@@ -332,11 +337,26 @@
         mUse32BitOffset = false;
     }
 
-    // System property can overwrite the file offset bits parameter
-    char value[PROPERTY_VALUE_MAX];
-    if (property_get("media.stagefright.record-64bits", value, NULL)
-        && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
-        mUse32BitOffset = false;
+    if (mUse32BitOffset) {
+        // Implicit 32 bit file size limit
+        if (mMaxFileSizeLimitBytes == 0) {
+            mMaxFileSizeLimitBytes = kMax32BitFileSize;
+        }
+
+        // If file size is set to be larger than the 32 bit file
+        // size limit, treat it as an error.
+        if (mMaxFileSizeLimitBytes > kMax32BitFileSize) {
+            LOGE("32-bit file size limit too big: %lld bytes",
+                mMaxFileSizeLimitBytes);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    int32_t use2ByteNalLength;
+    if (param &&
+        param->findInt32(kKey2ByteNalLength, &use2ByteNalLength) &&
+        use2ByteNalLength) {
+        mUse4ByteNalLength = false;
     }
 
     mStartTimestampUs = -1;
@@ -413,6 +433,10 @@
     return OK;
 }
 
+bool MPEG4Writer::use32BitFileOffset() const {
+    return mUse32BitOffset;
+}
+
 status_t MPEG4Writer::pause() {
     if (mFile == NULL) {
         return OK;
@@ -607,32 +631,30 @@
 
     size_t length = buffer->range_length();
 
-#if USE_NALLEN_FOUR
-    uint8_t x = length >> 24;
-    fwrite(&x, 1, 1, mFile);
-    x = (length >> 16) & 0xff;
-    fwrite(&x, 1, 1, mFile);
-    x = (length >> 8) & 0xff;
-    fwrite(&x, 1, 1, mFile);
-    x = length & 0xff;
-    fwrite(&x, 1, 1, mFile);
-#else
-    CHECK(length < 65536);
+    if (mUse4ByteNalLength) {
+        uint8_t x = length >> 24;
+        fwrite(&x, 1, 1, mFile);
+        x = (length >> 16) & 0xff;
+        fwrite(&x, 1, 1, mFile);
+        x = (length >> 8) & 0xff;
+        fwrite(&x, 1, 1, mFile);
+        x = length & 0xff;
+        fwrite(&x, 1, 1, mFile);
 
-    uint8_t x = length >> 8;
-    fwrite(&x, 1, 1, mFile);
-    x = length & 0xff;
-    fwrite(&x, 1, 1, mFile);
-#endif
+        fwrite((const uint8_t *)buffer->data() + buffer->range_offset(),
+                1, length, mFile);
+        mOffset += length + 4;
+    } else {
+        CHECK(length < 65536);
 
-    fwrite((const uint8_t *)buffer->data() + buffer->range_offset(),
-           1, length, mFile);
-
-#if USE_NALLEN_FOUR
-    mOffset += length + 4;
-#else
-    mOffset += length + 2;
-#endif
+        uint8_t x = length >> 8;
+        fwrite(&x, 1, 1, mFile);
+        x = length & 0xff;
+        fwrite(&x, 1, 1, mFile);
+        fwrite((const uint8_t *)buffer->data() + buffer->range_offset(),
+                1, length, mFile);
+        mOffset += length + 2;
+    }
 
     return old_offset;
 }
@@ -739,7 +761,8 @@
          it != mTracks.end(); ++it) {
         nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
     }
-    return (nTotalBytesEstimate >= mMaxFileSizeLimitBytes);
+
+    return (nTotalBytesEstimate  + 1024 >= mMaxFileSizeLimitBytes);
 }
 
 bool MPEG4Writer::exceedsFileDurationLimit() {
@@ -819,6 +842,48 @@
     setTimeScale();
 }
 
+void MPEG4Writer::Track::updateTrackSizeEstimate() {
+
+    int64_t stcoBoxSizeBytes = mOwner->use32BitFileOffset()
+                                ? mNumStcoTableEntries * 4
+                                : mNumStcoTableEntries * 8;
+
+    int64_t stszBoxSizeBytes = mSamplesHaveSameSize? 4: (mNumSamples * 4);
+
+    mEstimatedTrackSizeBytes = mMdatSizeBytes +             // media data size
+                               mNumStscTableEntries * 12 +  // stsc box size
+                               mNumStssTableEntries * 4 +   // stss box size
+                               mNumSttsTableEntries * 8 +   // stts box size
+                               stcoBoxSizeBytes +           // stco box size
+                               stszBoxSizeBytes;            // stsz box size
+}
+
+void MPEG4Writer::Track::addOneStscTableEntry(
+        size_t chunkId, size_t sampleId) {
+
+        StscTableEntry stscEntry(chunkId, sampleId, 1);
+        mStscTableEntries.push_back(stscEntry);
+        ++mNumStscTableEntries;
+}
+
+void MPEG4Writer::Track::addOneStssTableEntry(size_t sampleId) {
+    mStssTableEntries.push_back(sampleId);
+    ++mNumStssTableEntries;
+}
+
+void MPEG4Writer::Track::addOneSttsTableEntry(
+        size_t sampleCount, int64_t durationUs) {
+
+    SttsTableEntry sttsEntry(sampleCount, durationUs);
+    mSttsTableEntries.push_back(sttsEntry);
+    ++mNumSttsTableEntries;
+}
+
+void MPEG4Writer::Track::addChunkOffset(off_t offset) {
+    ++mNumStcoTableEntries;
+    mChunkOffsets.push_back(offset);
+}
+
 void MPEG4Writer::Track::setTimeScale() {
     LOGV("setTimeScale");
     // Default time scale
@@ -1039,6 +1104,7 @@
     return OK;
 }
 
+
 status_t MPEG4Writer::Track::start(MetaData *params) {
     if (!mDone && mPaused) {
         mPaused = false;
@@ -1077,6 +1143,11 @@
     mTrackDurationUs = 0;
     mReachedEOS = false;
     mEstimatedTrackSizeBytes = 0;
+    mNumStcoTableEntries = 0;
+    mNumStssTableEntries = 0;
+    mNumStscTableEntries = 0;
+    mNumSttsTableEntries = 0;
+    mMdatSizeBytes = 0;
 
     pthread_create(&mThread, &attr, ThreadWrapper, this);
     pthread_attr_destroy(&attr);
@@ -1123,46 +1194,6 @@
     return (void *) err;
 }
 
-#include <ctype.h>
-static void hexdump(const void *_data, size_t size) {
-    const uint8_t *data = (const uint8_t *)_data;
-    size_t offset = 0;
-    while (offset < size) {
-        printf("0x%04x  ", offset);
-
-        size_t n = size - offset;
-        if (n > 16) {
-            n = 16;
-        }
-
-        for (size_t i = 0; i < 16; ++i) {
-            if (i == 8) {
-                printf(" ");
-            }
-
-            if (offset + i < size) {
-                printf("%02x ", data[offset + i]);
-            } else {
-                printf("   ");
-            }
-        }
-
-        printf(" ");
-
-        for (size_t i = 0; i < n; ++i) {
-            if (isprint(data[offset + i])) {
-                printf("%c", data[offset + i]);
-            } else {
-                printf(".");
-            }
-        }
-
-        printf("\n");
-
-        offset += 16;
-    }
-}
-
 static void getNalUnitType(uint8_t byte, uint8_t* type) {
     LOGV("getNalUnitType: %d", byte);
 
@@ -1334,7 +1365,6 @@
 
 status_t MPEG4Writer::Track::makeAVCCodecSpecificData(
         const uint8_t *data, size_t size) {
-    // hexdump(data, size);
 
     if (mCodecSpecificData != NULL) {
         LOGE("Already have codec specific data");
@@ -1365,11 +1395,11 @@
     header[3] = mLevelIdc;
 
     // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne
-#if USE_NALLEN_FOUR
-    header[4] = 0xfc | 3;  // length size == 4 bytes
-#else
-    header[4] = 0xfc | 1;  // length size == 2 bytes
-#endif
+    if (mOwner->useNalLengthFour()) {
+        header[4] = 0xfc | 3;  // length size == 4 bytes
+    } else {
+        header[4] = 0xfc | 1;  // length size == 2 bytes
+    }
 
     // 3-bit '111' followed by 5-bit numSequenceParameterSets
     int nSequenceParamSets = mSeqParamSets.size();
@@ -1406,15 +1436,6 @@
     return OK;
 }
 
-static bool collectStatisticalData() {
-    char value[PROPERTY_VALUE_MAX];
-    if (property_get("media.stagefright.record-stats", value, NULL)
-        && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
-        return true;
-    }
-    return false;
-}
-
 status_t MPEG4Writer::Track::threadEntry() {
     int32_t count = 0;
     const int64_t interleaveDurationUs = mOwner->interleaveDuration();
@@ -1430,14 +1451,9 @@
     int64_t previousPausedDurationUs = 0;
     int64_t timestampUs;
 
-    int64_t wallClockTimeUs = 0;
-    int64_t lastWallClockTimeUs = 0;
-
     sp<MetaData> meta_data;
-    bool collectStats = collectStatisticalData();
 
     mNumSamples = 0;
-    mMaxWriteTimeUs = 0;
     status_t err = OK;
     MediaBuffer *buffer;
     while (!mDone && (err = mSource->read(&buffer)) == OK) {
@@ -1498,17 +1514,19 @@
 
         if (mIsAvc) StripStartcode(copy);
 
-        size_t sampleSize;
-        sampleSize = mIsAvc
-#if USE_NALLEN_FOUR
-                ? copy->range_length() + 4
-#else
-                ? copy->range_length() + 2
-#endif
-                : copy->range_length();
+        size_t sampleSize = copy->range_length();
+        if (mIsAvc) {
+            if (mOwner->useNalLengthFour()) {
+                sampleSize += 4;
+            } else {
+                sampleSize += 2;
+            }
+        }
 
         // Max file size or duration handling
-        mEstimatedTrackSizeBytes += sampleSize;
+        mMdatSizeBytes += sampleSize;
+        updateTrackSizeEstimate();
+
         if (mOwner->exceedsFileSizeLimit()) {
             mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
             break;
@@ -1542,14 +1560,15 @@
             // of neighboring samples. This in turn helps reduce the track header size,
             // especially, the number of entries in the "stts" box.
             if (mNumSamples > 1) {
-                int64_t durationUs = timestampUs + mOwner->getDriftTimeUs() - lastTimestampUs;
+                int64_t currDriftTimeUs = mOwner->getDriftTimeUs();
+                int64_t durationUs = timestampUs + currDriftTimeUs - lastTimestampUs;
                 int64_t diffUs = (durationUs > lastDurationUs)
                             ? durationUs - lastDurationUs
                             : lastDurationUs - durationUs;
                 if (diffUs <= 5000) {  // XXX: Magic number 5ms
                     timestampUs = lastTimestampUs + lastDurationUs;
                 } else {
-                    timestampUs += mOwner->getDriftTimeUs();
+                    timestampUs += currDriftTimeUs;
                 }
             }
         }
@@ -1557,12 +1576,6 @@
         if (mNumSamples > 1) {
             if (timestampUs <= lastTimestampUs) {
                 LOGW("Frame arrives too late!");
-#if 0
-                // Drop the late frame.
-                copy->release();
-                copy = NULL;
-                continue;
-#else
                 // Don't drop the late frame, since dropping a frame may cause
                 // problems later during playback
 
@@ -1573,7 +1586,6 @@
                 } else {
                     timestampUs = lastTimestampUs + (1000000LL + (mTimeScale >> 1)) / mTimeScale;
                 }
-#endif
             }
         }
 
@@ -1596,8 +1608,7 @@
                      (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
 
             if (currDurationTicks != lastDurationTicks) {
-                SttsTableEntry sttsEntry(sampleCount, lastDurationUs);
-                mSttsTableEntries.push_back(sttsEntry);
+                addOneSttsTableEntry(sampleCount, lastDurationUs);
                 sampleCount = 1;
             } else {
                 ++sampleCount;
@@ -1613,16 +1624,14 @@
         lastDurationTicks = currDurationTicks;
         lastTimestampUs = timestampUs;
         if (mIsRealTimeRecording && mIsAudio) {
-            wallClockTimeUs = systemTime() / 1000;
-            int64_t wallClockDurationUs = wallClockTimeUs - lastWallClockTimeUs;
-            if (mNumSamples > 2) {
-                mOwner->addDriftTimeUs(lastDurationUs - wallClockDurationUs);
+            int64_t driftTimeUs = 0;
+            if (meta_data->findInt64(kKeyDriftTime, &driftTimeUs)) {
+                mOwner->setDriftTimeUs(driftTimeUs);
             }
-            lastWallClockTimeUs = wallClockTimeUs;
         }
 
         if (isSync != 0) {
-            mStssTableEntries.push_back(mNumSamples);
+            addOneStssTableEntry(mNumSamples);
         }
 
         if (mTrackingProgressStatus) {
@@ -1635,7 +1644,7 @@
             off_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy)
                                  : mOwner->addSample_l(copy);
             if (mChunkOffsets.empty()) {
-                mChunkOffsets.push_back(offset);
+                addChunkOffset(offset);
             }
             copy->release();
             copy = NULL;
@@ -1644,8 +1653,7 @@
 
         mChunkSamples.push_back(copy);
         if (interleaveDurationUs == 0) {
-            StscTableEntry stscEntry(++nChunks, 1, 1);
-            mStscTableEntries.push_back(stscEntry);
+            addOneStscTableEntry(++nChunks, 1);
             bufferChunk(timestampUs);
         } else {
             if (chunkTimestampUs == 0) {
@@ -1653,15 +1661,10 @@
             } else {
                 if (timestampUs - chunkTimestampUs > interleaveDurationUs) {
                     ++nChunks;
-                    if (collectStats) {
-                        mChunkDurations.push_back(timestampUs - chunkTimestampUs);
-                    }
                     if (nChunks == 1 ||  // First chunk
                         (--(mStscTableEntries.end()))->samplesPerChunk !=
                          mChunkSamples.size()) {
-                        StscTableEntry stscEntry(nChunks,
-                                mChunkSamples.size(), 1);
-                        mStscTableEntries.push_back(stscEntry);
+                        addOneStscTableEntry(nChunks, mChunkSamples.size());
                     }
                     bufferChunk(timestampUs);
                     chunkTimestampUs = timestampUs;
@@ -1680,12 +1683,9 @@
 
     // Last chunk
     if (mOwner->numTracks() == 1) {
-        StscTableEntry stscEntry(1, mNumSamples, 1);
-        mStscTableEntries.push_back(stscEntry);
+        addOneStscTableEntry(1, mNumSamples);
     } else if (!mChunkSamples.empty()) {
-        ++nChunks;
-        StscTableEntry stscEntry(nChunks, mChunkSamples.size(), 1);
-        mStscTableEntries.push_back(stscEntry);
+        addOneStscTableEntry(++nChunks, mChunkSamples.size());
         bufferChunk(timestampUs);
     }
 
@@ -1697,14 +1697,12 @@
     } else {
         ++sampleCount;  // Count for the last sample
     }
-    SttsTableEntry sttsEntry(sampleCount, lastDurationUs);
-    mSttsTableEntries.push_back(sttsEntry);
+    addOneSttsTableEntry(sampleCount, lastDurationUs);
     mTrackDurationUs += lastDurationUs;
     mReachedEOS = true;
-    LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. Max write time: %lld us - %s",
-            count, nZeroLengthFrames, mNumSamples, mMaxWriteTimeUs, mIsAudio? "audio": "video");
+    LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s",
+            count, nZeroLengthFrames, mNumSamples, mIsAudio? "audio": "video");
 
-    logStatisticalData(mIsAudio);
     if (err == ERROR_END_OF_STREAM) {
         return OK;
     }
@@ -1729,17 +1727,6 @@
     CHECK(nTracks < 64);  // Arbitrary number
 
     int32_t trackNum = 0;
-#if 0
-    // In the worst case, we can put the trackNum
-    // along with MEDIA_RECORDER_INFO_COMPLETION_STATUS
-    // to report the progress.
-    for (List<Track *>::iterator it = mTracks.begin();
-         it != mTracks.end(); ++it, ++trackNum) {
-        if (track == (*it)) {
-            break;
-        }
-    }
-#endif
     CHECK(trackNum < nTracks);
     trackNum <<= 16;
 
@@ -1766,95 +1753,10 @@
     }
 }
 
-void MPEG4Writer::Track::findMinAvgMaxSampleDurationMs(
-        int32_t *min, int32_t *avg, int32_t *max) {
-    CHECK(!mSampleSizes.empty());
-    int32_t avgSampleDurationMs = mTrackDurationUs / 1000 / mNumSamples;
-    int32_t minSampleDurationMs = 0x7FFFFFFF;
-    int32_t maxSampleDurationMs = 0;
-    for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
-        it != mSttsTableEntries.end(); ++it) {
-        int32_t sampleDurationMs =
-            (static_cast<int32_t>(it->sampleDurationUs) + 500) / 1000;
-        if (sampleDurationMs > maxSampleDurationMs) {
-            maxSampleDurationMs = sampleDurationMs;
-        } else if (sampleDurationMs < minSampleDurationMs) {
-            minSampleDurationMs = sampleDurationMs;
-        }
-        LOGI("sample duration: %d ms", sampleDurationMs);
-    }
-    CHECK(minSampleDurationMs != 0);
-    CHECK(avgSampleDurationMs != 0);
-    CHECK(maxSampleDurationMs != 0);
-    *min = minSampleDurationMs;
-    *avg = avgSampleDurationMs;
-    *max = maxSampleDurationMs;
-}
-
-// Don't count the last duration
-void MPEG4Writer::Track::findMinMaxChunkDurations(int64_t *min, int64_t *max) {
-    int64_t duration = mOwner->interleaveDuration();
-    int64_t minChunkDuration = duration;
-    int64_t maxChunkDuration = duration;
-    if (mChunkDurations.size() > 1) {
-        for (List<int64_t>::iterator it = mChunkDurations.begin();
-            it != --mChunkDurations.end(); ++it) {
-            if (minChunkDuration > (*it)) {
-                minChunkDuration = (*it);
-            } else if (maxChunkDuration < (*it)) {
-                maxChunkDuration = (*it);
-            }
-        }
-    }
-    *min = minChunkDuration;
-    *max = maxChunkDuration;
-}
-
-void MPEG4Writer::Track::logStatisticalData(bool isAudio) {
-    if (mTrackDurationUs <= 0 || mSampleSizes.empty()) {
-        LOGI("nothing is recorded");
-        return;
-    }
-
-    bool collectStats = collectStatisticalData();
-
-    if (collectStats) {
-        LOGI("%s track - duration %lld us, total %d frames",
-                isAudio? "audio": "video", mTrackDurationUs,
-                mNumSamples);
-        int32_t min, avg, max;
-        findMinAvgMaxSampleDurationMs(&min, &avg, &max);
-        LOGI("min/avg/max sample duration (ms): %d/%d/%d", min, avg, max);
-        if (!isAudio) {
-            float avgFps = 1000.0 / avg;
-            float minFps = 1000.0 / max;
-            float maxFps = 1000.0 / min;
-            LOGI("min/avg/max frame rate (fps): %.2f/%.2f/%.2f",
-                minFps, avgFps, maxFps);
-        }
-
-        int64_t totalBytes = 0;
-        for (List<size_t>::iterator it = mSampleSizes.begin();
-            it != mSampleSizes.end(); ++it) {
-            totalBytes += (*it);
-        }
-        float bitRate = (totalBytes * 8000000.0) / mTrackDurationUs;
-        LOGI("avg bit rate (bps): %.2f", bitRate);
-
-        int64_t duration = mOwner->interleaveDuration();
-        if (duration != 0) {  // If interleaving is enabled
-            int64_t minChunk, maxChunk;
-            findMinMaxChunkDurations(&minChunk, &maxChunk);
-            LOGI("min/avg/max chunk duration (ms): %lld/%lld/%lld",
-                minChunk, duration, maxChunk);
-        }
-    }
-}
-
-void MPEG4Writer::addDriftTimeUs(int64_t driftTimeUs) {
-    LOGV("addDriftTimeUs: %lld us", driftTimeUs);
+void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) {
+    LOGV("setDriftTimeUs: %lld us", driftTimeUs);
     Mutex::Autolock autolock(mLock);
-    mDriftTimeUs += driftTimeUs;
+    mDriftTimeUs = driftTimeUs;
 }
 
 int64_t MPEG4Writer::getDriftTimeUs() {
@@ -1863,17 +1765,16 @@
     return mDriftTimeUs;
 }
 
+bool MPEG4Writer::useNalLengthFour() {
+    return mUse4ByteNalLength;
+}
+
 void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) {
     LOGV("bufferChunk");
 
-    int64_t startTimeUs = systemTime() / 1000;
     Chunk chunk(this, timestampUs, mChunkSamples);
     mOwner->bufferChunk(chunk);
     mChunkSamples.clear();
-    int64_t endTimeUs = systemTime() / 1000;
-    if (mMaxWriteTimeUs < endTimeUs - startTimeUs) {
-        mMaxWriteTimeUs = endTimeUs - startTimeUs;
-    }
 }
 
 int64_t MPEG4Writer::Track::getDurationUs() const {
@@ -2226,7 +2127,7 @@
 
           mOwner->beginBox("stts");
             mOwner->writeInt32(0);  // version=0, flags=0
-            mOwner->writeInt32(mSttsTableEntries.size());
+            mOwner->writeInt32(mNumSttsTableEntries);
             int64_t prevTimestampUs = 0;
             for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
                  it != mSttsTableEntries.end(); ++it) {
@@ -2246,7 +2147,7 @@
           if (!mIsAudio) {
             mOwner->beginBox("stss");
               mOwner->writeInt32(0);  // version=0, flags=0
-              mOwner->writeInt32(mStssTableEntries.size());  // number of sync frames
+              mOwner->writeInt32(mNumStssTableEntries);  // number of sync frames
               for (List<int32_t>::iterator it = mStssTableEntries.begin();
                    it != mStssTableEntries.end(); ++it) {
                   mOwner->writeInt32(*it);
@@ -2273,7 +2174,7 @@
 
           mOwner->beginBox("stsc");
             mOwner->writeInt32(0);  // version=0, flags=0
-            mOwner->writeInt32(mStscTableEntries.size());
+            mOwner->writeInt32(mNumStscTableEntries);
             for (List<StscTableEntry>::iterator it = mStscTableEntries.begin();
                  it != mStscTableEntries.end(); ++it) {
                 mOwner->writeInt32(it->firstChunk);
@@ -2283,7 +2184,7 @@
           mOwner->endBox();  // stsc
           mOwner->beginBox(use32BitOffset? "stco": "co64");
             mOwner->writeInt32(0);  // version=0, flags=0
-            mOwner->writeInt32(mChunkOffsets.size());
+            mOwner->writeInt32(mNumStcoTableEntries);
             for (List<off_t>::iterator it = mChunkOffsets.begin();
                  it != mChunkOffsets.end(); ++it) {
                 if (use32BitOffset) {
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index c02b7f3..9171aab 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -180,6 +180,7 @@
       mLastAccessPos(0),
       mFetching(true),
       mLastFetchTimeUs(-1) {
+    mLooper->setName("NuCachedSource2");
     mLooper->registerHandler(mReflector);
     mLooper->start();
 
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 9d45c80..f68c08a 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1811,7 +1811,9 @@
 
         case OMX_EventPortSettingsChanged:
         {
-            onPortSettingsChanged(data1);
+            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
+                onPortSettingsChanged(data1);
+            }
             break;
         }
 
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 2c1311a..7a8cf32 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -592,6 +592,7 @@
         { "DATE", kKeyDate },
         { "LYRICIST", kKeyWriter },
         { "METADATA_BLOCK_PICTURE", kKeyAlbumArt },
+        { "ANDROID_LOOP", kKeyAutoLoop },
     };
 
     for (int i = 0; i < mVc.comments; ++i) {
@@ -605,12 +606,15 @@
                     extractAlbumArt(
                             &comment[tagLen + 1],
                             mVc.comment_lengths[i] - tagLen - 1);
+                } else if (kMap[j].mKey == kKeyAutoLoop) {
+                    if (!strcasecmp(&comment[tagLen + 1], "true")) {
+                        mFileMeta->setInt32(kKeyAutoLoop, true);
+                    }
                 } else {
                     mFileMeta->setCString(kMap[j].mKey, &comment[tagLen + 1]);
                 }
             }
         }
-
     }
 
 #if 0
diff --git a/media/libstagefright/VideoSourceDownSampler.cpp b/media/libstagefright/VideoSourceDownSampler.cpp
new file mode 100644
index 0000000..ea7b09a
--- /dev/null
+++ b/media/libstagefright/VideoSourceDownSampler.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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 "VideoSourceDownSampler"
+
+#include <media/stagefright/VideoSourceDownSampler.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/YUVImage.h>
+#include <media/stagefright/YUVCanvas.h>
+#include "OMX_Video.h"
+
+namespace android {
+
+VideoSourceDownSampler::VideoSourceDownSampler(const sp<MediaSource> &videoSource,
+        int32_t width, int32_t height) {
+    LOGV("Construct VideoSourceDownSampler");
+    CHECK(width > 0);
+    CHECK(height > 0);
+
+    mRealVideoSource = videoSource;
+    mWidth = width;
+    mHeight = height;
+
+    mMeta = new MetaData(*(mRealVideoSource->getFormat()));
+    CHECK(mMeta->findInt32(kKeyWidth, &mRealSourceWidth));
+    CHECK(mMeta->findInt32(kKeyHeight, &mRealSourceHeight));
+
+    if ((mWidth != mRealSourceWidth) || (mHeight != mRealSourceHeight)) {
+        // Change meta data for width and height.
+        CHECK(mWidth <= mRealSourceWidth);
+        CHECK(mHeight <= mRealSourceHeight);
+
+        mNeedDownSampling = true;
+        computeDownSamplingParameters();
+        mMeta->setInt32(kKeyWidth, mWidth);
+        mMeta->setInt32(kKeyHeight, mHeight);
+    } else {
+        mNeedDownSampling = false;
+    }
+}
+
+VideoSourceDownSampler::~VideoSourceDownSampler() {
+}
+
+void VideoSourceDownSampler::computeDownSamplingParameters() {
+    mDownSampleSkipX = mRealSourceWidth / mWidth;
+    mDownSampleSkipY = mRealSourceHeight / mHeight;
+
+    mDownSampleOffsetX = mRealSourceWidth - mDownSampleSkipX * mWidth;
+    mDownSampleOffsetY = mRealSourceHeight - mDownSampleSkipY * mHeight;
+}
+
+void VideoSourceDownSampler::downSampleYUVImage(
+        const MediaBuffer &sourceBuffer, MediaBuffer **buffer) const {
+    // find the YUV format
+    int32_t srcFormat;
+    CHECK(mMeta->findInt32(kKeyColorFormat, &srcFormat));
+    YUVImage::YUVFormat yuvFormat;
+    if (srcFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
+        yuvFormat = YUVImage::YUV420SemiPlanar;
+    } else if (srcFormat == OMX_COLOR_FormatYUV420Planar) {
+        yuvFormat = YUVImage::YUV420Planar;
+    }
+
+    // allocate mediaBuffer for down sampled image and setup a canvas.
+    *buffer = new MediaBuffer(YUVImage::bufferSize(yuvFormat, mWidth, mHeight));
+    YUVImage yuvDownSampledImage(yuvFormat,
+            mWidth, mHeight,
+            (uint8_t *)(*buffer)->data());
+    YUVCanvas yuvCanvasDownSample(yuvDownSampledImage);
+
+    YUVImage yuvImageSource(yuvFormat,
+            mRealSourceWidth, mRealSourceHeight,
+            (uint8_t *)sourceBuffer.data());
+    yuvCanvasDownSample.downsample(mDownSampleOffsetX, mDownSampleOffsetY,
+            mDownSampleSkipX, mDownSampleSkipY,
+            yuvImageSource);
+}
+
+status_t VideoSourceDownSampler::start(MetaData *params) {
+    LOGV("start");
+    return mRealVideoSource->start();
+}
+
+status_t VideoSourceDownSampler::stop() {
+    LOGV("stop");
+    return mRealVideoSource->stop();
+}
+
+sp<MetaData> VideoSourceDownSampler::getFormat() {
+    LOGV("getFormat");
+    return mMeta;
+}
+
+status_t VideoSourceDownSampler::read(
+        MediaBuffer **buffer, const ReadOptions *options) {
+    LOGV("read");
+    MediaBuffer *realBuffer;
+    status_t err = mRealVideoSource->read(&realBuffer, options);
+
+    if (mNeedDownSampling) {
+        downSampleYUVImage(*realBuffer, buffer);
+
+        int64_t frameTime;
+        realBuffer->meta_data()->findInt64(kKeyTime, &frameTime);
+        (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
+
+        // We just want this buffer to be deleted when the encoder releases it.
+        // So don't add a reference to it and set the observer to NULL.
+        (*buffer)->setObserver(NULL);
+
+        // The original buffer is no longer required. Release it.
+        realBuffer->release();
+    } else {
+        *buffer = realBuffer;
+    }
+
+    return err;
+}
+
+status_t VideoSourceDownSampler::pause() {
+    LOGV("pause");
+    return mRealVideoSource->pause();
+}
+
+}  // namespace android
diff --git a/media/libstagefright/codecs/aacenc/AACEncoder.cpp b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
index 052c354..c05e3e5 100644
--- a/media/libstagefright/codecs/aacenc/AACEncoder.cpp
+++ b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
@@ -208,6 +208,8 @@
     MediaBuffer *buffer;
     CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
     uint8_t *outPtr = (uint8_t *)buffer->data();
+    bool readFromSource = false;
+    int64_t wallClockTimeUs = 0;
 
     if (mFrameCount == 0) {
         memcpy(outPtr, mAudioSpecificConfigData, 2);
@@ -238,9 +240,14 @@
             CHECK_EQ(align, 0);
 
             int64_t timeUs;
+            CHECK(mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs));
+            wallClockTimeUs = timeUs;
             if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
                 mAnchorTimeUs = timeUs;
             }
+            readFromSource = true;
+        } else {
+            readFromSource = false;
         }
         size_t copy =
             (kNumSamplesPerFrame - mNumInputSamples) * sizeof(int16_t);
@@ -288,9 +295,13 @@
     CHECK(outputData.Length != 0);
     buffer->set_range(0, outputData.Length);
 
-    int64_t timestampUs = ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate;
+    int64_t mediaTimeUs =
+        ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate;
+    buffer->meta_data()->setInt64(kKeyTime, mAnchorTimeUs + mediaTimeUs);
+    if (readFromSource) {
+        buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs);
+    }
     ++mFrameCount;
-    buffer->meta_data()->setInt64(kKeyTime, timestampUs);
 
     *out = buffer;
     return OK;
diff --git a/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp
index c875426..dab1390 100644
--- a/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp
@@ -147,6 +147,8 @@
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
     CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode));
+    bool readFromSource = false;
+    int64_t wallClockTimeUs = 0;
 
     while (mNumInputSamples < kNumSamplesPerFrame) {
         if (mInputBuffer == NULL) {
@@ -166,12 +168,16 @@
 
             size_t align = mInputBuffer->range_length() % sizeof(int16_t);
             CHECK_EQ(align, 0);
+            readFromSource = true;
 
             int64_t timeUs;
+            CHECK(mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs));
+            wallClockTimeUs = timeUs;
             if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
                 mAnchorTimeUs = timeUs;
-                mNumFramesOutput = 0;
             }
+        } else {
+            readFromSource = false;
         }
 
         size_t copy =
@@ -217,8 +223,14 @@
     buffer->set_range(0, res);
 
     // Each frame of 160 samples is 20ms long.
+    int64_t mediaTimeUs = mNumFramesOutput * 20000LL;
     buffer->meta_data()->setInt64(
-            kKeyTime, mAnchorTimeUs + mNumFramesOutput * 20000);
+            kKeyTime, mAnchorTimeUs + mediaTimeUs);
+
+    if (readFromSource) {
+        buffer->meta_data()->setInt64(kKeyDriftTime,
+            mediaTimeUs - wallClockTimeUs);
+    }
 
     ++mNumFramesOutput;
 
diff --git a/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp
index 93304d0..b62eb5b 100644
--- a/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp
+++ b/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp
@@ -198,6 +198,8 @@
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
     CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode));
+    bool readFromSource = false;
+    int64_t wallClockTimeUs = 0;
 
     while (mNumInputSamples < kNumSamplesPerFrame) {
         if (mInputBuffer == NULL) {
@@ -219,9 +221,14 @@
             CHECK_EQ(align, 0);
 
             int64_t timeUs;
+            CHECK(mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs));
+            wallClockTimeUs = timeUs;
             if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
                 mAnchorTimeUs = timeUs;
             }
+            readFromSource = true;
+        } else {
+            readFromSource = false;
         }
 
         size_t copy =
@@ -276,10 +283,11 @@
     buffer->set_range(0, outputData.Length);
     ++mNumFramesOutput;
 
-    // XXX: fix timestamp calculation
-    int64_t timestampUs = mNumFramesOutput * 20000LL;
-
-    buffer->meta_data()->setInt64(kKeyTime, timestampUs);
+    int64_t mediaTimeUs = mNumFramesOutput * 20000LL;
+    buffer->meta_data()->setInt64(kKeyTime, mAnchorTimeUs + mediaTimeUs);
+    if (readFromSource) {
+        buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs);
+    }
 
     *out = buffer;
     return OK;
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/libstagefright/foundation/ALooper.cpp
index 77afb01..b7087f8 100644
--- a/media/libstagefright/foundation/ALooper.cpp
+++ b/media/libstagefright/foundation/ALooper.cpp
@@ -65,6 +65,10 @@
     stop();
 }
 
+void ALooper::setName(const char *name) {
+    mName = name;
+}
+
 ALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) {
     return gLooperRoster.registerHandler(this, handler);
 }
@@ -100,7 +104,8 @@
 
     mThread = new LooperThread(this, canCallJava);
 
-    status_t err = mThread->run("ALooper", priority);
+    status_t err = mThread->run(
+            mName.empty() ? "ALooper" : mName.c_str(), priority);
     if (err != OK) {
         mThread.clear();
     }
diff --git a/media/libstagefright/include/ARTSPController.h b/media/libstagefright/include/ARTSPController.h
index 7016880..300d8f7 100644
--- a/media/libstagefright/include/ARTSPController.h
+++ b/media/libstagefright/include/ARTSPController.h
@@ -42,6 +42,7 @@
             size_t index, uint32_t flags);
 
     int64_t getNormalPlayTimeUs();
+    int64_t getQueueDurationUs(bool *eos);
 
     void onMessageReceived(const sp<AMessage> &msg);
 
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index f34eb456..ea2f7d5 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -107,6 +107,7 @@
         CACHE_UNDERRUN      = 128,
         AUDIO_AT_EOS        = 256,
         VIDEO_AT_EOS        = 512,
+        AUTO_LOOPING        = 1024,
     };
 
     mutable Mutex mLock;
@@ -241,6 +242,9 @@
     void onCheckAudioStatus();
     void onPrepareAsyncEvent();
     void abortPrepare(status_t err);
+    void finishAsyncPrepare_l();
+
+    bool getCachedDuration_l(int64_t *durationUs, bool *eos);
 
     status_t finishSetDataSource_l();
 
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index c99da59..83b75ad 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -59,10 +59,17 @@
             node_id node, OMX_INDEXTYPE index,
             const void *params, size_t size);
 
+    virtual status_t enableGraphicBuffers(
+            node_id node, OMX_U32 port_index, OMX_BOOL enable);
+
     virtual status_t useBuffer(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer);
 
+    virtual status_t useGraphicBuffer(
+            node_id node, OMX_U32 port_index,
+            const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer);
+
     virtual status_t allocateBuffer(
             node_id node, OMX_U32 port_index, size_t size,
             buffer_id *buffer, void **buffer_data);
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index b5b31ac..8c7c562 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -49,10 +49,16 @@
     status_t getConfig(OMX_INDEXTYPE index, void *params, size_t size);
     status_t setConfig(OMX_INDEXTYPE index, const void *params, size_t size);
 
+    status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable);
+
     status_t useBuffer(
             OMX_U32 portIndex, const sp<IMemory> &params,
             OMX::buffer_id *buffer);
 
+    status_t useGraphicBuffer(
+            OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
+            OMX::buffer_id *buffer);
+
     status_t allocateBuffer(
             OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
             void **buffer_data);
@@ -125,4 +131,3 @@
 }  // namespace android
 
 #endif  // OMX_NODE_INSTANCE_H_
-
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 26a0fb3..72de8d7 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -78,6 +78,8 @@
             unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS,
             const uint8_t *data, size_t size);
 
+    void extractAACFrames(const sp<ABuffer> &buffer);
+
     DISALLOW_EVIL_CONSTRUCTORS(Stream);
 };
 
@@ -226,7 +228,7 @@
 ATSParser::Stream::Stream(unsigned elementaryPID, unsigned streamType)
     : mElementaryPID(elementaryPID),
       mStreamType(streamType),
-      mBuffer(new ABuffer(65536)),
+      mBuffer(new ABuffer(128 * 1024)),
       mPayloadStarted(false) {
     mBuffer->setRange(0, 0);
 }
@@ -662,7 +664,7 @@
     csd->data()[sizeof(kStaticESDS) + 1] =
         ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
 
-    hexdump(csd->data(), csd->size());
+    // hexdump(csd->data(), csd->size());
     return csd;
 }
 
@@ -727,13 +729,76 @@
     buffer->meta()->setInt64("time", (PTS * 100) / 9);
 
     if (mStreamType == 0x0f) {
-        // WHY???
-        buffer->setRange(7, buffer->size() - 7);
+        extractAACFrames(buffer);
     }
 
     mSource->queueAccessUnit(buffer);
 }
 
+// Disassemble one or more ADTS frames into their constituent parts and
+// leave only the concatenated raw_data_blocks in the buffer.
+void ATSParser::Stream::extractAACFrames(const sp<ABuffer> &buffer) {
+    size_t dstOffset = 0;
+
+    size_t offset = 0;
+    while (offset < buffer->size()) {
+        CHECK_LE(offset + 7, buffer->size());
+
+        ABitReader bits(buffer->data() + offset, buffer->size() - offset);
+
+        // adts_fixed_header
+
+        CHECK_EQ(bits.getBits(12), 0xfffu);
+        bits.skipBits(3);  // ID, layer
+        bool protection_absent = bits.getBits(1) != 0;
+
+        // profile_ObjectType, sampling_frequency_index, private_bits,
+        // channel_configuration, original_copy, home
+        bits.skipBits(12);
+
+        // adts_variable_header
+
+        // copyright_identification_bit, copyright_identification_start
+        bits.skipBits(2);
+
+        unsigned aac_frame_length = bits.getBits(13);
+
+        bits.skipBits(11);  // adts_buffer_fullness
+
+        unsigned number_of_raw_data_blocks_in_frame = bits.getBits(2);
+
+        if (number_of_raw_data_blocks_in_frame == 0) {
+            size_t scan = offset + aac_frame_length;
+
+            offset += 7;
+            if (!protection_absent) {
+                offset += 2;
+            }
+
+            CHECK_LE(scan, buffer->size());
+
+            LOG(VERBOSE)
+                << "found aac raw data block at ["
+                << StringPrintf("0x%08x", offset)
+                << " ; "
+                << StringPrintf("0x%08x", scan)
+                << ")";
+
+            memmove(&buffer->data()[dstOffset], &buffer->data()[offset],
+                    scan - offset);
+
+            dstOffset += scan - offset;
+            offset = scan;
+        } else {
+            // To be implemented.
+            TRESPASS();
+        }
+    }
+    CHECK_EQ(offset, buffer->size());
+
+    buffer->setRange(buffer->offset(), dstOffset);
+}
+
 sp<MediaSource> ATSParser::Stream::getSource(SourceType type) {
     if ((type == AVC_VIDEO && mStreamType == 0x1b)
         || (type == MPEG2ADTS_AUDIO && mStreamType == 0x0f)) {
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 88b9605..37243ad 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -287,6 +287,11 @@
             index, params, size);
 }
 
+status_t OMX::enableGraphicBuffers(
+        node_id node, OMX_U32 port_index, OMX_BOOL enable) {
+    return findInstance(node)->enableGraphicBuffers(port_index, enable);
+}
+
 status_t OMX::useBuffer(
         node_id node, OMX_U32 port_index, const sp<IMemory> &params,
         buffer_id *buffer) {
@@ -294,6 +299,13 @@
             port_index, params, buffer);
 }
 
+status_t OMX::useGraphicBuffer(
+        node_id node, OMX_U32 port_index,
+        const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
+    return findInstance(node)->useGraphicBuffer(
+            port_index, graphicBuffer, buffer);
+}
+
 status_t OMX::allocateBuffer(
         node_id node, OMX_U32 port_index, size_t size,
         buffer_id *buffer, void **buffer_data) {
@@ -530,4 +542,3 @@
 }
 
 }  // namespace android
-
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 5db516e..ba4d765 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -24,6 +24,7 @@
 #include <OMX_Component.h>
 
 #include <binder/IMemory.h>
+#include <media/stagefright/HardwareAPI.h>
 #include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/MediaErrors.h>
 
@@ -40,6 +41,11 @@
           mIsBackup(false) {
     }
 
+    BufferMeta(const sp<GraphicBuffer> &graphicBuffer)
+        : mGraphicBuffer(graphicBuffer),
+          mIsBackup(false) {
+    }
+
     void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
         if (!mIsBackup) {
             return;
@@ -61,6 +67,7 @@
     }
 
 private:
+    sp<GraphicBuffer> mGraphicBuffer;
     sp<IMemory> mMem;
     size_t mSize;
     bool mIsBackup;
@@ -240,6 +247,43 @@
     return StatusFromOMXError(err);
 }
 
+status_t OMXNodeInstance::enableGraphicBuffers(
+        OMX_U32 portIndex, OMX_BOOL enable) {
+    Mutex::Autolock autoLock(mLock);
+
+    OMX_INDEXTYPE index;
+    OMX_ERRORTYPE err = OMX_GetExtensionIndex(
+            mHandle,
+            const_cast<OMX_STRING>("OMX.google.android.index.enableAndroidNativeBuffers"),
+            &index);
+
+    if (err != OMX_ErrorNone) {
+        LOGE("OMX_GetExtensionIndex failed");
+
+        return StatusFromOMXError(err);
+    }
+
+    OMX_VERSIONTYPE ver;
+    ver.s.nVersionMajor = 1;
+    ver.s.nVersionMinor = 0;
+    ver.s.nRevision = 0;
+    ver.s.nStep = 0;
+    EnableAndroidNativeBuffersParams params = {
+        sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable,
+    };
+
+    err = OMX_SetParameter(mHandle, index, &params);
+
+    if (err != OMX_ErrorNone) {
+        LOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)",
+                err, err);
+
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
 status_t OMXNodeInstance::useBuffer(
         OMX_U32 portIndex, const sp<IMemory> &params,
         OMX::buffer_id *buffer) {
@@ -273,6 +317,60 @@
     return OK;
 }
 
+status_t OMXNodeInstance::useGraphicBuffer(
+        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
+        OMX::buffer_id *buffer) {
+    Mutex::Autolock autoLock(mLock);
+
+    OMX_INDEXTYPE index;
+    OMX_ERRORTYPE err = OMX_GetExtensionIndex(
+            mHandle,
+            const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer"),
+            &index);
+
+    if (err != OMX_ErrorNone) {
+        LOGE("OMX_GetExtensionIndex failed");
+
+        return StatusFromOMXError(err);
+    }
+
+    BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
+
+    OMX_BUFFERHEADERTYPE *header;
+
+    OMX_VERSIONTYPE ver;
+    ver.s.nVersionMajor = 1;
+    ver.s.nVersionMinor = 0;
+    ver.s.nRevision = 0;
+    ver.s.nStep = 0;
+    UseAndroidNativeBufferParams params = {
+        sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
+        &header, graphicBuffer,
+    };
+
+    err = OMX_SetParameter(mHandle, index, &params);
+
+    if (err != OMX_ErrorNone) {
+        LOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err,
+                err);
+
+        delete bufferMeta;
+        bufferMeta = NULL;
+
+        *buffer = 0;
+
+        return UNKNOWN_ERROR;
+    }
+
+    CHECK_EQ(header->pAppPrivate, bufferMeta);
+
+    *buffer = header;
+
+    addActiveBuffer(portIndex, *buffer);
+
+    return OK;
+}
+
 status_t OMXNodeInstance::allocateBuffer(
         OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
         void **buffer_data) {
@@ -498,4 +596,3 @@
 }
 
 }  // namespace android
-
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
index 7dd3e3f..f68a35b 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
@@ -18,29 +18,160 @@
 
 #include "ARTPSource.h"
 
+#include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/Utils.h>
 
+#include <ctype.h>
 #include <stdint.h>
 
 #define BE_VERBOSE      0
 
 namespace android {
 
+static bool GetAttribute(const char *s, const char *key, AString *value) {
+    value->clear();
+
+    size_t keyLen = strlen(key);
+
+    for (;;) {
+        while (isspace(*s)) {
+            ++s;
+        }
+
+        const char *colonPos = strchr(s, ';');
+
+        size_t len =
+            (colonPos == NULL) ? strlen(s) : colonPos - s;
+
+        if (len >= keyLen + 1 && s[keyLen] == '='
+                && !strncasecmp(s, key, keyLen)) {
+            value->setTo(&s[keyLen + 1], len - keyLen - 1);
+            return true;
+        }
+
+        if (colonPos == NULL) {
+            return false;
+        }
+
+        s = colonPos + 1;
+    }
+}
+
+static bool GetIntegerAttribute(
+        const char *s, const char *key, unsigned *x) {
+    *x = 0;
+
+    AString val;
+    if (!GetAttribute(s, key, &val)) {
+        return false;
+    }
+
+    s = val.c_str();
+    char *end;
+    unsigned y = strtoul(s, &end, 10);
+
+    if (end == s || *end != '\0') {
+        return false;
+    }
+
+    *x = y;
+
+    return true;
+}
+
 // static
-AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(const sp<AMessage> &notify)
+AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(
+        const sp<AMessage> &notify, const AString &desc, const AString &params)
     : mNotifyMsg(notify),
+      mIsGeneric(false),
+      mParams(params),
+      mSizeLength(0),
+      mIndexLength(0),
+      mIndexDeltaLength(0),
+      mCTSDeltaLength(0),
+      mDTSDeltaLength(0),
+      mRandomAccessIndication(false),
+      mStreamStateIndication(0),
+      mAuxiliaryDataSizeLength(0),
+      mHasAUHeader(false),
       mAccessUnitRTPTime(0),
       mNextExpectedSeqNoValid(false),
       mNextExpectedSeqNo(0),
       mAccessUnitDamaged(false) {
+    mIsGeneric = desc.startsWith("mpeg4-generic/");
+
+    if (mIsGeneric) {
+        AString value;
+        CHECK(GetAttribute(params.c_str(), "mode", &value));
+
+        if (!GetIntegerAttribute(params.c_str(), "sizeLength", &mSizeLength)) {
+            mSizeLength = 0;
+        }
+
+        if (!GetIntegerAttribute(
+                    params.c_str(), "indexLength", &mIndexLength)) {
+            mIndexLength = 0;
+        }
+
+        if (!GetIntegerAttribute(
+                    params.c_str(), "indexDeltaLength", &mIndexDeltaLength)) {
+            mIndexDeltaLength = 0;
+        }
+
+        if (!GetIntegerAttribute(
+                    params.c_str(), "CTSDeltaLength", &mCTSDeltaLength)) {
+            mCTSDeltaLength = 0;
+        }
+
+        if (!GetIntegerAttribute(
+                    params.c_str(), "DTSDeltaLength", &mDTSDeltaLength)) {
+            mDTSDeltaLength = 0;
+        }
+
+        unsigned x;
+        if (!GetIntegerAttribute(
+                    params.c_str(), "randomAccessIndication", &x)) {
+            mRandomAccessIndication = false;
+        } else {
+            CHECK(x == 0 || x == 1);
+            mRandomAccessIndication = (x != 0);
+        }
+
+        if (!GetIntegerAttribute(
+                    params.c_str(), "streamStateIndication",
+                    &mStreamStateIndication)) {
+            mStreamStateIndication = 0;
+        }
+
+        if (!GetIntegerAttribute(
+                    params.c_str(), "auxiliaryDataSizeLength",
+                    &mAuxiliaryDataSizeLength)) {
+            mAuxiliaryDataSizeLength = 0;
+        }
+
+        mHasAUHeader =
+            mSizeLength > 0
+            || mIndexLength > 0
+            || mIndexDeltaLength > 0
+            || mCTSDeltaLength > 0
+            || mDTSDeltaLength > 0
+            || mRandomAccessIndication
+            || mStreamStateIndication > 0;
+    }
 }
 
 AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() {
 }
 
+struct AUHeader {
+    unsigned mSize;
+    unsigned mSerial;
+};
+
 ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket(
         const sp<ARTPSource> &source) {
     List<sp<ABuffer> > *queue = source->queue();
@@ -85,8 +216,116 @@
     }
     mAccessUnitRTPTime = rtpTime;
 
-    mPackets.push_back(buffer);
-    // hexdump(buffer->data(), buffer->size());
+    if (!mIsGeneric) {
+        mPackets.push_back(buffer);
+    } else {
+        // hexdump(buffer->data(), buffer->size());
+
+        CHECK_GE(buffer->size(), 2u);
+        unsigned AU_headers_length = U16_AT(buffer->data());  // in bits
+
+        CHECK_GE(buffer->size(), 2 + (AU_headers_length + 7) / 8);
+
+        List<AUHeader> headers;
+
+        ABitReader bits(buffer->data() + 2, buffer->size() - 2);
+        unsigned numBitsLeft = AU_headers_length;
+
+        unsigned AU_serial = 0;
+        for (;;) {
+            if (numBitsLeft < mSizeLength) { break; }
+
+            unsigned AU_size = bits.getBits(mSizeLength);
+            numBitsLeft -= mSizeLength;
+
+            size_t n = headers.empty() ? mIndexLength : mIndexDeltaLength;
+            if (numBitsLeft < n) { break; }
+
+            unsigned AU_index = bits.getBits(n);
+            numBitsLeft -= n;
+
+            if (headers.empty()) {
+                AU_serial = AU_index;
+            } else {
+                AU_serial += 1 + AU_index;
+            }
+
+            if (mCTSDeltaLength > 0) {
+                if (numBitsLeft < 1) {
+                    break;
+                }
+                --numBitsLeft;
+                if (bits.getBits(1)) {
+                    if (numBitsLeft < mCTSDeltaLength) {
+                        break;
+                    }
+                    bits.skipBits(mCTSDeltaLength);
+                    numBitsLeft -= mCTSDeltaLength;
+                }
+            }
+
+            if (mDTSDeltaLength > 0) {
+                if (numBitsLeft < 1) {
+                    break;
+                }
+                --numBitsLeft;
+                if (bits.getBits(1)) {
+                    if (numBitsLeft < mDTSDeltaLength) {
+                        break;
+                    }
+                    bits.skipBits(mDTSDeltaLength);
+                    numBitsLeft -= mDTSDeltaLength;
+                }
+            }
+
+            if (mRandomAccessIndication) {
+                if (numBitsLeft < 1) {
+                    break;
+                }
+                bits.skipBits(1);
+                --numBitsLeft;
+            }
+
+            if (mStreamStateIndication > 0) {
+                if (numBitsLeft < mStreamStateIndication) {
+                    break;
+                }
+                bits.skipBits(mStreamStateIndication);
+            }
+
+            AUHeader header;
+            header.mSize = AU_size;
+            header.mSerial = AU_serial;
+            headers.push_back(header);
+        }
+
+        size_t offset = 2 + (AU_headers_length + 7) / 8;
+
+        if (mAuxiliaryDataSizeLength > 0) {
+            ABitReader bits(buffer->data() + offset, buffer->size() - offset);
+
+            unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength);
+
+            offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8;
+        }
+
+        for (List<AUHeader>::iterator it = headers.begin();
+             it != headers.end(); ++it) {
+            const AUHeader &header = *it;
+
+            CHECK_LE(offset + header.mSize, buffer->size());
+
+            sp<ABuffer> accessUnit = new ABuffer(header.mSize);
+            memcpy(accessUnit->data(), buffer->data() + offset, header.mSize);
+
+            offset += header.mSize;
+
+            CopyTimes(accessUnit, buffer);
+            mPackets.push_back(accessUnit);
+        }
+
+        CHECK_EQ(offset, buffer->size());
+    }
 
     queue->erase(queue->begin());
     ++mNextExpectedSeqNo;
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h
index 1566d00..794bbcc 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h
@@ -20,6 +20,8 @@
 
 #include "ARTPAssembler.h"
 
+#include <media/stagefright/foundation/AString.h>
+
 #include <utils/List.h>
 #include <utils/RefBase.h>
 
@@ -29,7 +31,9 @@
 struct AMessage;
 
 struct AMPEG4ElementaryAssembler : public ARTPAssembler {
-    AMPEG4ElementaryAssembler(const sp<AMessage> &notify);
+    AMPEG4ElementaryAssembler(
+            const sp<AMessage> &notify, const AString &desc,
+            const AString &params);
 
 protected:
     virtual ~AMPEG4ElementaryAssembler();
@@ -40,6 +44,18 @@
 
 private:
     sp<AMessage> mNotifyMsg;
+    bool mIsGeneric;
+    AString mParams;
+
+    unsigned mSizeLength;
+    unsigned mIndexLength;
+    unsigned mIndexDeltaLength;
+    unsigned mCTSDeltaLength;
+    unsigned mDTSDeltaLength;
+    bool mRandomAccessIndication;
+    unsigned mStreamStateIndication;
+    unsigned mAuxiliaryDataSizeLength;
+    bool mHasAUHeader;
 
     uint32_t mAccessUnitRTPTime;
     bool mNextExpectedSeqNoValid;
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index 2d7738b..b63798f 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -247,6 +247,65 @@
     return csd;
 }
 
+// From mpeg4-generic configuration data.
+sp<ABuffer> MakeAACCodecSpecificData2(const char *params) {
+    AString val;
+    unsigned long objectType;
+    if (GetAttribute(params, "objectType", &val)) {
+        const char *s = val.c_str();
+        char *end;
+        objectType = strtoul(s, &end, 10);
+        CHECK(end > s && *end == '\0');
+    } else {
+        objectType = 0x40;  // Audio ISO/IEC 14496-3
+    }
+
+    CHECK(GetAttribute(params, "config", &val));
+
+    sp<ABuffer> config = decodeHex(val);
+    CHECK(config != NULL);
+
+    // Make sure size fits into a single byte and doesn't have to
+    // be encoded.
+    CHECK_LT(20 + config->size(), 128u);
+
+    const uint8_t *data = config->data();
+
+    static const uint8_t kStaticESDS[] = {
+        0x03, 22,
+        0x00, 0x00,     // ES_ID
+        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
+
+        0x04, 17,
+        0x40,                       // Audio ISO/IEC 14496-3
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+
+        0x05, 2,
+        // AudioSpecificInfo follows
+    };
+
+    sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size());
+    uint8_t *dst = csd->data();
+    *dst++ = 0x03;
+    *dst++ = 20 + config->size();
+    *dst++ = 0x00;  // ES_ID
+    *dst++ = 0x00;
+    *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
+    *dst++ = 0x04;
+    *dst++ = 15 + config->size();
+    *dst++ = objectType;
+    for (int i = 0; i < 12; ++i) { *dst++ = 0x00; }
+    *dst++ = 0x05;
+    *dst++ = config->size();
+    memcpy(dst, config->data(), config->size());
+
+    // hexdump(csd->data(), csd->size());
+
+    return csd;
+}
+
 static size_t GetSizeWidth(size_t x) {
     size_t n = 1;
     while (x > 127) {
@@ -560,6 +619,30 @@
 
         mFormat->setInt32(kKeyWidth, width);
         mFormat->setInt32(kKeyHeight, height);
+    } else if (!strncmp(desc.c_str(), "mpeg4-generic/", 14)) {
+        AString val;
+        if (!GetAttribute(params.c_str(), "mode", &val)
+                || (strcasecmp(val.c_str(), "AAC-lbr")
+                    && strcasecmp(val.c_str(), "AAC-hbr"))) {
+            mInitCheck = ERROR_UNSUPPORTED;
+            return;
+        }
+
+        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
+
+        int32_t sampleRate, numChannels;
+        ASessionDescription::ParseFormatDesc(
+                desc.c_str(), &sampleRate, &numChannels);
+
+        mFormat->setInt32(kKeySampleRate, sampleRate);
+        mFormat->setInt32(kKeyChannelCount, numChannels);
+
+        sp<ABuffer> codecSpecificData =
+            MakeAACCodecSpecificData2(params.c_str());
+
+        mFormat->setData(
+                kKeyESDS, 0,
+                codecSpecificData->data(), codecSpecificData->size());
     } else {
         mInitCheck = ERROR_UNSUPPORTED;
     }
@@ -663,4 +746,27 @@
     mNormalPlayTimeBaseUs = normalPlayTimeUs;
 }
 
+int64_t APacketSource::getQueueDurationUs(bool *eos) {
+    Mutex::Autolock autoLock(mLock);
+
+    *eos = (mEOSResult != OK);
+
+    if (mBuffers.size() < 2) {
+        return 0;
+    }
+
+    const sp<ABuffer> first = *mBuffers.begin();
+    const sp<ABuffer> last = *--mBuffers.end();
+
+    int64_t firstTimeUs;
+    CHECK(first->meta()->findInt64("timeUs", &firstTimeUs));
+
+    int64_t lastTimeUs;
+    CHECK(last->meta()->findInt64("timeUs", &lastTimeUs));
+
+    CHECK_GE(lastTimeUs, firstTimeUs);
+
+    return lastTimeUs - firstTimeUs;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/rtsp/APacketSource.h b/media/libstagefright/rtsp/APacketSource.h
index 3833ab1..076ddc47 100644
--- a/media/libstagefright/rtsp/APacketSource.h
+++ b/media/libstagefright/rtsp/APacketSource.h
@@ -50,6 +50,8 @@
     void setNormalPlayTimeMapping(
             uint32_t rtpTime, int64_t normalPlayTimeUs);
 
+    int64_t getQueueDurationUs(bool *eos);
+
 protected:
     virtual ~APacketSource();
 
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 42a22b7..10c9e02 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -263,6 +263,10 @@
         }
     }
 
+    if (maxSocket == -1) {
+        return;
+    }
+
     int res = select(maxSocket + 1, &rs, NULL, NULL, &tv);
     CHECK_GE(res, 0);
 
@@ -292,6 +296,10 @@
              it != mStreams.end(); ++it) {
             StreamInfo *s = &*it;
 
+            if (s->mIsInjected) {
+                continue;
+            }
+
             if (s->mNumRTCPPacketsReceived == 0) {
                 // We have never received any RTCP packets on this stream,
                 // we don't even know where to send a report.
@@ -354,7 +362,6 @@
     if (receiveRTP) {
         err = parseRTP(s, buffer);
     } else {
-        ++s->mNumRTCPPacketsReceived;
         err = parseRTCP(s, buffer);
     }
 
@@ -448,6 +455,12 @@
 }
 
 status_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) {
+    if (s->mNumRTCPPacketsReceived++ == 0) {
+        sp<AMessage> notify = s->mNotifyMsg->dup();
+        notify->setInt32("first-rtcp", true);
+        notify->post();
+    }
+
     const uint8_t *data = buffer->data();
     size_t size = buffer->size();
 
@@ -618,7 +631,6 @@
     if (it->mRTPSocket == index) {
         err = parseRTP(s, buffer);
     } else {
-        ++s->mNumRTCPPacketsReceived;
         err = parseRTCP(s, buffer);
     }
 }
diff --git a/media/libstagefright/rtsp/ARTPSession.cpp b/media/libstagefright/rtsp/ARTPSession.cpp
index d2c56f7..8ce93b7 100644
--- a/media/libstagefright/rtsp/ARTPSession.cpp
+++ b/media/libstagefright/rtsp/ARTPSession.cpp
@@ -125,6 +125,14 @@
     switch (msg->what()) {
         case kWhatAccessUnitComplete:
         {
+            int32_t firstRTCP;
+            if (msg->findInt32("first-rtcp", &firstRTCP)) {
+                // There won't be an access unit here, it's just a notification
+                // that the data communication worked since we got the first
+                // rtcp packet.
+                break;
+            }
+
             size_t trackIndex;
             CHECK(msg->findSize("track-index", &trackIndex));
 
@@ -167,6 +175,7 @@
 #endif
 
             accessUnit->meta()->setInt64("ntp-time", ntpTime);
+            accessUnit->meta()->setInt64("timeUs", 0);
 
 #if 0
             int32_t damaged;
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 775c4ee..9656ba2 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -64,8 +64,9 @@
         mAssembler = new AAMRAssembler(notify, false /* isWide */, params);
     } else  if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
         mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
-    } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) {
-        mAssembler = new AMPEG4ElementaryAssembler(notify);
+    } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
+            || !strncmp(desc.c_str(), "mpeg4-generic/", 14)) {
+        mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
         mIssueFIRRequests = true;
     } else {
         TRESPASS();
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index d4eed7c..ce1ee0e 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -31,6 +31,7 @@
       mReflector(new AHandlerReflector<ARTPWriter>(this)) {
     CHECK_GE(fd, 0);
 
+    mLooper->setName("rtp writer");
     mLooper->registerHandler(mReflector);
     mLooper->start();
 
diff --git a/media/libstagefright/rtsp/ARTSPController.cpp b/media/libstagefright/rtsp/ARTSPController.cpp
index a89946b..4c53639 100644
--- a/media/libstagefright/rtsp/ARTSPController.cpp
+++ b/media/libstagefright/rtsp/ARTSPController.cpp
@@ -143,4 +143,26 @@
     return mHandler->getNormalPlayTimeUs();
 }
 
+int64_t ARTSPController::getQueueDurationUs(bool *eos) {
+    *eos = true;
+
+    int64_t minQueuedDurationUs = 0;
+    for (size_t i = 0; i < mHandler->countTracks(); ++i) {
+        sp<APacketSource> source = mHandler->getPacketSource(i);
+
+        bool newEOS;
+        int64_t queuedDurationUs = source->getQueueDurationUs(&newEOS);
+
+        if (!newEOS) {
+            *eos = false;
+        }
+
+        if (i == 0 || queuedDurationUs < minQueuedDurationUs) {
+            minQueuedDurationUs = queuedDurationUs;
+        }
+    }
+
+    return minQueuedDurationUs;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 8337c93..0aefd58 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -31,7 +31,13 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaErrors.h>
 
-#define USE_TCP_INTERLEAVED     0
+// If no access units are received within 3 secs, assume that the rtp
+// stream has ended and signal end of stream.
+static int64_t kAccessUnitTimeoutUs = 3000000ll;
+
+// If no access units arrive for the first 10 secs after starting the
+// stream, assume none ever will and signal EOS or switch transports.
+static int64_t kStartupTimeoutUs = 10000000ll;
 
 namespace android {
 
@@ -75,8 +81,10 @@
           mFirstAccessUnit(true),
           mFirstAccessUnitNTP(0),
           mNumAccessUnitsReceived(0),
-          mCheckPending(false) {
-
+          mCheckPending(false),
+          mTryTCPInterleaving(false),
+          mReceivedFirstRTCPPacket(false) {
+        mNetLooper->setName("rtsp net");
         mNetLooper->start(false /* runOnCallingThread */,
                           false /* canCallJava */,
                           PRIORITY_HIGHEST);
@@ -150,7 +158,13 @@
 
             case 'disc':
             {
-                (new AMessage('quit', id()))->post();
+                int32_t reconnect;
+                if (msg->findInt32("reconnect", &reconnect) && reconnect) {
+                    sp<AMessage> reply = new AMessage('conn', id());
+                    mConn->connect(mSessionURL.c_str(), reply);
+                } else {
+                    (new AMessage('quit', id()))->post();
+                }
                 break;
             }
 
@@ -186,31 +200,35 @@
                         break;
                     }
 
-                    CHECK_EQ(response->mStatusCode, 200u);
-
-                    mSessionDesc = new ASessionDescription;
-
-                    mSessionDesc->setTo(
-                            response->mContent->data(),
-                            response->mContent->size());
-
-                    CHECK(mSessionDesc->isValid());
-
-                    ssize_t i = response->mHeaders.indexOfKey("content-base");
-                    if (i >= 0) {
-                        mBaseURL = response->mHeaders.valueAt(i);
+                    if (response->mStatusCode != 200) {
+                        result = UNKNOWN_ERROR;
                     } else {
-                        i = response->mHeaders.indexOfKey("content-location");
+                        mSessionDesc = new ASessionDescription;
+
+                        mSessionDesc->setTo(
+                                response->mContent->data(),
+                                response->mContent->size());
+
+                        CHECK(mSessionDesc->isValid());
+
+                        ssize_t i = response->mHeaders.indexOfKey("content-base");
                         if (i >= 0) {
                             mBaseURL = response->mHeaders.valueAt(i);
                         } else {
-                            mBaseURL = mSessionURL;
+                            i = response->mHeaders.indexOfKey("content-location");
+                            if (i >= 0) {
+                                mBaseURL = response->mHeaders.valueAt(i);
+                            } else {
+                                mBaseURL = mSessionURL;
+                            }
                         }
-                    }
 
-                    CHECK_GT(mSessionDesc->countTracks(), 1u);
-                    setupTrack(1);
-                } else {
+                        CHECK_GT(mSessionDesc->countTracks(), 1u);
+                        setupTrack(1);
+                    }
+                }
+
+                if (result != OK) {
                     sp<AMessage> reply = new AMessage('disc', id());
                     mConn->disconnect(reply);
                 }
@@ -234,6 +252,39 @@
                 LOG(INFO) << "SETUP(" << index << ") completed with result "
                      << result << " (" << strerror(-result) << ")";
 
+                if (result == OK) {
+                    CHECK(track != NULL);
+
+                    sp<RefBase> obj;
+                    CHECK(msg->findObject("response", &obj));
+                    sp<ARTSPResponse> response =
+                        static_cast<ARTSPResponse *>(obj.get());
+
+                    if (response->mStatusCode != 200) {
+                        result = UNKNOWN_ERROR;
+                    } else {
+                        ssize_t i = response->mHeaders.indexOfKey("session");
+                        CHECK_GE(i, 0);
+
+                        mSessionID = response->mHeaders.valueAt(i);
+                        i = mSessionID.find(";");
+                        if (i >= 0) {
+                            // Remove options, i.e. ";timeout=90"
+                            mSessionID.erase(i, mSessionID.size() - i);
+                        }
+
+                        sp<AMessage> notify = new AMessage('accu', id());
+                        notify->setSize("track-index", trackIndex);
+
+                        mRTPConn->addStream(
+                                track->mRTPSocket, track->mRTCPSocket,
+                                mSessionDesc, index,
+                                notify, track->mUsingInterleavedTCP);
+
+                        mSetupTracksSuccessful = true;
+                    }
+                }
+
                 if (result != OK) {
                     if (track) {
                         if (!track->mUsingInterleavedTCP) {
@@ -243,37 +294,6 @@
 
                         mTracks.removeItemsAt(trackIndex);
                     }
-                } else {
-                    CHECK(track != NULL);
-
-                    sp<RefBase> obj;
-                    CHECK(msg->findObject("response", &obj));
-                    sp<ARTSPResponse> response =
-                        static_cast<ARTSPResponse *>(obj.get());
-
-                    CHECK_EQ(response->mStatusCode, 200u);
-
-                    ssize_t i = response->mHeaders.indexOfKey("session");
-                    CHECK_GE(i, 0);
-
-                    if (index == 1) {
-                        mSessionID = response->mHeaders.valueAt(i);
-                        i = mSessionID.find(";");
-                        if (i >= 0) {
-                            // Remove options, i.e. ";timeout=90"
-                            mSessionID.erase(i, mSessionID.size() - i);
-                        }
-                    }
-
-                    sp<AMessage> notify = new AMessage('accu', id());
-                    notify->setSize("track-index", trackIndex);
-
-                    mRTPConn->addStream(
-                            track->mRTPSocket, track->mRTCPSocket,
-                            mSessionDesc, index,
-                            notify, track->mUsingInterleavedTCP);
-
-                    mSetupTracksSuccessful = true;
                 }
 
                 ++index;
@@ -317,12 +337,8 @@
 
                     parsePlayResponse(response);
 
-                    mDoneMsg->setInt32("result", OK);
-                    mDoneMsg->post();
-                    mDoneMsg = NULL;
-
                     sp<AMessage> timeout = new AMessage('tiou', id());
-                    timeout->post(10000000ll);
+                    timeout->post(kStartupTimeoutUs);
                 } else {
                     sp<AMessage> reply = new AMessage('disc', id());
                     mConn->disconnect(reply);
@@ -334,12 +350,32 @@
             case 'abor':
             {
                 for (size_t i = 0; i < mTracks.size(); ++i) {
-                    mTracks.editItemAt(i).mPacketSource->signalEOS(
-                            ERROR_END_OF_STREAM);
+                    TrackInfo *info = &mTracks.editItemAt(i);
+
+                    info->mPacketSource->signalEOS(ERROR_END_OF_STREAM);
+
+                    if (!info->mUsingInterleavedTCP) {
+                        mRTPConn->removeStream(info->mRTPSocket, info->mRTCPSocket);
+
+                        close(info->mRTPSocket);
+                        close(info->mRTCPSocket);
+                    }
                 }
+                mTracks.clear();
+                mSetupTracksSuccessful = false;
+                mSeekPending = false;
+                mFirstAccessUnit = true;
+                mFirstAccessUnitNTP = 0;
+                mNumAccessUnitsReceived = 0;
+                mReceivedFirstRTCPPacket = false;
 
                 sp<AMessage> reply = new AMessage('tear', id());
 
+                int32_t reconnect;
+                if (msg->findInt32("reconnect", &reconnect) && reconnect) {
+                    reply->setInt32("reconnect", true);
+                }
+
                 AString request;
                 request = "TEARDOWN ";
 
@@ -366,6 +402,12 @@
                      << result << " (" << strerror(-result) << ")";
 
                 sp<AMessage> reply = new AMessage('disc', id());
+
+                int32_t reconnect;
+                if (msg->findInt32("reconnect", &reconnect) && reconnect) {
+                    reply->setInt32("reconnect", true);
+                }
+
                 mConn->disconnect(reply);
                 break;
             }
@@ -389,23 +431,34 @@
                 }
 
                 mNumAccessUnitsReceived = 0;
-                msg->post(500000);
+                msg->post(kAccessUnitTimeoutUs);
                 break;
             }
 
             case 'accu':
             {
+                int32_t firstRTCP;
+                if (msg->findInt32("first-rtcp", &firstRTCP)) {
+                    mReceivedFirstRTCPPacket = true;
+                    break;
+                }
+
                 ++mNumAccessUnitsReceived;
 
                 if (!mCheckPending) {
                     mCheckPending = true;
                     sp<AMessage> check = new AMessage('chek', id());
-                    check->post(500000);
+                    check->post(kAccessUnitTimeoutUs);
                 }
 
                 size_t trackIndex;
                 CHECK(msg->findSize("track-index", &trackIndex));
 
+                if (trackIndex >= mTracks.size()) {
+                    LOG(ERROR) << "late packets ignored.";
+                    break;
+                }
+
                 TrackInfo *track = &mTracks.editItemAt(trackIndex);
 
                 int32_t eos;
@@ -449,6 +502,10 @@
                 }
 
                 if (mFirstAccessUnit) {
+                    mDoneMsg->setInt32("result", OK);
+                    mDoneMsg->post();
+                    mDoneMsg = NULL;
+
                     mFirstAccessUnit = false;
                     mFirstAccessUnitNTP = ntpTime;
                 }
@@ -574,9 +631,20 @@
 
             case 'tiou':
             {
-                if (mFirstAccessUnit) {
-                    LOG(WARNING) << "Never received any data, disconnecting.";
-                    (new AMessage('abor', id()))->post();
+                if (!mReceivedFirstRTCPPacket) {
+                    if (mTryTCPInterleaving) {
+                        LOG(WARNING) << "Never received any data, disconnecting.";
+                        (new AMessage('abor', id()))->post();
+                    } else {
+                        LOG(WARNING)
+                            << "Never received any data, switching transports.";
+
+                        mTryTCPInterleaving = true;
+
+                        sp<AMessage> msg = new AMessage('abor', id());
+                        msg->setInt32("reconnect", true);
+                        msg->post();
+                    }
                 }
                 break;
             }
@@ -697,6 +765,8 @@
     uint64_t mFirstAccessUnitNTP;
     int64_t mNumAccessUnitsReceived;
     bool mCheckPending;
+    bool mTryTCPInterleaving;
+    bool mReceivedFirstRTCPPacket;
 
     struct TrackInfo {
         AString mURL;
@@ -715,6 +785,7 @@
     void setupTrack(size_t index) {
         sp<APacketSource> source =
             new APacketSource(mSessionDesc, index);
+
         if (source->initCheck() != OK) {
             LOG(WARNING) << "Unsupported format. Ignoring track #"
                          << index << ".";
@@ -746,26 +817,26 @@
         request.append(trackURL);
         request.append(" RTSP/1.0\r\n");
 
-#if USE_TCP_INTERLEAVED
-        size_t interleaveIndex = 2 * (mTracks.size() - 1);
-        info->mUsingInterleavedTCP = true;
-        info->mRTPSocket = interleaveIndex;
-        info->mRTCPSocket = interleaveIndex + 1;
+        if (mTryTCPInterleaving) {
+            size_t interleaveIndex = 2 * (mTracks.size() - 1);
+            info->mUsingInterleavedTCP = true;
+            info->mRTPSocket = interleaveIndex;
+            info->mRTCPSocket = interleaveIndex + 1;
 
-        request.append("Transport: RTP/AVP/TCP;interleaved=");
-        request.append(interleaveIndex);
-        request.append("-");
-        request.append(interleaveIndex + 1);
-#else
-        unsigned rtpPort;
-        ARTPConnection::MakePortPair(
-                &info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
+            request.append("Transport: RTP/AVP/TCP;interleaved=");
+            request.append(interleaveIndex);
+            request.append("-");
+            request.append(interleaveIndex + 1);
+        } else {
+            unsigned rtpPort;
+            ARTPConnection::MakePortPair(
+                    &info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
 
-        request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
-        request.append(rtpPort);
-        request.append("-");
-        request.append(rtpPort + 1);
-#endif
+            request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
+            request.append(rtpPort);
+            request.append("-");
+            request.append(rtpPort + 1);
+        }
 
         request.append("\r\n");
 
diff --git a/media/mtp/MtpDatabase.h b/media/mtp/MtpDatabase.h
index 899b34a..c8cb016 100644
--- a/media/mtp/MtpDatabase.h
+++ b/media/mtp/MtpDatabase.h
@@ -93,6 +93,10 @@
                                             MtpObjectFormat format) = 0;
 
     virtual MtpProperty*            getDevicePropertyDesc(MtpDeviceProperty property) = 0;
+
+    virtual void                    sessionStarted() = 0;
+
+    virtual void                    sessionEnded() = 0;
 };
 
 }; // namespace android
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index bd68f75..fca0142 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -342,7 +342,7 @@
     MtpResponseCode ret = readResponse();
     if (ret == MTP_RESPONSE_OK) {
         MtpProperty* property = new MtpProperty;
-        property->read(mData, true);
+        property->read(mData);
         return property;
     }
     return NULL;
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 932ad6a..c7a91d6 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -120,7 +120,7 @@
     delete[] mEnumValues;
 }
 
-void MtpProperty::read(MtpDataPacket& packet, bool deviceProp) {
+void MtpProperty::read(MtpDataPacket& packet) {
 
     mCode = packet.getUInt16();
     mType = packet.getUInt16();
@@ -141,7 +141,7 @@
             break;
         default:
             readValue(packet, mDefaultValue);
-            if (deviceProp)
+            if (isDeviceProperty())
                 readValue(packet, mCurrentValue);
     }
     mGroupCode = packet.getUInt32();
@@ -159,7 +159,6 @@
     }
 }
 
-// FIXME - only works for object properties
 void MtpProperty::write(MtpDataPacket& packet) {
     packet.putUInt16(mCode);
     packet.putUInt16(mType);
diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h
index c5b4e28..64cfb93 100644
--- a/media/mtp/MtpProperty.h
+++ b/media/mtp/MtpProperty.h
@@ -65,16 +65,22 @@
 
     inline MtpPropertyCode getPropertyCode() const { return mCode; }
 
-    void                read(MtpDataPacket& packet, bool deviceProp);
+    void                read(MtpDataPacket& packet);
     void                write(MtpDataPacket& packet);
 
     void                print();
 
+    inline bool         isDeviceProperty() const {
+                            return (   ((mCode & 0xF000) == 0x5000)
+                                    || ((mCode & 0xF800) == 0xD000));
+                        }
+
 private:
     void                readValue(MtpDataPacket& packet, MtpPropertyValue& value);
     void                writeValue(MtpDataPacket& packet, MtpPropertyValue& value);
     MtpPropertyValue*   readArrayValues(MtpDataPacket& packet, int& length);
-    void                writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length);
+    void                writeArrayValues(MtpDataPacket& packet,
+                                            MtpPropertyValue* values, int length);
 };
 
 }; // namespace android
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 1e64e4f..3d3bd62 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -55,7 +55,7 @@
 //    MTP_OPERATION_SELF_TEST,
 //    MTP_OPERATION_SET_OBJECT_PROTECTION,
 //    MTP_OPERATION_POWER_DOWN,
-//    MTP_OPERATION_GET_DEVICE_PROP_DESC,
+    MTP_OPERATION_GET_DEVICE_PROP_DESC,
     MTP_OPERATION_GET_DEVICE_PROP_VALUE,
     MTP_OPERATION_SET_DEVICE_PROP_VALUE,
     MTP_OPERATION_RESET_DEVICE_PROP_VALUE,
@@ -185,6 +185,9 @@
             LOGV("skipping response\n");
         }
     }
+
+    if (mSessionOpen)
+        mDatabase->sessionEnded();
 }
 
 void MtpServer::sendObjectAdded(MtpObjectHandle handle) {
@@ -285,6 +288,9 @@
         case MTP_OPERATION_GET_OBJECT_PROP_DESC:
             response = doGetObjectPropDesc();
             break;
+        case MTP_OPERATION_GET_DEVICE_PROP_DESC:
+            response = doGetDevicePropDesc();
+            break;
         default:
             response = MTP_RESPONSE_OPERATION_NOT_SUPPORTED;
             break;
@@ -346,6 +352,9 @@
     }
     mSessionID = mRequest.getParameter(1);
     mSessionOpen = true;
+
+    mDatabase->sessionStarted();
+
     return MTP_RESPONSE_OK;
 }
 
@@ -354,6 +363,7 @@
         return MTP_RESPONSE_SESSION_NOT_OPEN;
     mSessionID = 0;
     mSessionOpen = false;
+    mDatabase->sessionEnded();
     return MTP_RESPONSE_OK;
 }
 
diff --git a/native/android/input.cpp b/native/android/input.cpp
index a82282d..379960a 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -33,7 +33,6 @@
 using android::KeyEvent;
 using android::MotionEvent;
 using android::InputDeviceInfo;
-using android::InputDeviceProxy;
 using android::sp;
 using android::Vector;
 
@@ -270,74 +269,3 @@
 void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled) {
     queue->finishEvent(event, handled != 0);
 }
-
-
-int32_t AInputDevice_getDeviceIds(int32_t* idBuf, size_t nMax, size_t* nActual) {
-    Vector<int32_t> ids;
-    InputDeviceProxy::getDeviceIds(ids);
-
-    if (nActual) {
-        *nActual = ids.size();
-    }
-
-    if (idBuf && ids.size() < nMax) {
-        memcpy(idBuf, ids.array(), ids.size() * sizeof(int32_t));
-        return 0;
-    }
-
-    return -ENOMEM;
-}
-
-AInputDevice* AInputDevice_acquire(int32_t deviceId) {
-    sp<InputDeviceProxy> proxy(InputDeviceProxy::getDevice(deviceId));
-    if (proxy == NULL) {
-        return NULL;
-    }
-    proxy->incStrong((void*)AInputDevice_acquire);
-    return static_cast<AInputDevice*>(proxy.get());
-}
-
-void AInputDevice_release(AInputDevice* device) {
-    if (device) {
-        InputDeviceProxy* proxy = static_cast<InputDeviceProxy*>(device);
-        proxy->decStrong((void*)AInputDevice_acquire);
-    }
-}
-
-const char* AInputDevice_getName(AInputDevice* device) {
-    InputDeviceProxy* proxy = static_cast<InputDeviceProxy*>(device);
-    return proxy->getInfo()->getName().string();
-}
-
-uint32_t AInputDevice_getSources(AInputDevice* device) {
-    InputDeviceProxy* proxy = static_cast<InputDeviceProxy*>(device);
-    return proxy->getInfo()->getSources();
-}
-
-int32_t AInputDevice_getKeyboardType(AInputDevice* device) {
-    InputDeviceProxy* proxy = static_cast<InputDeviceProxy*>(device);
-    return proxy->getInfo()->getKeyboardType();
-}
-
-int32_t AInputDevice_getMotionRange(AInputDevice* device, int32_t rangeType,
-        float* outMin, float* outMax, float* outFlat, float* outFuzz) {
-    InputDeviceProxy* proxy = static_cast<InputDeviceProxy*>(device);
-    const InputDeviceInfo::MotionRange* range = proxy->getInfo()->getMotionRange(rangeType);
-    if (range) {
-        if (outMin) {
-            *outMin = range->min;
-        }
-        if (outMax) {
-            *outMax = range->max;
-        }
-        if (outFlat) {
-            *outFlat = range->flat;
-        }
-        if (outFuzz) {
-            *outFuzz = range->fuzz;
-        }
-        return 0;
-    } else {
-        return -ENOTSUP;
-    }
-}
diff --git a/native/include/android/input.h b/native/include/android/input.h
index 243c33c..418f609 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -662,64 +662,6 @@
  */
 void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
 
-/*
- * Input devices.
- *
- * These functions provide a mechanism for querying the set of available input devices
- * and their characteristics and capabilities.
- */
-struct AInputDevice;
-typedef struct AInputDevice AInputDevice;
-
-/*
- * Populates the supplied array with the ids of all input devices in the system.
- * Sets nActual to the actual number of devices.
- * Returns zero if enumeration was successful.
- * Returns non-zero if the actual number of devices is greater than nMax, in which case the
- * client should call the method again with a larger id buffer.
- */
-int32_t AInputDevice_getDeviceIds(int32_t* idBuf, size_t nMax, size_t* nActual);
-
-/*
- * Acquires a device by id.
- * Returns NULL if the device was not found.
- *
- * Note: The returned object must be freed using AInputDevice_release when no longer needed.
- */
-AInputDevice* AInputDevice_acquire(int32_t deviceId);
-
-/*
- * Releases a device previously acquired by AInputDevice_acquire.
- * If device is NULL, this function does nothing.
- */
-void AInputDevice_release(AInputDevice* device);
-
-/*
- * Gets the name of an input device.
- *
- * Note: The caller should copy the name into a private buffer since the returned pointer
- * will become invalid when the device object is released.
- */
-const char* AInputDevice_getName(AInputDevice* device);
-
-/*
- * Gets the combination of input sources provided by the input device.
- */
-uint32_t AInputDevice_getSources(AInputDevice* device);
-
-/*
- * Gets the keyboard type.
- */
-int32_t AInputDevice_getKeyboardType(AInputDevice* device);
-
-/* Gets the minimum value, maximum value, flat position and error tolerance for a
- * particular motion coodinate.
- * Returns zero if the device supports the specified motion range. */
-int32_t AInputDevice_getMotionRange(AInputDevice* device, int32_t rangeType,
-        float* outMin, float* outMax, float* outFlat, float* outFuzz);
-
-//TODO hasKey, keymap stuff, etc...
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 8349fe6..2ae34e3 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -22,7 +22,7 @@
     <bool name="def_airplane_mode_on">false</bool>
     <!-- Comma-separated list of bluetooth, wifi, and cell. -->
     <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi</string>
-    <string name="airplane_mode_toggleable_radios" translatable="false">wifi</string>
+    <string name="airplane_mode_toggleable_radios" translatable="false">bluetooth,wifi</string>
     <bool name="def_auto_time">true</bool>
     <bool name="def_accelerometer_rotation">true</bool>
     <!-- Default screen brightness, from 0 to 255.  102 is 40%. -->
@@ -72,4 +72,6 @@
 
     <!-- Default for Settings.System.VIBRATE_IN_SILENT -->
     <bool name="def_vibrate_in_silent">true</bool>
+
+    <bool name="def_use_ptp_interface">false</bool>
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 7395233..c1ad1ca 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -64,7 +64,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 56;
+    private static final int DATABASE_VERSION = 57;
 
     private Context mContext;
 
@@ -713,6 +713,27 @@
              }
             upgradeVersion = 56;
         }
+
+        if (upgradeVersion == 56) {
+            /*
+             * Add Bluetooth to list of toggleable radios in airplane mode
+             */
+            db.beginTransaction();
+            SQLiteStatement stmt = null;
+            try {
+                db.execSQL("DELETE FROM system WHERE name='"
+                        + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'");
+                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+                        + " VALUES(?,?);");
+                loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
+                        R.string.airplane_mode_toggleable_radios);
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+                if (stmt != null) stmt.close();
+            }
+            upgradeVersion = 57;
+        }
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
@@ -1047,6 +1068,9 @@
     
             loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
                     R.bool.def_vibrate_in_silent);
+
+            loadBooleanSetting(stmt, Settings.System.USE_PTP_INTERFACE,
+                    R.bool.def_use_ptp_interface);
         } finally {
             if (stmt != null) stmt.close();
         }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 18e2f479..c81da70 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -5,6 +5,8 @@
         >
 
     <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.GET_TASKS" />
 
     <application
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 9ccc5a9..5e48461 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -1,4 +1,6 @@
 -keep class com.android.systemui.statusbar.tablet.TabletStatusBarService {
   public void notificationIconsClicked(android.view.View);
   public void systemInfoClicked(android.view.View);
+  public void recentButtonClicked(android.view.View);
+  public void toggleLightsOut(android.view.View);
 }
diff --git a/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml b/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml
new file mode 100644
index 0000000..5b6778e
--- /dev/null
+++ b/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/ease_out_interpolator.xml
+**
+** Copyright 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.
+*/
+-->
+
+<decelerateInterpolator 
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:factor="10.0" />
diff --git a/packages/SystemUI/res/anim/lights_out_in.xml b/packages/SystemUI/res/anim/lights_out_in.xml
new file mode 100644
index 0000000..8154ec0
--- /dev/null
+++ b/packages/SystemUI/res/anim/lights_out_in.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    >
+    <translate android:fromYDelta="100%p" android:toYDelta="0"
+        android:duration="@android:integer/config_mediumAnimTime" 
+        android:interpolator="@anim/hydraulic_brake_interpolator"
+        />
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:duration="@android:integer/config_longAnimTime" 
+        />
+</set>
diff --git a/packages/SystemUI/res/anim/lights_out_out.xml b/packages/SystemUI/res/anim/lights_out_out.xml
new file mode 100644
index 0000000..b4bc55a
--- /dev/null
+++ b/packages/SystemUI/res/anim/lights_out_out.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    >
+    <translate android:toYDelta="100%p" android:fromYDelta="0" 
+        android:duration="@android:integer/config_mediumAnimTime" 
+        android:interpolator="@anim/hydraulic_brake_interpolator"
+        />
+    <alpha android:toAlpha="0.0" android:fromAlpha="1.0"
+        android:duration="@android:integer/config_longAnimTime" 
+        />
+</set>
diff --git a/packages/SystemUI/res/anim/status_bar_in.xml b/packages/SystemUI/res/anim/status_bar_in.xml
new file mode 100644
index 0000000..460fe50
--- /dev/null
+++ b/packages/SystemUI/res/anim/status_bar_in.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    >
+    <translate android:fromYDelta="-100%p" android:toYDelta="0"
+        android:duration="@android:integer/config_longAnimTime" 
+        android:interpolator="@anim/hydraulic_brake_interpolator"
+        />
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:duration="@android:integer/config_longAnimTime" 
+        />
+</set>
diff --git a/packages/SystemUI/res/anim/status_bar_out.xml b/packages/SystemUI/res/anim/status_bar_out.xml
new file mode 100644
index 0000000..6572ab4
--- /dev/null
+++ b/packages/SystemUI/res/anim/status_bar_out.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    >
+    <translate android:toYDelta="-100%p" android:fromYDelta="0"
+        android:duration="@android:integer/config_longAnimTime" 
+        android:interpolator="@anim/hydraulic_brake_interpolator"
+        />
+    <alpha android:toAlpha="0.0" android:fromAlpha="1.0"
+        android:duration="@android:integer/config_longAnimTime" 
+        />
+</set>
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_0.png b/packages/SystemUI/res/drawable-mdpi/battery_0.png
deleted file mode 100644
index e81638d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_10.png b/packages/SystemUI/res/drawable-mdpi/battery_10.png
deleted file mode 100644
index a739f50..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_10.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_100.png b/packages/SystemUI/res/drawable-mdpi/battery_100.png
deleted file mode 100644
index 9a66db38..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_25.png b/packages/SystemUI/res/drawable-mdpi/battery_25.png
deleted file mode 100644
index 7ae7ebb..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_25.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_5.png b/packages/SystemUI/res/drawable-mdpi/battery_5.png
deleted file mode 100644
index 1a15a21..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_5.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_50.png b/packages/SystemUI/res/drawable-mdpi/battery_50.png
deleted file mode 100644
index 7088066..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_50.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_75.png b/packages/SystemUI/res/drawable-mdpi/battery_75.png
deleted file mode 100644
index d4cfb6f..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_75.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
deleted file mode 100644
index 60bbe6c..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_off.png
new file mode 100644
index 0000000..d897ba61
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_on.png
new file mode 100644
index 0000000..0296b5b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..6c5a79b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_mini.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_mini.png
new file mode 100644
index 0000000..9ababb7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_mini.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_on.png
new file mode 100644
index 0000000..668b472
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_off.png
new file mode 100644
index 0000000..e463ba4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_on.png
new file mode 100644
index 0000000..1239d50
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness.png
new file mode 100644
index 0000000..97fa5fc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_auto.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_auto.png
new file mode 100644
index 0000000..37a1533
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_auto.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_low.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_low.png
new file mode 100644
index 0000000..8a55e3a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_low.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_close.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_close.png
new file mode 100644
index 0000000..53abcbc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_close.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_default_bg.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_default_bg.png
new file mode 100644
index 0000000..3e82d4e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_default_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_off.png
new file mode 100644
index 0000000..dc2ed34
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_on.png
new file mode 100644
index 0000000..1e39fdc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
new file mode 100644
index 0000000..ed813dc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lightsout.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lightsout.png
new file mode 100644
index 0000000..8a07acc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lightsout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
new file mode 100644
index 0000000..d7775f2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_open.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_open.png
new file mode 100644
index 0000000..b7d624e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_open.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_press_bg.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_press_bg.png
new file mode 100644
index 0000000..0958393
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_press_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..178af73
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png
new file mode 100644
index 0000000..adaadf7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png
new file mode 100644
index 0000000..fdc0ac7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png
new file mode 100644
index 0000000..4517d1b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_off.png
new file mode 100644
index 0000000..bd11e86
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_on.png
new file mode 100644
index 0000000..1b3ba2f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_mini.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_mini.png
new file mode 100644
index 0000000..ffbd2d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_mini.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_off.png
new file mode 100644
index 0000000..87acc14
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png
new file mode 100644
index 0000000..bbb1c74
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_0.png b/packages/SystemUI/res/drawable-mdpi/signal_0.png
deleted file mode 100644
index ff2727b..0000000
--- a/packages/SystemUI/res/drawable-mdpi/signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_100.png b/packages/SystemUI/res/drawable-mdpi/signal_100.png
deleted file mode 100644
index 55c34ff..0000000
--- a/packages/SystemUI/res/drawable-mdpi/signal_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_25.png b/packages/SystemUI/res/drawable-mdpi/signal_25.png
deleted file mode 100644
index a415596..0000000
--- a/packages/SystemUI/res/drawable-mdpi/signal_25.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_50.png b/packages/SystemUI/res/drawable-mdpi/signal_50.png
deleted file mode 100644
index 3c5a708b0..0000000
--- a/packages/SystemUI/res/drawable-mdpi/signal_50.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_75.png b/packages/SystemUI/res/drawable-mdpi/signal_75.png
deleted file mode 100644
index e176f37..0000000
--- a/packages/SystemUI/res/drawable-mdpi/signal_75.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_scan1.png b/packages/SystemUI/res/drawable-mdpi/signal_scan1.png
deleted file mode 100644
index f64b9cc..0000000
--- a/packages/SystemUI/res/drawable-mdpi/signal_scan1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_scan2.png b/packages/SystemUI/res/drawable-mdpi/signal_scan2.png
deleted file mode 100644
index 982feb4..0000000
--- a/packages/SystemUI/res/drawable-mdpi/signal_scan2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_scan3.png b/packages/SystemUI/res/drawable-mdpi/signal_scan3.png
deleted file mode 100644
index a4c0689..0000000
--- a/packages/SystemUI/res/drawable-mdpi/signal_scan3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_scan4.png b/packages/SystemUI/res/drawable-mdpi/signal_scan4.png
deleted file mode 100644
index d1e95fe..0000000
--- a/packages/SystemUI/res/drawable-mdpi/signal_scan4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_0.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_0.png
new file mode 100644
index 0000000..ff75a51
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_10.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_10.png
new file mode 100644
index 0000000..66ab4c6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_10.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_100.png
new file mode 100644
index 0000000..3b50500
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_20.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_20.png
new file mode 100644
index 0000000..9119065
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_30.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_30.png
new file mode 100644
index 0000000..296f19f26b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_30.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_40.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_40.png
new file mode 100644
index 0000000..9daab23
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_50.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_50.png
new file mode 100644
index 0000000..62d24c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_50.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_60.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_60.png
new file mode 100644
index 0000000..eea927a1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_70.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_70.png
new file mode 100644
index 0000000..6816088
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_70.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_80.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_80.png
new file mode 100644
index 0000000..b7dd9bb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_90.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_90.png
new file mode 100644
index 0000000..6e36f53
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_90.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_100.png
new file mode 100644
index 0000000..8eb0f29
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_red.png b/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_red.png
new file mode 100644
index 0000000..adcc6b9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_red.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_hidenotification_handle.png b/packages/SystemUI/res/drawable-mdpi/sysbar_hidenotification_handle.png
new file mode 100644
index 0000000..e43edd7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_hidenotification_handle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_minimeter_bg.png b/packages/SystemUI/res/drawable-mdpi/sysbar_minimeter_bg.png
new file mode 100644
index 0000000..0d265fc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_minimeter_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/sysbar_panel_bg.9.png
new file mode 100644
index 0000000..77e034b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png
new file mode 100644
index 0000000..7469372
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png
new file mode 100644
index 0000000..6625d9a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png
new file mode 100644
index 0000000..b2e763b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png
new file mode 100644
index 0000000..fb66362
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png
new file mode 100644
index 0000000..a87d94e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png
new file mode 100644
index 0000000..8e229d5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png
new file mode 100644
index 0000000..fe989d4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png
new file mode 100644
index 0000000..aac57dc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png
new file mode 100644
index 0000000..2281968
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png
new file mode 100644
index 0000000..7177ae1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png
new file mode 100644
index 0000000..7f60480
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signalmini_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signalmini_100.png
new file mode 100644
index 0000000..a5eaa63
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signalmini_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_off.9.png b/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_off.9.png
new file mode 100644
index 0000000..94849d8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_on.9.png b/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_on.9.png
new file mode 100644
index 0000000..f11058c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/wifi_0.png b/packages/SystemUI/res/drawable-mdpi/wifi_0.png
deleted file mode 100644
index e81638d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/wifi_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/wifi_100.png b/packages/SystemUI/res/drawable-mdpi/wifi_100.png
deleted file mode 100644
index 4468389..0000000
--- a/packages/SystemUI/res/drawable-mdpi/wifi_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/wifi_25.png b/packages/SystemUI/res/drawable-mdpi/wifi_25.png
deleted file mode 100644
index 0e389a7..0000000
--- a/packages/SystemUI/res/drawable-mdpi/wifi_25.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/wifi_50.png b/packages/SystemUI/res/drawable-mdpi/wifi_50.png
deleted file mode 100644
index 1cad0d1..0000000
--- a/packages/SystemUI/res/drawable-mdpi/wifi_50.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/wifi_75.png b/packages/SystemUI/res/drawable-mdpi/wifi_75.png
deleted file mode 100644
index dd2d7dc..0000000
--- a/packages/SystemUI/res/drawable-mdpi/wifi_75.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/wifi_scan1.png b/packages/SystemUI/res/drawable-mdpi/wifi_scan1.png
deleted file mode 100644
index 0e389a7..0000000
--- a/packages/SystemUI/res/drawable-mdpi/wifi_scan1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/wifi_scan2.png b/packages/SystemUI/res/drawable-mdpi/wifi_scan2.png
deleted file mode 100644
index 34e7c70..0000000
--- a/packages/SystemUI/res/drawable-mdpi/wifi_scan2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/wifi_scan3.png b/packages/SystemUI/res/drawable-mdpi/wifi_scan3.png
deleted file mode 100644
index 4c2a9e1..0000000
--- a/packages/SystemUI/res/drawable-mdpi/wifi_scan3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/wifi_scan4.png b/packages/SystemUI/res/drawable-mdpi/wifi_scan4.png
deleted file mode 100644
index b504131..0000000
--- a/packages/SystemUI/res/drawable-mdpi/wifi_scan4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/battery.xml b/packages/SystemUI/res/drawable/battery.xml
deleted file mode 100644
index 3bc0c74..0000000
--- a/packages/SystemUI/res/drawable/battery.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<level-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:maxLevel="1" android:drawable="@drawable/battery_0" />
-    <item android:maxLevel="5" android:drawable="@drawable/battery_5" />
-    <item android:maxLevel="10" android:drawable="@drawable/battery_10" />
-    <item android:maxLevel="25" android:drawable="@drawable/battery_25" />
-    <item android:maxLevel="50" android:drawable="@drawable/battery_50" />
-    <item android:maxLevel="75" android:drawable="@drawable/battery_75" />
-    <item android:maxLevel="101" android:drawable="@drawable/battery_100" />
-</level-list>
-
diff --git a/packages/SystemUI/res/drawable/battery_charging.xml b/packages/SystemUI/res/drawable/battery_charging.xml
deleted file mode 100644
index c9b77dd..0000000
--- a/packages/SystemUI/res/drawable/battery_charging.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<level-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:maxLevel="25">
-        <animation-list android:oneshot="false">
-            <item android:drawable="@drawable/battery_0" android:duration="1000" />
-            <item android:drawable="@drawable/battery_25" android:duration="1000" />
-        </animation-list>
-    </item>
-    <item android:maxLevel="50">
-        <animation-list android:oneshot="false">
-            <item android:drawable="@drawable/battery_25" android:duration="1000" />
-            <item android:drawable="@drawable/battery_50" android:duration="1000" />
-        </animation-list>
-    </item>
-    <item android:maxLevel="75">
-        <animation-list android:oneshot="false">
-            <item android:drawable="@drawable/battery_50" android:duration="1000" />
-            <item android:drawable="@drawable/battery_75" android:duration="1000" />
-        </animation-list>
-    </item>
-    <item android:maxLevel="92">
-        <animation-list android:oneshot="false">
-            <item android:drawable="@drawable/battery_75" android:duration="1000" />
-            <item android:drawable="@drawable/battery_100" android:duration="1000" />
-        </animation-list>
-    </item>
-    <item android:maxLevel="101" android:drawable="@drawable/battery_100" />
-</level-list>
-
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml b/packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml
new file mode 100644
index 0000000..d8ba2a8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_press_bg" />
+    <item android:drawable="@drawable/ic_sysbar_default_bg" />
+</selector>
+
diff --git a/packages/SystemUI/res/drawable/signal.xml b/packages/SystemUI/res/drawable/signal.xml
deleted file mode 100644
index 7367418..0000000
--- a/packages/SystemUI/res/drawable/signal.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<level-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:maxLevel="01" android:drawable="@drawable/signal_0" />
-    <item android:maxLevel="25" android:drawable="@drawable/signal_25" />
-    <item android:maxLevel="50" android:drawable="@drawable/signal_50" />
-    <item android:maxLevel="75" android:drawable="@drawable/signal_75" />
-    <item android:maxLevel="101" android:drawable="@drawable/signal_100" />
-</level-list>
-
diff --git a/packages/SystemUI/res/drawable/signal_scan.xml b/packages/SystemUI/res/drawable/signal_scan.xml
deleted file mode 100644
index fe21992..0000000
--- a/packages/SystemUI/res/drawable/signal_scan.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/signal_scan1" android:duration="500" />
-    <item android:drawable="@drawable/signal_scan2" android:duration="500" />
-    <item android:drawable="@drawable/signal_scan3" android:duration="500" />
-    <item android:drawable="@drawable/signal_scan4" android:duration="500" />
-    <item android:drawable="@drawable/signal_scan3" android:duration="500" />
-    <item android:drawable="@drawable/signal_scan2" android:duration="500" />
-</animation-list>
-
diff --git a/packages/SystemUI/res/drawable/status_bar_recent.xml b/packages/SystemUI/res/drawable/status_bar_recent.xml
new file mode 100755
index 0000000..d708455
--- /dev/null
+++ b/packages/SystemUI/res/drawable/status_bar_recent.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/status_bar_recent_pressed" />
+    <item android:drawable="@drawable/status_bar_recent_default" />
+</selector>
+
diff --git a/packages/SystemUI/res/drawable/sysbar_battery.xml b/packages/SystemUI/res/drawable/sysbar_battery.xml
new file mode 100644
index 0000000..9551bf0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/sysbar_battery.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 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.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:maxLevel="01" android:drawable="@drawable/sysbar_battery_0" />
+    <item android:maxLevel="10" android:drawable="@drawable/sysbar_battery_10" />
+    <item android:maxLevel="20" android:drawable="@drawable/sysbar_battery_20" />
+    <item android:maxLevel="30" android:drawable="@drawable/sysbar_battery_30" />
+    <item android:maxLevel="40" android:drawable="@drawable/sysbar_battery_40" />
+    <item android:maxLevel="50" android:drawable="@drawable/sysbar_battery_50" />
+    <item android:maxLevel="60" android:drawable="@drawable/sysbar_battery_60" />
+    <item android:maxLevel="70" android:drawable="@drawable/sysbar_battery_70" />
+    <item android:maxLevel="80" android:drawable="@drawable/sysbar_battery_80" />
+    <item android:maxLevel="90" android:drawable="@drawable/sysbar_battery_90" />
+    <item android:maxLevel="101" android:drawable="@drawable/sysbar_battery_100" />
+</level-list>
diff --git a/packages/SystemUI/res/drawable/sysbar_batterymini.xml b/packages/SystemUI/res/drawable/sysbar_batterymini.xml
new file mode 100644
index 0000000..c7300e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/sysbar_batterymini.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 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.
+*/
+-->
+
+<clip xmlns:android="http://schemas.android.com/apk/res/android"
+        android:clipOrientation="horizontal"
+        android:maxLevel="100"
+        android:gravity="left">
+    <level-list>
+        <item android:maxLevel="1500"  android:drawable="@drawable/sysbar_batterymini_red" />
+        <item android:maxLevel="10000" android:drawable="@drawable/sysbar_batterymini_100" />
+    </level-list>
+</clip>
diff --git a/packages/SystemUI/res/drawable/sysbar_signal.xml b/packages/SystemUI/res/drawable/sysbar_signal.xml
new file mode 100644
index 0000000..9561c37
--- /dev/null
+++ b/packages/SystemUI/res/drawable/sysbar_signal.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 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.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:maxLevel="01" android:drawable="@drawable/sysbar_signal_0" />
+    <item android:maxLevel="10" android:drawable="@drawable/sysbar_signal_10" />
+    <item android:maxLevel="20" android:drawable="@drawable/sysbar_signal_20" />
+    <item android:maxLevel="30" android:drawable="@drawable/sysbar_signal_30" />
+    <item android:maxLevel="40" android:drawable="@drawable/sysbar_signal_40" />
+    <item android:maxLevel="50" android:drawable="@drawable/sysbar_signal_50" />
+    <item android:maxLevel="60" android:drawable="@drawable/sysbar_signal_60" />
+    <item android:maxLevel="70" android:drawable="@drawable/sysbar_signal_70" />
+    <item android:maxLevel="80" android:drawable="@drawable/sysbar_signal_80" />
+    <item android:maxLevel="90" android:drawable="@drawable/sysbar_signal_90" />
+    <item android:maxLevel="101" android:drawable="@drawable/sysbar_signal_100" />
+</level-list>
diff --git a/packages/SystemUI/res/drawable/sysbar_signalmini.xml b/packages/SystemUI/res/drawable/sysbar_signalmini.xml
new file mode 100644
index 0000000..598bf10
--- /dev/null
+++ b/packages/SystemUI/res/drawable/sysbar_signalmini.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 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.
+*/
+-->
+
+<clip xmlns:android="http://schemas.android.com/apk/res/android"
+        android:clipOrientation="horizontal"
+        android:gravity="right"
+        android:maxLevel="10000"
+        android:drawable="@drawable/sysbar_signalmini_100" />
diff --git a/packages/SystemUI/res/drawable/sysbar_wifi.xml b/packages/SystemUI/res/drawable/sysbar_wifi.xml
new file mode 100644
index 0000000..9561c37
--- /dev/null
+++ b/packages/SystemUI/res/drawable/sysbar_wifi.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 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.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:maxLevel="01" android:drawable="@drawable/sysbar_signal_0" />
+    <item android:maxLevel="10" android:drawable="@drawable/sysbar_signal_10" />
+    <item android:maxLevel="20" android:drawable="@drawable/sysbar_signal_20" />
+    <item android:maxLevel="30" android:drawable="@drawable/sysbar_signal_30" />
+    <item android:maxLevel="40" android:drawable="@drawable/sysbar_signal_40" />
+    <item android:maxLevel="50" android:drawable="@drawable/sysbar_signal_50" />
+    <item android:maxLevel="60" android:drawable="@drawable/sysbar_signal_60" />
+    <item android:maxLevel="70" android:drawable="@drawable/sysbar_signal_70" />
+    <item android:maxLevel="80" android:drawable="@drawable/sysbar_signal_80" />
+    <item android:maxLevel="90" android:drawable="@drawable/sysbar_signal_90" />
+    <item android:maxLevel="101" android:drawable="@drawable/sysbar_signal_100" />
+</level-list>
diff --git a/packages/SystemUI/res/drawable/sysbar_wifimini.xml b/packages/SystemUI/res/drawable/sysbar_wifimini.xml
new file mode 100644
index 0000000..ca6c9ed
--- /dev/null
+++ b/packages/SystemUI/res/drawable/sysbar_wifimini.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 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.
+*/
+-->
+
+<clip xmlns:android="http://schemas.android.com/apk/res/android"
+        android:clipOrientation="horizontal"
+        android:gravity="right"
+        android:maxLevel="100"
+        android:drawable="@drawable/sysbar_signalmini_100" />
diff --git a/packages/SystemUI/res/drawable/wifi.xml b/packages/SystemUI/res/drawable/wifi.xml
deleted file mode 100644
index 6e63af6..0000000
--- a/packages/SystemUI/res/drawable/wifi.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<level-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:maxLevel="01" android:drawable="@drawable/wifi_0" />
-    <item android:maxLevel="25" android:drawable="@drawable/wifi_25" />
-    <item android:maxLevel="50" android:drawable="@drawable/wifi_50" />
-    <item android:maxLevel="75" android:drawable="@drawable/wifi_75" />
-    <item android:maxLevel="101" android:drawable="@drawable/wifi_100" />
-
-</level-list>
-
diff --git a/packages/SystemUI/res/drawable/wifi_scan.xml b/packages/SystemUI/res/drawable/wifi_scan.xml
deleted file mode 100644
index 5888d0e..0000000
--- a/packages/SystemUI/res/drawable/wifi_scan.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 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.
-*/
--->
-
-<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/wifi_scan1" android:duration="500" />
-    <item android:drawable="@drawable/wifi_scan2" android:duration="500" />
-    <item android:drawable="@drawable/wifi_scan3" android:duration="500" />
-    <item android:drawable="@drawable/wifi_scan4" android:duration="500" />
-    <item android:drawable="@drawable/wifi_scan3" android:duration="500" />
-    <item android:drawable="@drawable/wifi_scan2" android:duration="500" />
-</animation-list>
-
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 481bcde..f4040d91 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -19,13 +19,16 @@
 -->
 
 <!--    android:background="@drawable/status_bar_closed_default_background" -->
-<RelativeLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
     android:background="@drawable/status_bar_background"
-    android:focusable="true"
-    android:descendantFocusability="afterDescendants"
     >
+    <RelativeLayout
+        android:id="@+id/bar_contents"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
 
         <com.android.systemui.statusbar.tablet.NotificationIconArea
             android:id="@+id/notificationIcons"
@@ -35,18 +38,7 @@
             android:paddingLeft="6dip"
             android:gravity="center_vertical"
             android:orientation="horizontal"
-            android:clickable="true"
-            android:onClick="notificationIconsClicked"
-            android:background="@drawable/status_bar_icon_tray"
             >
-            <ImageView
-                class="com.android.systemui.statusbar.tablet.NotificationIconArea$MoreView"
-                android:id="@+id/expand"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:src="@drawable/status_bar_expand"
-                android:onClick="notificationIconsClicked"
-                />
             <view
                 class="com.android.systemui.statusbar.tablet.NotificationIconArea$IconLayout"
                 android:id="@+id/icons"
@@ -57,10 +49,19 @@
             <view
                 class="com.android.systemui.statusbar.tablet.NotificationIconArea$DraggerView"
                 android:id="@+id/handle"
-                android:layout_width="24dip"
+                android:layout_width="32dip"
                 android:layout_height="match_parent"
+                android:background="@drawable/sysbar_hidenotification_handle"
                 android:layout_marginLeft="8dip"
                 />
+            <ImageView
+                class="com.android.systemui.statusbar.tablet.NotificationIconArea$MoreView"
+                android:id="@+id/expand"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/ic_sysbar_open"
+                android:onClick="notificationIconsClicked"
+                />
 
         </com.android.systemui.statusbar.tablet.NotificationIconArea>
 
@@ -101,37 +102,64 @@
         </LinearLayout>
 
         <include layout="@layout/status_bar_center"
-            android:layout_width="160dip"
+            android:layout_width="256dip"
             android:layout_height="match_parent"
             android:layout_centerInParent="true"
             />
 
-        <com.android.systemui.statusbar.KeyButtonView android:id="@+id/back"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_toLeftOf="@+id/menu"
-            android:paddingLeft="4dip"
-            android:paddingRight="4dip"
-            android:src="@drawable/status_bar_back"
-            systemui:keyCode="4"
-            />
         <com.android.systemui.statusbar.KeyButtonView android:id="@+id/menu"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:layout_toLeftOf="@+id/home"
-            android:src="@drawable/status_bar_menu"
+            android:layout_toLeftOf="@+id/recent"
+            android:src="@drawable/ic_sysbar_menu"
+            android:background="@drawable/ic_sysbar_icon_bg"
             android:paddingLeft="4dip"
             android:paddingRight="4dip"
             systemui:keyCode="82"
             />
+        <ImageButton android:id="@+id/recent"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_toLeftOf="@+id/home"
+            android:src="@drawable/ic_sysbar_recent"
+            android:background="@drawable/ic_sysbar_icon_bg"
+            android:paddingLeft="4dip"
+            android:paddingRight="4dip"
+            android:onClick="recentButtonClicked"
+            />
         <com.android.systemui.statusbar.KeyButtonView android:id="@+id/home"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
+            android:layout_toLeftOf="@+id/back"
+            android:paddingLeft="4dip"
+            android:paddingRight="4dip"
+            android:src="@drawable/ic_sysbar_home"
+            android:background="@drawable/ic_sysbar_icon_bg"
+            systemui:keyCode="3"
+            />
+        <com.android.systemui.statusbar.KeyButtonView android:id="@+id/back"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
             android:layout_alignParentRight="true"
             android:paddingLeft="4dip"
             android:paddingRight="4dip"
-            android:src="@drawable/status_bar_home"
-            systemui:keyCode="3"
+            android:src="@drawable/ic_sysbar_back"
+            android:background="@drawable/ic_sysbar_icon_bg"
+            systemui:keyCode="4"
             />
-</RelativeLayout>
+    </RelativeLayout>
+
+    <!-- It's curtains for you. -->
+    <ImageView
+        android:id="@+id/lights_out"
+        android:src="@drawable/ic_sysbar_lightsout"
+        android:gravity="center"
+        android:background="#FF000000"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="invisible"
+        android:clickable="true"
+        android:onClick="toggleLightsOut"
+        />
+</FrameLayout>
 
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_center.xml b/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
index 5bf8316..2d74672 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
@@ -18,7 +18,7 @@
 <RelativeLayout android:id="@+id/systemInfo"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-    android:layout_width="160dip"
+    android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_centerInParent="true"
     android:clickable="true"
@@ -38,17 +38,35 @@
         />
     <ImageView
         android:id="@+id/battery"
-        android:layout_width="48dip"
-        android:layout_height="48dip"
+        android:layout_width="64dip"
+        android:layout_height="16dip"
         android:layout_toLeftOf="@id/clock"
-        android:src="@drawable/battery"
+        android:layout_centerInParent="true"
+        android:background="@drawable/sysbar_minimeter_bg" 
         />
     <ImageView
         android:id="@+id/signal"
-        android:layout_width="48dip"
-        android:layout_height="48dip"
+        android:layout_width="64dip"
+        android:layout_height="16dip"
         android:layout_toRightOf="@id/clock"
-        android:src="@drawable/signal"
+        android:layout_centerInParent="true"
+        android:background="@drawable/sysbar_minimeter_bg" 
+        />
+    <ImageView
+        android:id="@+id/battery_icon"
+        android:layout_height="30dip"
+        android:layout_width="30dip"
+        android:layout_toLeftOf="@id/battery"
+        android:layout_centerInParent="true"
+        android:src="@drawable/ic_sysbar_battery_mini"
+        />
+    <ImageView
+        android:id="@+id/signal_icon"
+        android:layout_height="30dip"
+        android:layout_width="30dip"
+        android:layout_toRightOf="@id/signal"
+        android:layout_centerInParent="true"
+        android:src="@drawable/ic_sysbar_wifi_mini"
         />
 </RelativeLayout>
 
diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
index 36c6388..7e469f7 100644
--- a/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
+++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
@@ -22,130 +22,187 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
-    android:background="#FF000000"
+    android:background="@drawable/sysbar_panel_bg"
     android:orientation="vertical"
+    android:paddingLeft="70dip"
+    android:paddingRight="120dip"
     >
 
-    <TextView android:id="@+id/settings_button"
-        style="?android:attr/textAppearance"
+    <!-- top row: quick settings buttons -->
+    <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="left|center_vertical"
-        android:layout_marginTop="2dip"
-        android:layout_marginBottom="1dip"
-        android:layout_marginRight="10dip"
-        android:padding="8dip"
-        android:textSize="20sp"
-        android:text="@string/system_panel_settings_button"
-        />
+        android:layout_height="64dip"
+        android:orientation="horizontal"
+        android:gravity="center"
+        >
+        <ImageButton android:id="@+id/brightness"
+            android:layout_width="90dip"
+            android:layout_height="64dip"
+            android:src="@drawable/ic_sysbar_brightness"
+            android:background="@drawable/sysbar_toggle_bg_off"
+            />
+        <ImageButton android:id="@+id/sound"
+            android:layout_width="90dip"
+            android:layout_height="64dip"
+            android:layout_marginLeft="8dip"
+            android:src="@drawable/ic_sysbar_sound_on"
+            android:background="@drawable/sysbar_toggle_bg_off"
+            />
+        <ImageButton android:id="@+id/orientation"
+            android:layout_width="90dip"
+            android:layout_height="64dip"
+            android:layout_marginLeft="8dip"
+            android:src="@drawable/ic_sysbar_rotate_on"
+            android:background="@drawable/sysbar_toggle_bg_off"
+            />
+        <ImageButton android:id="@+id/airplane"
+            android:layout_width="90dip"
+            android:layout_height="64dip"
+            android:layout_marginLeft="8dip"
+            android:src="@drawable/ic_sysbar_airplane_on"
+            android:background="@drawable/sysbar_toggle_bg_off"
+            />
+        <ImageButton android:id="@+id/gps"
+            android:layout_width="90dip"
+            android:layout_height="64dip"
+            android:layout_marginLeft="8dip"
+            android:src="@drawable/ic_sysbar_gps_on"
+            android:background="@drawable/sysbar_toggle_bg_off"
+            />
+        <ImageButton android:id="@+id/bluetooth"
+            android:layout_width="90dip"
+            android:layout_height="64dip"
+            android:layout_marginLeft="8dip"
+            android:src="@drawable/ic_sysbar_bluetooth_on"
+            android:background="@drawable/sysbar_toggle_bg_off"
+            />
+    </LinearLayout>
 
+    <!-- main row: meters, clock -->
+    <RelativeLayout
+        android:padding="8dip"
+        android:layout_width="match_parent"
+        android:layout_height="192dip"
+        >
+        <RelativeLayout
+            android:layout_width="256dip"
+            android:layout_height="192dip"
+            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="48dip"
+            >
+            <ImageView android:id="@+id/battery_meter"
+                android:layout_width="256dip"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="true"
+                android:scaleType="centerCrop"
+                android:src="@drawable/sysbar_battery"
+                />
+            <TextView android:id="@+id/battery_info"
+                style="@style/TextAppearance.StatusBar.SystemPanel"
+                android:layout_width="match_parent"
+                android:layout_height="24dip"
+                android:gravity="center"
+                android:layout_above="@id/battery_meter"
+                />
+        </RelativeLayout>
+
+        <com.android.systemui.statusbar.Clock
+            style="@style/TextAppearance.StatusBar.SystemPanel"
+            android:id="@+id/clock"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:textSize="50sp"
+            android:textStyle="normal"
+            android:textColor="#FFFFFFFF"
+            android:layout_centerHorizontal="true"
+            android:layout_alignParentBottom="true"
+            />
+
+        <RelativeLayout
+            android:layout_width="256dip"
+            android:layout_height="192dip"
+            android:layout_alignParentRight="true"
+            android:layout_marginRight="48dip"
+            >
+            <ImageView android:id="@+id/signal_meter"
+                android:layout_width="256dip"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="true"
+                android:scaleType="centerCrop"
+                android:src="@drawable/sysbar_signal"
+                />
+
+            <TextView android:id="@+id/signal_info"
+                style="@style/TextAppearance.StatusBar.SystemPanel"
+                android:layout_width="match_parent"
+                android:layout_height="24dip"
+                android:gravity="center"
+                android:layout_above="@id/signal_meter"
+                />
+        </RelativeLayout>
+
+        <ImageView
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentBottom="true"
+            android:layout_marginBottom="8dip"
+            android:layout_marginLeft="8dip"
+            android:src="@drawable/ic_sysbar_battery_on"
+            />
+        <ImageView
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_alignParentRight="true"
+            android:layout_alignParentBottom="true"
+            android:layout_marginBottom="8dip"
+            android:layout_marginRight="8dip"
+            android:src="@drawable/ic_sysbar_wifi_on"
+            />
+    </RelativeLayout>
+
+    <!-- bottom row: transient indicators, settings button -->
     <View
         android:layout_width="match_parent"
         android:layout_height="1sp"
         android:background="@android:drawable/divider_horizontal_dark"
         />
-
-    <LinearLayout
-        android:padding="8dip"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:gravity="center"
-        >
-        <ImageButton android:id="@+id/brightness"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:src="@drawable/system_panel_brightness_default"
-            android:background="@drawable/button_frame"
-            />
-        <ImageButton android:id="@+id/sound"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="8dip"
-            android:src="@drawable/system_panel_sound_default"
-            android:background="@drawable/button_frame"
-            />
-        <ImageButton android:id="@+id/orientation"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="8dip"
-            android:src="@drawable/system_panel_orientation_default"
-            android:background="@drawable/button_frame"
-            />
-        <ImageButton android:id="@+id/airplane"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="8dip"
-            android:src="@drawable/system_panel_airplane_default"
-            android:background="@drawable/button_frame"
-            />
-    </LinearLayout>
-
     <RelativeLayout
-        android:padding="8dip"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="48dip"
         >
-        <RelativeLayout
-            android:layout_width="120dip"
+        <LinearLayout
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_alignParentLeft="true"
+            android:orientation="horizontal"
             >
-            <ImageView android:id="@+id/battery_meter"
-                android:layout_width="96dip"
+            <!-- TODO: alarm -->
+            <!-- TODO: sync -->
+            <TextView android:id="@+id/date"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_centerHorizontal="true"
-                android:scaleType="centerCrop"
-                android:src="@drawable/battery"
                 />
+        </LinearLayout>
 
-            <TextView android:id="@+id/battery_info"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center"
-                android:layout_below="@id/battery_meter"
-                />
-        </RelativeLayout>
-
-        <com.android.systemui.statusbar.Clock
-            style="@*android:style/TextAppearance.StatusBar.Icon"
-            android:id="@+id/clock"
+        <TextView android:id="@+id/settings_button"
+            style="@style/TextAppearance.StatusBar.TextButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:textSize="20sp"
-            android:textStyle="bold"
-            android:padding="2dip"
-            android:layout_centerHorizontal="true"
-            />
-
-        <TextView android:id="@+id/date"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/clock"
-            />
-
-        <RelativeLayout
-            android:layout_width="120dip"
-            android:layout_height="wrap_content"
             android:layout_alignParentRight="true"
-            >
-            <ImageView android:id="@+id/signal_meter"
-                android:layout_width="96dip"
-                android:layout_height="wrap_content"
-                android:layout_centerHorizontal="true"
-                android:scaleType="centerCrop"
-                android:src="@drawable/signal"
-                />
-
-            <TextView android:id="@+id/signal_info"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center"
-                android:layout_below="@id/signal_meter"
-                />
-        </RelativeLayout>
+            android:layout_centerVertical="true"
+            android:paddingRight="32dip"
+            android:paddingLeft="32dip"
+            android:textSize="20sp"
+            android:text="@string/system_panel_settings_button"
+            />
+        <View
+            android:layout_height="match_parent"
+            android:layout_width="1sp"
+            android:layout_toLeftOf="@id/settings_button"
+            android:background="@*android:drawable/divider_vertical_dark"
+            />
 
     </RelativeLayout>
-
 </com.android.systemui.statusbar.tablet.SystemPanel>
diff --git a/packages/SystemUI/res/values/defaults.xml b/packages/SystemUI/res/values/defaults.xml
index 34302c4..df07a3d 100644
--- a/packages/SystemUI/res/values/defaults.xml
+++ b/packages/SystemUI/res/values/defaults.xml
@@ -17,62 +17,4 @@
  */
 -->
 <resources>
-    <bool name="def_dim_screen">true</bool>
-    <integer name="def_screen_off_timeout">60000</integer>
-    <bool name="def_airplane_mode_on">false</bool>
-    <!-- Comma-separated list of bluetooth, wifi, and cell. -->
-    <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi</string>
-    <string name="airplane_mode_toggleable_radios" translatable="false">wifi</string>
-    <bool name="def_auto_time">true</bool>
-    <bool name="def_accelerometer_rotation">true</bool>
-    <!-- Default screen brightness, from 0 to 255.  102 is 40%. -->
-    <integer name="def_screen_brightness">102</integer>
-    <bool name="def_screen_brightness_automatic_mode">false</bool>
-    <fraction name="def_window_animation_scale">100%</fraction>
-    <fraction name="def_window_transition_scale">100%</fraction>
-    <bool name="def_haptic_feedback">true</bool>
-    
-    <bool name="def_bluetooth_on">false</bool>
-    <bool name="def_install_non_market_apps">false</bool>
-    <!-- Comma-separated list of location providers. 
-         Network location is off by default because it requires
-         user opt-in via Setup Wizard or Settings.  
-    -->
-    <string name="def_location_providers_allowed" translatable="false">gps</string>
-    <bool name="assisted_gps_enabled">true</bool>
-    <!--  0 == mobile, 1 == wifi. -->
-    <integer name="def_network_preference">1</integer>
-    <bool name="def_usb_mass_storage_enabled">true</bool>
-    <bool name="def_wifi_on">false</bool>
-    <bool name="def_networks_available_notification_on">true</bool>
-    
-    <bool name="def_backup_enabled">false</bool>
-    <string name="def_backup_transport" translatable="false"></string>
-    <!-- Default value for whether or not to pulse the notification LED when there is a 
-         pending notification -->
-    <bool name="def_notification_pulse">true</bool>
-
-    <bool name="def_mount_play_notification_snd">true</bool>
-    <bool name="def_mount_ums_autostart">false</bool>
-    <bool name="def_mount_ums_prompt">true</bool>
-    <bool name="def_mount_ums_notify_enabled">true</bool>
-    <!-- Enable User preference for setting install location -->
-    <bool name="set_install_location">true</bool>
-    <!-- Default install location if user preference for setting install location is turned on. -->
-    <integer name="def_install_location">2</integer>
-
-    <!-- user interface sound effects -->
-    <integer name="def_power_sounds_enabled">1</integer>
-    <string name="def_low_battery_sound" translatable="false">/system/media/audio/ui/LowBattery.ogg</string>
-    <integer name="def_dock_sounds_enabled">0</integer>
-    <string name="def_desk_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
-    <string name="def_desk_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
-    <string name="def_car_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
-    <string name="def_car_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
-    <integer name="def_lockscreen_sounds_enabled">0</integer>
-    <string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string>
-    <string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string>
-
-    <!-- Default for Settings.System.VIBRATE_IN_SILENT -->
-    <bool name="def_vibrate_in_silent">true</bool>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 816f34a4..f592703 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -25,4 +25,18 @@
     <style name="TextAppearance.StatusBar.IntruderAlert"
         parent="@android:style/TextAppearance.StatusBar">
     </style>
+
+    <style name="TextAppearance.StatusBar.SystemPanel"
+        parent="@android:style/TextAppearance.StatusBar">
+        <item name="android:textAppearance">?android:attr/textAppearance</item>
+        <item name="android:textStyle">normal</item>
+        <item name="android:textColor">#50FFFFFF</item>
+    </style>
+
+    <style name="TextAppearance.StatusBar.TextButton"
+        parent="@android:style/TextAppearance.StatusBar">
+        <item name="android:textAppearance">?android:attr/textAppearance</item>
+        <item name="android:textStyle">normal</item>
+        <item name="android:textColor">#FFFFFFFF</item>
+    </style>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyButtonView.java
index b0508b8..fe29dea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyButtonView.java
@@ -25,10 +25,12 @@
 import android.os.ServiceManager;
 import android.util.AttributeSet;
 import android.util.Slog;
+import android.view.HapticFeedbackConstants;
 import android.view.IWindowManager;
 import android.view.InputDevice;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.ViewConfiguration;
 import android.widget.ImageView;
 import android.widget.RemoteViews.RemoteView;
 
@@ -37,9 +39,22 @@
 public class KeyButtonView extends ImageView {
     IWindowManager mWindowManager;
     long mDownTime;
-    boolean mSending;
+    boolean mSending, mLongPressed;
     int mCode;
     int mRepeat;
+    Runnable mCheckLongPress = new Runnable() {
+        public void run() {
+            Slog.d("KeyButtonView", "longpress");
+            if (isPressed()) {
+                mLongPressed = true;
+                mRepeat++;
+                sendEvent(KeyEvent.ACTION_DOWN,
+                        KeyEvent.FLAG_FROM_SYSTEM
+                        | KeyEvent.FLAG_VIRTUAL_HARD_KEY
+                        | KeyEvent.FLAG_LONG_PRESS);
+            }
+        }
+    };
 
     public KeyButtonView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -69,12 +84,16 @@
 
         switch (action) {
             case MotionEvent.ACTION_DOWN:
+                Slog.d("KeyButtonView", "press");
                 mDownTime = SystemClock.uptimeMillis();
                 mRepeat = 0;
                 mSending = true;
+                mLongPressed = false;
                 sendEvent(KeyEvent.ACTION_DOWN,
-                        KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_SOFT_KEYBOARD, mDownTime);
+                        KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, mDownTime);
                 setPressed(true);
+                removeCallbacks(mCheckLongPress);
+                postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
                 break;
             case MotionEvent.ACTION_MOVE:
                 if (mSending) {
@@ -83,19 +102,21 @@
                     if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {
                         mSending = false;
                         sendEvent(KeyEvent.ACTION_UP,
-                                KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_SOFT_KEYBOARD
+                                KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY
                                         | KeyEvent.FLAG_CANCELED);
                         setPressed(false);
+                        removeCallbacks(mCheckLongPress);
                     }
                 }
                 break;
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
-                if (mSending) {
+                setPressed(false);
+                if (mSending && !mLongPressed) {
                     mSending = false;
                     sendEvent(KeyEvent.ACTION_UP,
-                            KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_SOFT_KEYBOARD);
-                    setPressed(false);
+                            KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY);
+                    removeCallbacks(mCheckLongPress);
                 }
                 break;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
index dfa2d10..491ef1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
@@ -20,6 +20,7 @@
 import android.app.PendingIntent;
 import android.app.Service;
 import android.app.StatusBarManager;
+import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -28,6 +29,7 @@
 import android.content.res.Resources;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.location.LocationManager;
 import android.media.AudioManager;
 import android.net.NetworkInfo;
 import android.net.wifi.SupplicantState;
@@ -78,13 +80,12 @@
 public class SystemPanel extends LinearLayout {
     private static final String TAG = "SystemPanel";
     private static final boolean DEBUG = TabletStatusBarService.DEBUG;
-    private static final boolean DEBUG_SIGNAL = true;
+    private static final boolean DEBUG_SIGNAL = false;
 
     private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 5;
     private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
     private static final int DEFAULT_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.4f);
 
-
     private TabletStatusBarService mBar;
     private boolean mAirplaneMode;
 
@@ -92,6 +93,8 @@
     private ImageButton mSoundButton;
     private ImageButton mOrientationButton;
     private ImageButton mAirplaneButton;
+    private ImageButton mGpsButton;
+    private ImageButton mBluetoothButton;
 
     private ImageView mBatteryMeter;
     private ImageView mSignalMeter;
@@ -102,6 +105,7 @@
     private final AudioManager mAudioManager;
     private final WifiManager mWifiManager;
     private final TelephonyManager mPhone;
+    private final BluetoothAdapter mBluetoothAdapter;
 
     // state trackers for telephony code
     IccCard.State mSimState = IccCard.State.READY;
@@ -123,7 +127,7 @@
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
             if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
-                mSoundButton.setAlpha(getSilentMode() ? 0x7F : 0xFF);
+                refreshSound();
             } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                 updateBattery(intent);
             } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)
@@ -133,6 +137,8 @@
                 updateWifiState(intent);
             } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
                 updateSimState(intent);
+            } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+                refreshBluetooth();
             }
         }
     };
@@ -295,7 +301,7 @@
             mWifiConnected = detailedState == NetworkInfo.DetailedState.CONNECTED;
         } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
             final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
-            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 6) * 20;
+            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 101);
             mWifiLevel = mWifiConnected ? newSignalLevel : 0;
         }
 
@@ -351,7 +357,7 @@
             level = 0;
         }
 
-        mSignalMeter.setImageResource(mWifiConnected ? R.drawable.wifi : R.drawable.signal);
+        mSignalMeter.setImageResource(R.drawable.sysbar_signal);
         mSignalMeter.setImageLevel(level);
         mSignalText.setText(text);
 
@@ -367,7 +373,7 @@
         final int level = intent.getIntExtra("level", 0);
         final boolean plugged = intent.getIntExtra("plugged", 0) != 0;
 
-        mBatteryMeter.setImageResource(plugged ? R.drawable.battery_charging : R.drawable.battery);
+        mBatteryMeter.setImageResource(R.drawable.sysbar_battery);
         mBatteryMeter.setImageLevel(level);
         mBatteryText.setText(getContext()
                 .getString(R.string.system_panel_battery_meter_format, level));
@@ -401,6 +407,9 @@
 
         // mobile data 
         mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
+
+        // Bluetooth
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
     }
 
     public void onAttachedToWindow() {
@@ -445,6 +454,22 @@
             }
         });
 
+        mGpsButton = (ImageButton)findViewById(R.id.gps);
+        mGpsButton.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                toggleGps();
+                refreshGps();
+            }
+        });
+
+        mBluetoothButton = (ImageButton)findViewById(R.id.bluetooth);
+        mBluetoothButton.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                toggleBluetooth();
+                refreshBluetooth();
+            }
+        });
+
         // register for broadcasts
         IntentFilter filter = new IntentFilter();
         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
@@ -454,19 +479,22 @@
         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
         getContext().registerReceiver(mReceiver, filter);
         
         mBatteryMeter = (ImageView)findViewById(R.id.battery_meter);
-        mBatteryMeter.setImageResource(R.drawable.battery);
+        mBatteryMeter.setImageResource(R.drawable.sysbar_battery);
         mBatteryMeter.setImageLevel(0);
         mSignalMeter = (ImageView)findViewById(R.id.signal_meter);
-        mBatteryMeter.setImageResource(R.drawable.signal);
+        mBatteryMeter.setImageResource(R.drawable.sysbar_signal);
         mBatteryMeter.setImageLevel(0);
 
         mBatteryText = (TextView)findViewById(R.id.battery_info);
         mSignalText = (TextView)findViewById(R.id.signal_info);
 
         refreshSignalMeters();
+        refreshBluetooth();
+        refreshGps();
     }
 
     public void onDetachedFromWindow() {
@@ -492,7 +520,8 @@
 //    }
 
     private void rotateBrightness() {
-        int alpha = 0xFF;
+        int icon = R.drawable.ic_sysbar_brightness;
+        int bg = R.drawable.sysbar_toggle_bg_on;
         Context context = getContext();
         try {
             IPowerManager power = IPowerManager.Stub.asInterface(
@@ -513,18 +542,16 @@
                 // Technically, not a toggle...
                 if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
                     brightness = MINIMUM_BACKLIGHT;
+                    icon = R.drawable.ic_sysbar_brightness_low;
                     brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
-                    alpha = 0x40;
                 } else if (brightness < DEFAULT_BACKLIGHT) {
                     brightness = DEFAULT_BACKLIGHT;
-                    alpha = 0xC0;
                 } else if (brightness < MAXIMUM_BACKLIGHT) {
                     brightness = MAXIMUM_BACKLIGHT;
-                    alpha = 0xFF;
                 } else {
                     brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
                     brightness = MINIMUM_BACKLIGHT;
-                    alpha = 0x60;
+                    icon = R.drawable.ic_sysbar_brightness_auto;
                 }
 
                 if (context.getResources().getBoolean(
@@ -546,7 +573,8 @@
         } catch (Settings.SettingNotFoundException e) {
         }
 
-        mBrightnessButton.setAlpha(alpha);
+        mBrightnessButton.setImageResource(icon);
+        mBrightnessButton.setBackgroundResource(bg);
     }
 
     PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@@ -558,7 +586,12 @@
             mServiceState = serviceState;
             mAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
             if (mAirplaneButton != null) {
-                mAirplaneButton.setAlpha(mAirplaneMode ? 0xFF : 0x7F);
+                mAirplaneButton.setImageResource(mAirplaneMode 
+                                                 ? R.drawable.ic_sysbar_airplane_on
+                                                 : R.drawable.ic_sysbar_airplane_off);
+                mAirplaneButton.setBackgroundResource(mAirplaneMode 
+                                                 ? R.drawable.sysbar_toggle_bg_on
+                                                 : R.drawable.sysbar_toggle_bg_off);
             }
             updateDataState();
         }
@@ -621,4 +654,51 @@
         }
     }
 
+    void refreshSound() {
+        boolean silent = getSilentMode();
+        mSoundButton.setImageResource(!silent 
+                                         ? R.drawable.ic_sysbar_sound_on
+                                         : R.drawable.ic_sysbar_sound_off);
+        mSoundButton.setBackgroundResource(!silent 
+                                         ? R.drawable.sysbar_toggle_bg_on
+                                         : R.drawable.sysbar_toggle_bg_off);
+    }
+
+    void toggleBluetooth() {
+        if (mBluetoothAdapter == null) return;
+        if (mBluetoothAdapter.isEnabled()) {
+            mBluetoothAdapter.disable();
+        } else {
+            mBluetoothAdapter.enable();
+        }
+    }
+
+    void refreshBluetooth() {
+        boolean on = mBluetoothAdapter != null && mBluetoothAdapter.isEnabled();
+        mBluetoothButton.setImageResource(on ? R.drawable.ic_sysbar_bluetooth_on
+                                             : R.drawable.ic_sysbar_bluetooth_off);
+        mBluetoothButton.setBackgroundResource(on
+                                         ? R.drawable.sysbar_toggle_bg_on
+                                         : R.drawable.sysbar_toggle_bg_off);
+    }
+
+    private boolean isGpsEnabled() {
+        ContentResolver res = mContext.getContentResolver();
+        return Settings.Secure.isLocationProviderEnabled(
+                                res, LocationManager.GPS_PROVIDER);
+    }
+
+    private void toggleGps() {
+        Settings.Secure.setLocationProviderEnabled(mContext.getContentResolver(),
+                LocationManager.GPS_PROVIDER, !isGpsEnabled());
+    }
+
+    private void refreshGps() {
+        boolean on = isGpsEnabled();
+        mGpsButton.setImageResource(on ? R.drawable.ic_sysbar_gps_on
+                                       : R.drawable.ic_sysbar_gps_off);
+        mGpsButton.setBackgroundResource(on
+                                         ? R.drawable.sysbar_toggle_bg_on
+                                         : R.drawable.sysbar_toggle_bg_off);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 087671a..5dc46d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -22,6 +22,7 @@
 import android.app.PendingIntent;
 import android.app.Service;
 import android.app.StatusBarManager;
+import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -32,6 +33,8 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.util.Slog;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -57,6 +60,8 @@
     public static final boolean DEBUG = false;
     public static final String TAG = "TabletStatusBar";
 
+    private static final int MAX_IMAGE_LEVEL = 10000;
+
 
 
     int mIconSize;
@@ -77,6 +82,10 @@
 
     ImageView mBatteryMeter;
     ImageView mSignalMeter;
+    ImageView mSignalIcon;
+
+    View mBarContents;
+    View mCurtains;
 
     NotificationIconArea.IconLayout mIconLayout;
 
@@ -89,16 +98,13 @@
     int mDisabled = 0;
 
     protected void addPanelWindows() {
-        mNotificationPanel = View.inflate(this, R.layout.sysbar_panel_notifications, null);
-        mSystemPanel = (SystemPanel) View.inflate(this, R.layout.sysbar_panel_system, null);
-
-        mNotificationPanel.setVisibility(View.GONE);
-        mSystemPanel.setVisibility(View.GONE);
-
         final Resources res = getResources();
         final int barHeight= res.getDimensionPixelSize(
             com.android.internal.R.dimen.status_bar_height);
 
+        mNotificationPanel = View.inflate(this, R.layout.sysbar_panel_notifications, null);
+        mNotificationPanel.setVisibility(View.GONE);
+
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 400, // ViewGroup.LayoutParams.WRAP_CONTENT,
                 ViewGroup.LayoutParams.WRAP_CONTENT,
@@ -115,8 +121,11 @@
 
         WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
 
+        mSystemPanel = (SystemPanel) View.inflate(this, R.layout.sysbar_panel_system, null);
+        mSystemPanel.setVisibility(View.GONE);
+
         lp = new WindowManager.LayoutParams(
-                500, // ViewGroup.LayoutParams.WRAP_CONTENT,
+                800,
                 ViewGroup.LayoutParams.WRAP_CONTENT,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
@@ -146,6 +155,19 @@
         final View sb = View.inflate(this, R.layout.status_bar, null);
         mStatusBarView = sb;
 
+        mBarContents = sb.findViewById(R.id.bar_contents);
+        mCurtains = sb.findViewById(R.id.lights_out);
+        View systemInfo = sb.findViewById(R.id.systemInfo);
+        View.OnLongClickListener toggle = new View.OnLongClickListener() {
+            public boolean onLongClick(View v) {
+                toggleLightsOut(v);
+                return true;
+            }
+        };
+        
+        systemInfo.setOnLongClickListener(toggle);
+        mCurtains.setOnLongClickListener(toggle);
+
         // the more notifications icon
         mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons);
 
@@ -157,6 +179,7 @@
         // System info (center)
         mBatteryMeter = (ImageView) sb.findViewById(R.id.battery);
         mSignalMeter = (ImageView) sb.findViewById(R.id.signal);
+        mSignalIcon = (ImageView) sb.findViewById(R.id.signal_icon);
 
         // Add the windows
         addPanelWindows();
@@ -208,18 +231,23 @@
     
     public void setBatteryMeter(int level, boolean plugged) {
         if (DEBUG) Slog.d(TAG, "battery=" + level + (plugged ? " - plugged" : " - unplugged"));
-        mBatteryMeter.setImageResource(plugged ? R.drawable.battery_charging : R.drawable.battery);
-        mBatteryMeter.setImageLevel(level);
+        mBatteryMeter.setImageResource(R.drawable.sysbar_batterymini);
+        // adjust percent to permyriad for ClipDrawable's sake
+        mBatteryMeter.setImageLevel(level * (MAX_IMAGE_LEVEL / 100));
     }
 
     public void setSignalMeter(int level, boolean isWifi) {
         if (DEBUG) Slog.d(TAG, "signal=" + level);
         if (level < 0) {
-            mSignalMeter.setImageResource(isWifi ? R.drawable.wifi_scan : R.drawable.signal_scan);
+            mSignalMeter.setImageDrawable(null);
             mSignalMeter.setImageLevel(0);
+            mSignalIcon.setImageDrawable(null);
         } else {
-            mSignalMeter.setImageResource(isWifi ? R.drawable.wifi : R.drawable.signal);
-            mSignalMeter.setImageLevel(level);
+            mSignalMeter.setImageResource(R.drawable.sysbar_wifimini);
+            // adjust to permyriad
+            mSignalMeter.setImageLevel(level * (MAX_IMAGE_LEVEL / 100));
+            mSignalIcon.setImageResource(isWifi ? R.drawable.ic_sysbar_wifi_mini 
+                                                : R.drawable.ic_sysbar_wifi_mini); // XXX
         }
     }
 
@@ -495,6 +523,15 @@
         mHandler.sendEmptyMessage(msg);
     }
 
+    public void recentButtonClicked(View v) {
+        if (DEBUG) Slog.d(TAG, "clicked recent apps");
+        Intent intent = new Intent();
+        intent.setClass(this, RecentApplicationsActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        startActivity(intent);
+    }
+
     /**
      * Cancel this notification and tell the status bar service about the failure. Hold no locks.
      */
@@ -700,4 +737,28 @@
 
         return true;
     }
+
+    protected void setLightsOut(boolean out) {
+        if (out) {
+            mCurtains.setAnimation(AnimationUtils.loadAnimation((Context)this,
+                        R.anim.lights_out_in));
+            mCurtains.setVisibility(View.VISIBLE);
+            mBarContents.setAnimation(AnimationUtils.loadAnimation((Context)this,
+                        R.anim.status_bar_out));
+            mBarContents.setVisibility(View.GONE);
+        } else {
+            mCurtains.setAnimation(AnimationUtils.loadAnimation((Context)this,
+                        R.anim.lights_out_out));
+            mCurtains.setVisibility(View.GONE);
+            mBarContents.setAnimation(AnimationUtils.loadAnimation((Context)this,
+                        R.anim.status_bar_in));
+            mBarContents.setVisibility(View.VISIBLE);
+        }
+    }
+
+    public void toggleLightsOut(View v) {
+        setLightsOut(mCurtains.getVisibility() != View.VISIBLE);
+    }
 }
+
+
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 88203c3..d19f318 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.policy.impl;
 
+import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+
 import com.android.internal.telephony.IccCard;
 import com.android.internal.widget.LockPatternUtils;
 
@@ -41,6 +43,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
 import android.telephony.TelephonyManager;
 import android.util.Config;
 import android.util.EventLog;
@@ -93,6 +96,7 @@
  */
 public class KeyguardViewMediator implements KeyguardViewCallback,
         KeyguardUpdateMonitor.SimStateCallback {
+    private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
     private final static boolean DEBUG = false && Config.LOGD;
     private final static boolean DBG_WAKE = DEBUG || true;
 
@@ -133,7 +137,7 @@
      * turning on the keyguard (i.e, the user has this much time to turn
      * the screen back on without having to face the keyguard).
      */
-    private static final int KEYGUARD_DELAY_MS = 5000;
+    private static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000;
 
     /**
      * How long we'll wait for the {@link KeyguardViewCallback#keyguardDoneDrawing()}
@@ -244,6 +248,7 @@
      * the keyguard.
      */
     private boolean mWaitingUntilKeyguardVisible = false;
+    private LockPatternUtils mLockPatternUtils;
 
     public KeyguardViewMediator(Context context, PhoneWindowManager callback,
             LocalPowerManager powerManager) {
@@ -275,8 +280,9 @@
 
         mUpdateMonitor.registerSimStateCallback(this);
 
-        mKeyguardViewProperties = new LockPatternKeyguardViewProperties(
-                new LockPatternUtils(mContext), mUpdateMonitor);
+        mLockPatternUtils = new LockPatternUtils(mContext);
+        mKeyguardViewProperties 
+                = new LockPatternKeyguardViewProperties(mLockPatternUtils, mUpdateMonitor);
 
         mKeyguardViewManager = new KeyguardViewManager(
                 context, WindowManagerImpl.getDefault(), this,
@@ -326,15 +332,46 @@
                 // to enable it a little bit later (i.e, give the user a chance
                 // to turn the screen back on within a certain window without
                 // having to unlock the screen)
-                long when = SystemClock.elapsedRealtime() + KEYGUARD_DELAY_MS;
-                Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);
-                intent.putExtra("seq", mDelayedShowingSequence);
-                PendingIntent sender = PendingIntent.getBroadcast(mContext,
-                        0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
-                mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
-                        sender);
-                if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
-                                 + mDelayedShowingSequence);
+                final ContentResolver cr = mContext.getContentResolver();
+
+                // From DisplaySettings
+                long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT,
+                        KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT);
+
+                // From SecuritySettings
+                final long lockAfterTimeout = Settings.Secure.getInt(cr,
+                        Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
+                        KEYGUARD_LOCK_AFTER_DELAY_DEFAULT);
+
+                // From DevicePolicyAdmin
+                final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
+                        .getMaximumTimeToLock(null);
+
+                long timeout;
+                if (policyTimeout > 0) {
+                    // policy in effect. Make sure we don't go beyond policy limit.
+                    displayTimeout = Math.max(displayTimeout, 0); // ignore negative values
+                    timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout);
+                } else {
+                    timeout = lockAfterTimeout;
+                }
+
+                if (timeout <= 0) {
+                    // Lock now
+                    mSuppressNextLockSound = true;
+                    doKeyguard();
+                } else {
+                    // Lock in the future
+                    long when = SystemClock.elapsedRealtime() + timeout;
+                    Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);
+                    intent.putExtra("seq", mDelayedShowingSequence);
+                    PendingIntent sender = PendingIntent.getBroadcast(mContext,
+                            0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+                    mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
+                            sender);
+                    if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
+                                     + mDelayedShowingSequence);
+                }
             } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
                 // Do not enable the keyguard if the prox sensor forced the screen off.
             } else {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ff31470..3770b55 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1781,6 +1781,14 @@
                 if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
                     // Do not ramp volume is volume is controlled by effect
                     param = AudioMixer::VOLUME;
+                    track->mHasVolumeController = true;
+                } else {
+                    // force no volume ramp when volume controller was just disabled or removed
+                    // from effect chain to avoid volume spike
+                    if (track->mHasVolumeController) {
+                        param = AudioMixer::VOLUME;
+                    }
+                    track->mHasVolumeController = false;
                 }
 
                 // Convert volumes from 8.24 to 4.12 format
@@ -2901,7 +2909,8 @@
             const sp<IMemory>& sharedBuffer,
             int sessionId)
     :   TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer, sessionId),
-    mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL), mAuxEffectId(0)
+    mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL),
+    mAuxEffectId(0), mHasVolumeController(false)
 {
     if (mCblk != NULL) {
         sp<ThreadBase> baseThread = thread.promote();
@@ -5371,7 +5380,7 @@
         return;
     }
 
-    if (mState == ACTIVE || mState == STOPPING || mState == STOPPED || mState == RESTART) {
+    if (isProcessEnabled()) {
         // do 32 bit to 16 bit conversion for auxiliary effect input buffer
         if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
             AudioMixer::ditherAndClamp(mConfig.inputCfg.buffer.s32,
@@ -5600,6 +5609,8 @@
 
         // going from enabled to disabled
         case RESTART:
+            mState = STOPPED;
+            break;
         case STARTING:
             mState = IDLE;
             break;
@@ -5632,6 +5643,21 @@
     }
 }
 
+bool AudioFlinger::EffectModule::isProcessEnabled()
+{
+    switch (mState) {
+    case RESTART:
+    case ACTIVE:
+    case STOPPING:
+    case STOPPED:
+        return true;
+    case IDLE:
+    case STARTING:
+    default:
+        return false;
+    }
+}
+
 status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
 {
     Mutex::Autolock _l(mLock);
@@ -5639,7 +5665,7 @@
 
     // Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume
     // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set)
-    if ((mState >= ACTIVE) &&
+    if (isProcessEnabled() &&
             ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
             (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND)) {
         status_t cmdStatus;
@@ -5966,12 +5992,14 @@
                                             p,
                                             &rsize,
                                             &reply);
-            if (ret == NO_ERROR) {
-                if (reply != NO_ERROR) {
-                    status = reply;
-                }
-            } else {
+            // stop at first error encountered
+            if (ret != NO_ERROR) {
                 status = ret;
+                *(int *)pReplyData = reply;
+                break;
+            } else if (reply != NO_ERROR) {
+                *(int *)pReplyData = reply;
+                break;
             }
             mCblk->serverIndex += size;
         }
@@ -5979,8 +6007,10 @@
         mCblk->clientIndex = 0;
         return status;
     } else if (cmdCode == EFFECT_CMD_ENABLE) {
+        *(int *)pReplyData = NO_ERROR;
         return enable();
     } else if (cmdCode == EFFECT_CMD_DISABLE) {
+        *(int *)pReplyData = NO_ERROR;
         return disable();
     }
 
@@ -6288,7 +6318,7 @@
 
     // first update volume controller
     for (size_t i = size; i > 0; i--) {
-        if ((mEffects[i - 1]->state() >= EffectModule::ACTIVE) &&
+        if (mEffects[i - 1]->isProcessEnabled() &&
             (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) {
             ctrlIdx = i - 1;
             hasControl = true;
@@ -6304,9 +6334,6 @@
         return hasControl;
     }
 
-    if (mVolumeCtrlIdx != -1) {
-        hasControl = true;
-    }
     mVolumeCtrlIdx = ctrlIdx;
     mLeftVolume = newLeft;
     mRightVolume = newRight;
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 51881f0..5917632 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -514,6 +514,7 @@
             int16_t             *mMainBuffer;
             int32_t             *mAuxBuffer;
             int                 mAuxEffectId;
+            bool                mHasVolumeController;
         };  // end of Track
 
 
@@ -965,6 +966,7 @@
         }
         status_t    setEnabled(bool enabled);
         bool isEnabled();
+        bool isProcessEnabled();
 
         void        setInBuffer(int16_t *buffer) { mConfig.inputCfg.buffer.s16 = buffer; }
         int16_t     *inBuffer() { return mConfig.inputCfg.buffer.s16; }
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index 4614c8d..65d9ef7 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -133,7 +133,7 @@
         // request routing change if necessary
         uint32_t newDevice = getNewDevice(mHardwareOutput, false);
 #ifdef WITH_A2DP
-        checkOutputForAllStrategies(newDevice);
+        checkOutputForAllStrategies();
         // A2DP outputs must be closed after checkOutputForAllStrategies() is executed
         if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) {
             closeA2dpOutputs();
@@ -274,7 +274,7 @@
     // check for device and output changes triggered by new phone state
     newDevice = getNewDevice(mHardwareOutput, false);
 #ifdef WITH_A2DP
-    checkOutputForAllStrategies(newDevice);
+    checkOutputForAllStrategies();
     // suspend A2DP output if a SCO device is present.
     if (mA2dpOutput != 0 && mScoDeviceAddress != "") {
         if (oldState == AudioSystem::MODE_NORMAL) {
@@ -386,13 +386,28 @@
     // check for device and output changes triggered by new phone state
     uint32_t newDevice = getNewDevice(mHardwareOutput, false);
 #ifdef WITH_A2DP
-    checkOutputForAllStrategies(newDevice);
+    checkOutputForAllStrategies();
 #endif
     updateDeviceForStrategy();
     setOutputDevice(mHardwareOutput, newDevice);
     if (forceVolumeReeval) {
         applyStreamVolumes(mHardwareOutput, newDevice);
     }
+
+    audio_io_handle_t activeInput = getActiveInput();
+    if (activeInput != 0) {
+        AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
+        newDevice = getDeviceForInputSource(inputDesc->mInputSource);
+        if (newDevice != inputDesc->mDevice) {
+            LOGV("setForceUse() changing device from %x to %x for input %d",
+                    inputDesc->mDevice, newDevice, activeInput);
+            inputDesc->mDevice = newDevice;
+            AudioParameter param = AudioParameter();
+            param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
+            mpClientInterface->setParameters(activeInput, param.toString());
+        }
+    }
+
 }
 
 AudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage)
@@ -1382,7 +1397,7 @@
     }
 }
 
-void AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy, uint32_t &newDevice)
+void AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy)
 {
     uint32_t prevDevice = getDeviceForStrategy(strategy);
     uint32_t curDevice = getDeviceForStrategy(strategy, false);
@@ -1401,12 +1416,6 @@
             LOGV("checkOutputForStrategy() moving strategy %d from a2dp", strategy);
             srcOutput = mA2dpOutput;
         }
-
-        // do not change newDevice if it was already set before this call by a previous call to
-        // getNewDevice() or checkOutputForStrategy() for a strategy with higher priority
-        if (newDevice == 0 && mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(strategy)) {
-            newDevice = getDeviceForStrategy(strategy, false);
-        }
     }
     if (a2dpIsUsed && !a2dpWasUsed) {
         bool dupUsed = a2dpUsedForSonification() && a2dpIsUsed && (AudioSystem::popCount(curDevice) == 2);
@@ -1441,15 +1450,12 @@
     }
 }
 
-void AudioPolicyManagerBase::checkOutputForAllStrategies(uint32_t &newDevice)
+void AudioPolicyManagerBase::checkOutputForAllStrategies()
 {
-    // Check strategies in order of priority so that once newDevice is set
-    // for a given strategy it is not modified by subsequent calls to
-    // checkOutputForStrategy()
-    checkOutputForStrategy(STRATEGY_PHONE, newDevice);
-    checkOutputForStrategy(STRATEGY_SONIFICATION, newDevice);
-    checkOutputForStrategy(STRATEGY_MEDIA, newDevice);
-    checkOutputForStrategy(STRATEGY_DTMF, newDevice);
+    checkOutputForStrategy(STRATEGY_PHONE);
+    checkOutputForStrategy(STRATEGY_SONIFICATION);
+    checkOutputForStrategy(STRATEGY_MEDIA);
+    checkOutputForStrategy(STRATEGY_DTMF);
 }
 
 #endif
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c6a9909..d1fbf17 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -336,11 +336,6 @@
     int callingPid = getCallingPid();
     LOG1("Client::~Client E (pid %d, this %p)", callingPid, this);
 
-    // Clean up the ANativeWindow
-    if (mSurface != 0) {
-        setPreviewDisplay(0);
-    }
-
     // set mClientPid to let disconnet() tear down the hardware
     mClientPid = callingPid;
     disconnect();
diff --git a/services/java/com/android/server/BootReceiver.java b/services/java/com/android/server/BootReceiver.java
index d15a058..b9ff8d0 100644
--- a/services/java/com/android/server/BootReceiver.java
+++ b/services/java/com/android/server/BootReceiver.java
@@ -167,7 +167,7 @@
             if (lastTime == fileTime) return;  // Already logged this particular file
             // TODO: move all these SharedPreferences Editor commits
             // outside this function to the end of logBootEvents
-            prefs.edit().putLong(filename, fileTime).startCommit();
+            prefs.edit().putLong(filename, fileTime).apply();
         }
 
         Slog.i(TAG, "Copying " + filename + " to DropBox (" + tag + ")");
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 57e8e02..b6d725f 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -26,13 +26,14 @@
 import android.net.IConnectivityManager;
 import android.net.MobileDataStateTracker;
 import android.net.NetworkInfo;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.net.NetworkStateTracker;
 import android.net.NetworkUtils;
 import android.net.wifi.WifiStateTracker;
 import android.net.NetworkUtils;
 import android.os.Binder;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
@@ -121,6 +122,8 @@
     private int mNetTransitionWakeLockSerialNumber;
     private int mNetTransitionWakeLockTimeout;
 
+    private InetAddress mDefaultDns;
+
     private static class NetworkAttributes {
         /**
          * Class for holding settings read from resources.
@@ -156,52 +159,20 @@
     }
     RadioAttributes[] mRadioAttributes;
 
-    private static class ConnectivityThread extends Thread {
-        private Context mContext;
-
-        private ConnectivityThread(Context context) {
-            super("ConnectivityThread");
-            mContext = context;
+    public static synchronized ConnectivityService getInstance(Context context) {
+        if (sServiceInstance == null) {
+            sServiceInstance = new ConnectivityService(context);
         }
-
-        @Override
-        public void run() {
-            Looper.prepare();
-            synchronized (this) {
-                sServiceInstance = new ConnectivityService(mContext);
-                notifyAll();
-            }
-            Looper.loop();
-        }
-
-        public static ConnectivityService getServiceInstance(Context context) {
-            ConnectivityThread thread = new ConnectivityThread(context);
-            thread.start();
-
-            synchronized (thread) {
-                while (sServiceInstance == null) {
-                    try {
-                        // Wait until sServiceInstance has been initialized.
-                        thread.wait();
-                    } catch (InterruptedException ignore) {
-                        Slog.e(TAG,
-                            "Unexpected InterruptedException while waiting"+
-                            " for ConnectivityService thread");
-                    }
-                }
-            }
-
-            return sServiceInstance;
-        }
-    }
-
-    public static ConnectivityService getInstance(Context context) {
-        return ConnectivityThread.getServiceInstance(context);
+        return sServiceInstance;
     }
 
     private ConnectivityService(Context context) {
         if (DBG) Slog.v(TAG, "ConnectivityService starting up");
 
+        HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
+        handlerThread.start();
+        mHandler = new MyHandler(handlerThread.getLooper());
+
         // setup our unique device name
         String id = Settings.Secure.getString(context.getContentResolver(),
                 Settings.Secure.ANDROID_ID);
@@ -210,6 +181,19 @@
             SystemProperties.set("net.hostname", name);
         }
 
+        // read our default dns server ip
+        String dns = Settings.Secure.getString(context.getContentResolver(),
+                Settings.Secure.DEFAULT_DNS_SERVER);
+        if (dns == null || dns.length() == 0) {
+            dns = context.getResources().getString(
+                    com.android.internal.R.string.config_default_dns_server);
+        }
+        try {
+            mDefaultDns = InetAddress.getByName(dns);
+        } catch (UnknownHostException e) {
+            Slog.e(TAG, "Error setting defaultDns using " + dns);
+        }
+
         mContext = context;
 
         PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
@@ -219,7 +203,6 @@
 
         mNetTrackers = new NetworkStateTracker[
                 ConnectivityManager.MAX_NETWORK_TYPE+1];
-        mHandler = new MyHandler();
 
         mNetworkPreference = getPersistedNetworkPreference();
 
@@ -756,7 +739,6 @@
      * specified host is to be routed
      * @param hostAddress the IP address of the host to which the route is
      * desired
-     * todo - deprecate (only v4!)
      * @return {@code true} on success, {@code false} on failure
      */
     public boolean requestRouteToHost(int networkType, int hostAddress) {
@@ -813,7 +795,7 @@
             return false;
         }
 
-        NetworkProperties p = nt.getNetworkProperties();
+        LinkProperties p = nt.getLinkProperties();
         if (p == null) return false;
         String interfaceName = p.getInterfaceName();
 
@@ -1258,7 +1240,7 @@
 
     private void addPrivateDnsRoutes(NetworkStateTracker nt) {
         boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet();
-        NetworkProperties p = nt.getNetworkProperties();
+        LinkProperties p = nt.getLinkProperties();
         if (p == null) return;
         String interfaceName = p.getInterfaceName();
 
@@ -1279,7 +1261,7 @@
     private void removePrivateDnsRoutes(NetworkStateTracker nt) {
         // TODO - we should do this explicitly but the NetUtils api doesnt
         // support this yet - must remove all.  No worse than before
-        NetworkProperties p = nt.getNetworkProperties();
+        LinkProperties p = nt.getLinkProperties();
         if (p == null) return;
         String interfaceName = p.getInterfaceName();
         boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet();
@@ -1295,7 +1277,7 @@
 
 
     private void addDefaultRoute(NetworkStateTracker nt) {
-        NetworkProperties p = nt.getNetworkProperties();
+        LinkProperties p = nt.getLinkProperties();
         if (p == null) return;
         String interfaceName = p.getInterfaceName();
         InetAddress defaultGatewayAddr = p.getGateway();
@@ -1311,7 +1293,7 @@
 
 
     public void removeDefaultRoute(NetworkStateTracker nt) {
-        NetworkProperties p = nt.getNetworkProperties();
+        LinkProperties p = nt.getLinkProperties();
         if (p == null) return;
         String interfaceName = p.getInterfaceName();
 
@@ -1410,7 +1392,7 @@
             NetworkStateTracker nt = mNetTrackers[i];
             if (nt.getNetworkInfo().isConnected() &&
                     !nt.isTeardownRequested()) {
-                NetworkProperties p = nt.getNetworkProperties();
+                LinkProperties p = nt.getLinkProperties();
                 if (p == null) continue;
                 List pids = mNetRequestersPids[i];
                 for (int j=0; j<pids.size(); j++) {
@@ -1465,17 +1447,25 @@
         // add default net's dns entries
         NetworkStateTracker nt = mNetTrackers[netType];
         if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
-            NetworkProperties p = nt.getNetworkProperties();
+            LinkProperties p = nt.getLinkProperties();
             if (p == null) return;
             Collection<InetAddress> dnses = p.getDnses();
             if (mNetAttributes[netType].isDefault()) {
                 int j = 1;
-                for (InetAddress dns : dnses) {
+                if (dnses.size() == 0 && mDefaultDns != null) {
                     if (DBG) {
-                        Slog.d(TAG, "adding dns " + dns + " for " +
-                                nt.getNetworkInfo().getTypeName());
+                        Slog.d(TAG, "no dns provided - using " + mDefaultDns.getHostAddress());
                     }
-                    SystemProperties.set("net.dns" + j++, dns.getHostAddress());
+                    SystemProperties.set("net.dns1", mDefaultDns.getHostAddress());
+                    j++;
+                } else {
+                    for (InetAddress dns : dnses) {
+                        if (DBG) {
+                            Slog.d(TAG, "adding dns " + dns + " for " +
+                                    nt.getNetworkInfo().getTypeName());
+                        }
+                        SystemProperties.set("net.dns" + j++, dns.getHostAddress());
+                    }
                 }
                 for (int k=j ; k<mNumDnsEntries; k++) {
                     if (DBG) Slog.d(TAG, "erasing net.dns" + k);
@@ -1558,6 +1548,10 @@
 
     // must be stateless - things change under us.
     private class MyHandler extends Handler {
+        public MyHandler(Looper looper) {
+            super(looper);
+        }
+
         @Override
         public void handleMessage(Message msg) {
             NetworkInfo info;
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index f330d40..314dd8a 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -30,6 +30,7 @@
 import android.util.Slog;
 import android.util.Xml;
 import android.view.InputChannel;
+import android.view.InputDevice;
 import android.view.InputEvent;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -45,6 +46,7 @@
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Properties;
 
 /*
  * Wraps the C++ InputManager and provides its callbacks.
@@ -82,6 +84,8 @@
     private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen);
     private static native void nativeSetFocusedApplication(InputApplication application);
     private static native void nativePreemptInputDispatch();
+    private static native InputDevice nativeGetInputDevice(int deviceId);
+    private static native int[] nativeGetInputDeviceIds();
     private static native String nativeDump();
     
     // Input event injection constants defined in InputDispatcher.h.
@@ -302,6 +306,23 @@
         return nativeInjectInputEvent(event, injectorPid, injectorUid, syncMode, timeoutMillis);
     }
     
+    /**
+     * Gets information about the input device with the specified id.
+     * @param id The device id.
+     * @return The input device or null if not found.
+     */
+    public InputDevice getInputDevice(int deviceId) {
+        return nativeGetInputDevice(deviceId);
+    }
+    
+    /**
+     * Gets the ids of all input devices in the system.
+     * @return The input device ids.
+     */
+    public int[] getInputDeviceIds() {
+        return nativeGetInputDeviceIds();
+    }
+    
     public void setInputWindows(InputWindow[] windows) {
         nativeSetInputWindows(windows);
     }
@@ -335,6 +356,11 @@
         public int height;
     }
     
+    private static final class InputDeviceCalibration {
+        public String[] keys;
+        public String[] values;
+    }
+    
     /*
      * Callbacks from native.
      */
@@ -343,6 +369,7 @@
         
         private static final boolean DEBUG_VIRTUAL_KEYS = false;
         private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
+        private static final String CALIBRATION_DIR_PATH = "usr/idc/";
         
         @SuppressWarnings("unused")
         public void virtualKeyDownFeedback() {
@@ -438,8 +465,8 @@
                     final int N = it.length-6;
                     for (int i=0; i<=N; i+=6) {
                         if (!"0x01".equals(it[i])) {
-                            Slog.w(TAG, "Unknown virtual key type at elem #" + i
-                                    + ": " + it[i]);
+                            Slog.w(TAG, "Unknown virtual key type at elem #"
+                                    + i + ": " + it[i] + " for device " + deviceName);
                             continue;
                         }
                         try {
@@ -455,22 +482,47 @@
                                     + key.height);
                             keys.add(key);
                         } catch (NumberFormatException e) {
-                            Slog.w(TAG, "Bad number at region " + i + " in: "
-                                    + str, e);
+                            Slog.w(TAG, "Bad number in virtual key definition at region "
+                                    + i + " in: " + str + " for device " + deviceName, e);
                         }
                     }
                 }
                 br.close();
             } catch (FileNotFoundException e) {
-                Slog.i(TAG, "No virtual keys found");
+                Slog.i(TAG, "No virtual keys found for device " + deviceName + ".");
             } catch (IOException e) {
-                Slog.w(TAG, "Error reading virtual keys", e);
+                Slog.w(TAG, "Error reading virtual keys for device " + deviceName + ".", e);
             }
             
             return keys.toArray(new VirtualKeyDefinition[keys.size()]);
         }
         
         @SuppressWarnings("unused")
+        public InputDeviceCalibration getInputDeviceCalibration(String deviceName) {
+            // Calibration is specified as a sequence of colon-delimited key value pairs.
+            Properties properties = new Properties();
+            File calibrationFile = new File(Environment.getRootDirectory(),
+                    CALIBRATION_DIR_PATH + deviceName + ".idc");
+            if (calibrationFile.exists()) {
+                try {
+                    properties.load(new FileInputStream(calibrationFile));
+                } catch (IOException ex) {
+                    Slog.w(TAG, "Error reading input device calibration properties for device "
+                            + deviceName + " from " + calibrationFile + ".", ex);
+                }
+            } else {
+                Slog.i(TAG, "No input device calibration properties found for device "
+                        + deviceName + ".");
+                return null;
+            }
+            
+            InputDeviceCalibration calibration = new InputDeviceCalibration();
+            calibration.keys = properties.keySet().toArray(new String[properties.size()]);
+            calibration.values = properties.values().toArray(new String[properties.size()]);
+            return calibration;
+        }
+        
+        @SuppressWarnings("unused")
         public String[] getExcludedDeviceNames() {
             ArrayList<String> names = new ArrayList<String>();
             
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index d604886..c07007a 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -68,6 +68,8 @@
 
     private static final String TAG = "MountService";
 
+    private static final String VOLD_TAG = "VoldConnector";
+
     /*
      * Internal vold volume state constants
      */
@@ -1006,9 +1008,15 @@
             return;
         }
 
-        mConnector = new NativeDaemonConnector(this, "vold", 10, "VoldConnector");
+        /*
+         * Create the connection to vold with a maximum queue of twice the
+         * amount of containers we'd ever expect to have. This keeps an
+         * "asec list" from blocking a thread repeatedly.
+         */
+        mConnector = new NativeDaemonConnector(this, "vold",
+                PackageManagerService.MAX_CONTAINERS * 2, VOLD_TAG);
         mReady = false;
-        Thread thread = new Thread(mConnector, NativeDaemonConnector.class.getName());
+        Thread thread = new Thread(mConnector, VOLD_TAG);
         thread.start();
     }
 
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index 249c32b..03f8dae 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -109,6 +109,10 @@
                 int count = inputStream.read(buffer, start, BUFFER_SIZE - start);
                 if (count < 0) break;
 
+                // Add our starting point to the count and reset the start.
+                count += start;
+                start = 0;
+
                 for (int i = 0; i < count; i++) {
                     if (buffer[i] == 0) {
                         String event = new String(buffer, start, i - start);
@@ -141,6 +145,9 @@
                         start = i + 1;
                     }
                 }
+
+                // We should end at the amount we read. If not, compact then
+                // buffer and read again.
                 if (start != count) {
                     final int remaining = BUFFER_SIZE - start;
                     System.arraycopy(buffer, start, buffer, 0, remaining);
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index cb8fa35..de459ab 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -55,6 +55,8 @@
 
     private static final String TAG = "NetworkManagmentService";
 
+    private static final String NETD_TAG = "NetdConnector";
+
     class NetdResponseCode {
         public static final int InterfaceListResult       = 110;
         public static final int TetherInterfaceListResult = 111;
@@ -101,8 +103,8 @@
         }
 
         mConnector = new NativeDaemonConnector(
-                new NetdCallbackReceiver(), "netd", 10, "NetdConnector");
-        Thread thread = new Thread(mConnector, NativeDaemonConnector.class.getName());
+                new NetdCallbackReceiver(), "netd", 10, NETD_TAG);
+        Thread thread = new Thread(mConnector, NETD_TAG);
         thread.start();
     }
 
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 171de9c..5ae87cf 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -1615,6 +1615,18 @@
         return null;
     }
 
+    public ProviderInfo getProviderInfo(ComponentName component, int flags) {
+        synchronized (mPackages) {
+            PackageParser.Provider p = mProvidersByComponent.get(component);
+            if (Config.LOGV) Log.v(
+                TAG, "getProviderInfo " + component + ": " + p);
+            if (p != null && mSettings.isEnabledLP(p.info, flags)) {
+                return PackageParser.generateProviderInfo(p, flags);
+            }
+        }
+        return null;
+    }
+
     public String[] getSystemSharedLibraryNames() {
         Set<String> libSet;
         synchronized (mPackages) {
@@ -2010,7 +2022,11 @@
                     ActivityInfo ai = getActivityInfo(pa.mActivity, flags);
                     if (DEBUG_PREFERRED) {
                         Log.v(TAG, "Got preferred activity:");
-                        ai.dump(new LogPrinter(Log.INFO, TAG), "  ");
+                        if (ai != null) {
+                            ai.dump(new LogPrinter(Log.VERBOSE, TAG), "  ");
+                        } else {
+                            Log.v(TAG, "  null");
+                        }
                     }
                     if (ai != null) {
                         for (int j=0; j<N; j++) {
@@ -2591,7 +2607,7 @@
         }
         // First check if this is a system package that may involve an update
         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
-            if (!ps.codePath.equals(scanFile)) {
+            if (ps != null && !ps.codePath.equals(scanFile)) {
                 // The path has changed from what was last scanned...  check the
                 // version of the new path against what we have stored to determine
                 // what to do.
@@ -6169,18 +6185,15 @@
         }
         // Delete the updated package
         outInfo.isRemovedPackageSystemUpdate = true;
-        boolean deleteCodeAndResources = false;
-        if (ps.versionCode <  p.mVersionCode) {
+        final boolean deleteCodeAndResources;
+        if (ps.versionCode < p.mVersionCode) {
             // Delete code and resources for downgrades
             deleteCodeAndResources = true;
-            if ((flags & PackageManager.DONT_DELETE_DATA) == 0) {
-                flags &= ~PackageManager.DONT_DELETE_DATA;
-            }
+            flags &= ~PackageManager.DONT_DELETE_DATA;
         } else {
             // Preserve data by setting flag
-            if ((flags & PackageManager.DONT_DELETE_DATA) == 0) {
-                flags |= PackageManager.DONT_DELETE_DATA;
-            }
+            deleteCodeAndResources = false;
+            flags |= PackageManager.DONT_DELETE_DATA;
         }
         boolean ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo);
         if (!ret) {
@@ -9374,17 +9387,18 @@
 
     // ------- apps on sdcard specific code -------
     static final boolean DEBUG_SD_INSTALL = false;
-    final private String mSdEncryptKey = "AppsOnSD";
-    final private String mSdEncryptAlg = "AES";
+    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
+    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
+    static final int MAX_CONTAINERS = 250;
     private boolean mMediaMounted = false;
-    private static final int MAX_CONTAINERS = 250;
 
     private String getEncryptKey() {
         try {
-            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(mSdEncryptKey);
+            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
+                    SD_ENCRYPTION_KEYSTORE_NAME);
             if (sdEncKey == null) {
-                sdEncKey = SystemKeyStore.getInstance().
-                        generateNewKeyHexString(128, mSdEncryptAlg, mSdEncryptKey);
+                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
+                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
                 if (sdEncKey == null) {
                     Slog.e(TAG, "Failed to create encryption keys");
                     return null;
@@ -9834,6 +9848,7 @@
                                        ps.codePathString = ps.codePath.getPath();
                                        ps.resourcePath = new File(pkg.applicationInfo.publicSourceDir);
                                        ps.resourcePathString = ps.resourcePath.getPath();
+                                       ps.nativeLibraryPathString = newNativePath;
                                        // Set the application info flag correctly.
                                        if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
                                            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 16f3f10..2e32e60 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -2456,7 +2456,8 @@
             }
             mKeylightDelay = LONG_KEYLIGHT_DELAY;
             if (totalDelay < 0) {
-                mScreenOffDelay = Integer.MAX_VALUE;
+                // negative number means stay on as long as possible.
+                mScreenOffDelay = mMaximumScreenOffTimeout;
             } else if (mKeylightDelay < totalDelay) {
                 // subtract the time that the keylight delay. This will give us the
                 // remainder of the time that we need to sleep to get the accurate
diff --git a/services/java/com/android/server/ProcessStats.java b/services/java/com/android/server/ProcessStats.java
index 4fa89d9..5bdadcc 100644
--- a/services/java/com/android/server/ProcessStats.java
+++ b/services/java/com/android/server/ProcessStats.java
@@ -39,7 +39,7 @@
     
     private static final int[] PROCESS_STATS_FORMAT = new int[] {
         PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_PARENS,
         PROC_SPACE_TERM,
         PROC_SPACE_TERM,
         PROC_SPACE_TERM,
@@ -75,16 +75,21 @@
         PROC_SPACE_TERM,
         PROC_SPACE_TERM,
         PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 9: minor faults
         PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 11: major faults
         PROC_SPACE_TERM,
         PROC_SPACE_TERM|PROC_OUT_LONG,                  // 13: utime
         PROC_SPACE_TERM|PROC_OUT_LONG                   // 14: stime
     };
 
-    private final String[] mProcessFullStatsStringData = new String[3];
-    private final long[] mProcessFullStatsData = new long[3];
+    static final int PROCESS_FULL_STAT_MINOR_FAULTS = 1;
+    static final int PROCESS_FULL_STAT_MAJOR_FAULTS = 2;
+    static final int PROCESS_FULL_STAT_UTIME = 3;
+    static final int PROCESS_FULL_STAT_STIME = 4;
+
+    private final String[] mProcessFullStatsStringData = new String[5];
+    private final long[] mProcessFullStatsData = new long[5];
 
     private static final int[] SYSTEM_CPU_FORMAT = new int[] {
         PROC_SPACE_TERM|PROC_COMBINE,
@@ -116,6 +121,9 @@
     private long mCurrentSampleTime;
     private long mLastSampleTime;
     
+    private long mCurrentSampleRealTime;
+    private long mLastSampleRealTime;
+
     private long mBaseUserTime;
     private long mBaseSystemTime;
     private long mBaseIoWaitTime;
@@ -167,6 +175,9 @@
         public String name;
         int nameWidth;
 
+        public long base_uptime;
+        public long rel_uptime;
+
         public long base_utime;
         public long base_stime;
         public int rel_utime;
@@ -178,6 +189,7 @@
         public int rel_majfaults;
         
         public boolean active;
+        public boolean working;
         public boolean added;
         public boolean removed;
         
@@ -211,8 +223,7 @@
 
     private final static Comparator<Stats> sLoadComparator = new Comparator<Stats>() {
         public final int
-        compare(Stats sta, Stats stb)
-        {
+        compare(Stats sta, Stats stb) {
             int ta = sta.rel_utime + sta.rel_stime;
             int tb = stb.rel_utime + stb.rel_stime;
             if (ta != tb) {
@@ -241,31 +252,17 @@
     }
     
     public void init() {
+        if (DEBUG) Slog.v(TAG, "Init: " + this);
         mFirst = true;
         update();
     }
     
     public void update() {
+        if (DEBUG) Slog.v(TAG, "Update: " + this);
         mLastSampleTime = mCurrentSampleTime;
         mCurrentSampleTime = SystemClock.uptimeMillis();
-        
-        final float[] loadAverages = mLoadAverageData;
-        if (Process.readProcFile("/proc/loadavg", LOAD_AVERAGE_FORMAT,
-                null, null, loadAverages)) {
-            float load1 = loadAverages[0];
-            float load5 = loadAverages[1];
-            float load15 = loadAverages[2];
-            if (load1 != mLoad1 || load5 != mLoad5 || load15 != mLoad15) {
-                mLoad1 = load1;
-                mLoad5 = load5;
-                mLoad15 = load15;
-                onLoadChanged(load1, load5, load15);
-            }
-        }
-
-        mCurPids = collectStats("/proc", -1, mFirst, mCurPids,
-                mProcStats, mWorkingProcs);
-        mFirst = false;
+        mLastSampleRealTime = mCurrentSampleRealTime;
+        mCurrentSampleRealTime = SystemClock.elapsedRealtime();
         
         final long[] sysCpu = mSystemCpuData;
         if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT,
@@ -288,7 +285,7 @@
             mRelSoftIrqTime = (int)(softirqtime - mBaseSoftIrqTime);
             mRelIdleTime = (int)(idletime - mBaseIdleTime);
 
-            if (false) {
+            if (DEBUG) {
                 Slog.i("Load", "Total U:" + sysCpu[0] + " N:" + sysCpu[1]
                       + " S:" + sysCpu[2] + " I:" + sysCpu[3]
                       + " W:" + sysCpu[4] + " Q:" + sysCpu[5]
@@ -305,16 +302,32 @@
             mBaseIdleTime = idletime;
         }
 
+        mCurPids = collectStats("/proc", -1, mFirst, mCurPids, mProcStats);
+
+        final float[] loadAverages = mLoadAverageData;
+        if (Process.readProcFile("/proc/loadavg", LOAD_AVERAGE_FORMAT,
+                null, null, loadAverages)) {
+            float load1 = loadAverages[0];
+            float load5 = loadAverages[1];
+            float load15 = loadAverages[2];
+            if (load1 != mLoad1 || load5 != mLoad5 || load15 != mLoad15) {
+                mLoad1 = load1;
+                mLoad5 = load5;
+                mLoad15 = load15;
+                onLoadChanged(load1, load5, load15);
+            }
+        }
+
+        if (DEBUG) Slog.i(TAG, "*** TIME TO COLLECT STATS: "
+                + (SystemClock.uptimeMillis()-mCurrentSampleTime));
+
         mWorkingProcsSorted = false;
         mFirst = false;
     }    
     
     private int[] collectStats(String statsFile, int parentPid, boolean first,
-            int[] curPids, ArrayList<Stats> allProcs,
-            ArrayList<Stats> workingProcs) {
+            int[] curPids, ArrayList<Stats> allProcs) {
         
-        workingProcs.clear();
-
         int[] pids = Process.getPids(statsFile, curPids);
         int NP = (pids == null) ? 0 : pids.length;
         int NS = allProcs.size();
@@ -330,8 +343,13 @@
             if (st != null && st.pid == pid) {
                 // Update an existing process...
                 st.added = false;
+                st.working = false;
                 curStatsIndex++;
-                if (localLOGV) Slog.v(TAG, "Existing pid " + pid + ": " + st);
+                if (DEBUG) Slog.v(TAG, "Existing "
+                        + (parentPid < 0 ? "process" : "thread")
+                        + " pid " + pid + ": " + st);
+
+                final long uptime = SystemClock.uptimeMillis();
 
                 final long[] procStats = mProcessStatsData;
                 if (!Process.readProcFile(st.statFile.toString(),
@@ -363,11 +381,18 @@
                     getName(st, st.cmdlineFile);
                     if (st.threadStats != null) {
                         mCurThreadPids = collectStats(st.threadsDir, pid, false,
-                                mCurThreadPids, st.threadStats,
-                                st.workingThreads);
+                                mCurThreadPids, st.threadStats);
                     }
                 }
 
+                if (DEBUG) Slog.v("Load", "Stats changed " + st.name + " pid=" + st.pid
+                        + " utime=" + utime + "-" + st.base_utime
+                        + " stime=" + stime + "-" + st.base_stime
+                        + " minfaults=" + minfaults + "-" + st.base_minfaults
+                        + " majfaults=" + majfaults + "-" + st.base_majfaults);
+
+                st.rel_uptime = uptime - st.base_uptime;
+                st.base_uptime = uptime;
                 st.rel_utime = (int)(utime - st.base_utime);
                 st.rel_stime = (int)(stime - st.base_stime);
                 st.base_utime = utime;
@@ -376,10 +401,7 @@
                 st.rel_majfaults = (int)(majfaults - st.base_majfaults);
                 st.base_minfaults = minfaults;
                 st.base_majfaults = majfaults;
-                //Slog.i("Load", "Stats changed " + name + " pid=" + st.pid
-                //      + " name=" + st.name + " utime=" + utime
-                //      + " stime=" + stime);
-                workingProcs.add(st);
+                st.working = true;
                 continue;
             }
             
@@ -389,18 +411,21 @@
                 allProcs.add(curStatsIndex, st);
                 curStatsIndex++;
                 NS++;
-                if (localLOGV) Slog.v(TAG, "New pid " + pid + ": " + st);
+                if (DEBUG) Slog.v(TAG, "New "
+                        + (parentPid < 0 ? "process" : "thread")
+                        + " pid " + pid + ": " + st);
 
                 final String[] procStatsString = mProcessFullStatsStringData;
                 final long[] procStats = mProcessFullStatsData;
+                st.base_uptime = SystemClock.uptimeMillis();
                 if (Process.readProcFile(st.statFile.toString(),
                         PROCESS_FULL_STATS_FORMAT, procStatsString,
                         procStats, null)) {
-                    st.baseName = parentPid < 0
-                            ? procStatsString[0] : Integer.toString(pid);
-                    st.base_utime = 0; //procStats[1];
-                    st.base_stime = 0; //procStats[2];
-                    st.base_minfaults = st.base_majfaults = 0;
+                    st.baseName = procStatsString[0];
+                    st.base_minfaults = procStats[PROCESS_FULL_STAT_MINOR_FAULTS];
+                    st.base_majfaults = procStats[PROCESS_FULL_STAT_MAJOR_FAULTS];
+                    st.base_utime = procStats[PROCESS_FULL_STAT_UTIME];
+                    st.base_stime = procStats[PROCESS_FULL_STAT_STIME];
                 } else {
                     st.baseName = "<unknown>";
                     st.base_utime = st.base_stime = 0;
@@ -409,24 +434,26 @@
 
                 if (parentPid < 0) {
                     getName(st, st.cmdlineFile);
+                    if (st.threadStats != null) {
+                        mCurThreadPids = collectStats(st.threadsDir, pid, true,
+                                mCurThreadPids, st.threadStats);
+                    }
                 } else {
                     st.name = st.baseName;
                     st.nameWidth = onMeasureProcessName(st.name);
-                    if (st.threadStats != null) {
-                        mCurThreadPids = collectStats(st.threadsDir, pid, true,
-                                mCurThreadPids, st.threadStats,
-                                st.workingThreads);
-                    }
                 }
+
+                if (DEBUG) Slog.v("Load", "Stats added " + st.name + " pid=" + st.pid
+                        + " utime=" + st.base_utime + " stime=" + st.base_stime
+                        + " minfaults=" + st.base_minfaults + " majfaults=" + st.base_majfaults);
                 
-                //Slog.i("Load", "New process: " + st.pid + " " + st.name);
                 st.rel_utime = 0;
                 st.rel_stime = 0;
                 st.rel_minfaults = 0;
                 st.rel_majfaults = 0;
                 st.added = true;
                 if (!first) {
-                    workingProcs.add(st);
+                    st.working = true;
                 }
                 continue;
             }
@@ -437,10 +464,12 @@
             st.rel_minfaults = 0;
             st.rel_majfaults = 0;
             st.removed = true;
-            workingProcs.add(st);
+            st.working = true;
             allProcs.remove(curStatsIndex);
             NS--;
-            if (localLOGV) Slog.v(TAG, "Removed pid " + st.pid + ": " + st);
+            if (DEBUG) Slog.v(TAG, "Removed "
+                    + (parentPid < 0 ? "process" : "thread")
+                    + " pid " + pid + ": " + st);
             // Decrement the loop counter so that we process the current pid
             // again the next time through the loop.
             i--;
@@ -455,7 +484,7 @@
             st.rel_minfaults = 0;
             st.rel_majfaults = 0;
             st.removed = true;
-            workingProcs.add(st);
+            st.working = true;
             allProcs.remove(curStatsIndex);
             NS--;
             if (localLOGV) Slog.v(TAG, "Removed pid " + st.pid + ": " + st);
@@ -569,11 +598,34 @@
                 / (mRelUserTime+mRelSystemTime+mRelIrqTime+mRelIdleTime);
     }
     
-    final public int countWorkingStats() {
+    final void buildWorkingProcs() {
         if (!mWorkingProcsSorted) {
+            mWorkingProcs.clear();
+            final int N = mProcStats.size();
+            for (int i=0; i<N; i++) {
+                Stats stats = mProcStats.get(i);
+                if (stats.working) {
+                    mWorkingProcs.add(stats);
+                    if (stats.threadStats != null && stats.threadStats.size() > 1) {
+                        stats.workingThreads.clear();
+                        final int M = stats.threadStats.size();
+                        for (int j=0; j<M; j++) {
+                            Stats tstats = stats.threadStats.get(j);
+                            if (tstats.working) {
+                                stats.workingThreads.add(tstats);
+                            }
+                        }
+                        Collections.sort(stats.workingThreads, sLoadComparator);
+                    }
+                }
+            }
             Collections.sort(mWorkingProcs, sLoadComparator);
             mWorkingProcsSorted = true;
         }
+    }
+
+    final public int countWorkingStats() {
+        buildWorkingProcs();
         return mWorkingProcs.size();
     }
 
@@ -581,12 +633,7 @@
         return mWorkingProcs.get(index);
     }
     
-    final public String printCurrentState() {
-        if (!mWorkingProcsSorted) {
-            Collections.sort(mWorkingProcs, sLoadComparator);
-            mWorkingProcsSorted = true;
-        }
-        
+    final public String printCurrentLoad() {
         StringWriter sw = new StringWriter();
         PrintWriter pw = new PrintWriter(sw);
         pw.print("Load: ");
@@ -595,67 +642,111 @@
         pw.print(mLoad5);
         pw.print(" / ");
         pw.println(mLoad15);
+        return sw.toString();
+    }
+
+    final public String printCurrentState(long now) {
+        buildWorkingProcs();
         
-        long now = SystemClock.uptimeMillis();
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
         
         pw.print("CPU usage from ");
-        pw.print(now-mLastSampleTime);
-        pw.print("ms to ");
-        pw.print(now-mCurrentSampleTime);
-        pw.println("ms ago:");
+        if (now > mLastSampleTime) {
+            pw.print(now-mLastSampleTime);
+            pw.print("ms to ");
+            pw.print(now-mCurrentSampleTime);
+            pw.print("ms ago");
+        } else {
+            pw.print(mLastSampleTime-now);
+            pw.print("ms to ");
+            pw.print(mCurrentSampleTime-now);
+            pw.print("ms later");
+        }
+
+        long sampleTime = mCurrentSampleTime - mLastSampleTime;
+        long sampleRealTime = mCurrentSampleRealTime - mLastSampleRealTime;
+        long percAwake = (sampleTime*100) / sampleRealTime;
+        if (percAwake != 100) {
+            pw.print(" with ");
+            pw.print(percAwake);
+            pw.print("% awake");
+        }
+        pw.println(":");
         
         final int totalTime = mRelUserTime + mRelSystemTime + mRelIoWaitTime
                 + mRelIrqTime + mRelSoftIrqTime + mRelIdleTime;
         
+        if (DEBUG) Slog.i(TAG, "totalTime " + totalTime + " over sample time "
+                + (mCurrentSampleTime-mLastSampleTime));
+
         int N = mWorkingProcs.size();
         for (int i=0; i<N; i++) {
             Stats st = mWorkingProcs.get(i);
             printProcessCPU(pw, st.added ? " +" : (st.removed ? " -": "  "),
-                    st.name, totalTime, st.rel_utime, st.rel_stime, 0, 0, 0,
-                    st.rel_minfaults, st.rel_majfaults);
+                    st.pid, st.name, (int)(st.rel_uptime+5)/10,
+                    st.rel_utime, st.rel_stime, 0, 0, 0, st.rel_minfaults, st.rel_majfaults);
             if (!st.removed && st.workingThreads != null) {
                 int M = st.workingThreads.size();
                 for (int j=0; j<M; j++) {
                     Stats tst = st.workingThreads.get(j);
                     printProcessCPU(pw,
                             tst.added ? "   +" : (tst.removed ? "   -": "    "),
-                            tst.name, totalTime, tst.rel_utime, tst.rel_stime,
-                            0, 0, 0, 0, 0);
+                            tst.pid, tst.name, (int)(st.rel_uptime+5)/10,
+                            tst.rel_utime, tst.rel_stime, 0, 0, 0, 0, 0);
                 }
             }
         }
         
-        printProcessCPU(pw, "", "TOTAL", totalTime, mRelUserTime, mRelSystemTime,
+        printProcessCPU(pw, "", -1, "TOTAL", totalTime, mRelUserTime, mRelSystemTime,
                 mRelIoWaitTime, mRelIrqTime, mRelSoftIrqTime, 0, 0);
         
         return sw.toString();
     }
     
-    private void printProcessCPU(PrintWriter pw, String prefix, String label, int totalTime, 
-            int user, int system, int iowait, int irq, int softIrq, int minFaults, int majFaults) {
+    private void printRatio(PrintWriter pw, long numerator, long denominator) {
+        long thousands = (numerator*1000)/denominator;
+        long hundreds = thousands/10;
+        pw.print(hundreds);
+        if (hundreds < 10) {
+            long remainder = thousands - (hundreds*10);
+            if (remainder != 0) {
+                pw.print('.');
+                pw.print(remainder);
+            }
+        }
+    }
+
+    private void printProcessCPU(PrintWriter pw, String prefix, int pid, String label,
+            int totalTime, int user, int system, int iowait, int irq, int softIrq,
+            int minFaults, int majFaults) {
         pw.print(prefix);
+        if (totalTime == 0) totalTime = 1;
+        printRatio(pw, user+system+iowait+irq+softIrq, totalTime);
+        pw.print("% ");
+        if (pid >= 0) {
+            pw.print(pid);
+            pw.print("/");
+        }
         pw.print(label);
         pw.print(": ");
-        if (totalTime == 0) totalTime = 1;
-        pw.print(((user+system+iowait+irq+softIrq)*100)/totalTime);
-        pw.print("% = ");
-        pw.print((user*100)/totalTime);
+        printRatio(pw, user, totalTime);
         pw.print("% user + ");
-        pw.print((system*100)/totalTime);
+        printRatio(pw, system, totalTime);
         pw.print("% kernel");
         if (iowait > 0) {
             pw.print(" + ");
-            pw.print((iowait*100)/totalTime);
+            printRatio(pw, iowait, totalTime);
             pw.print("% iowait");
         }
         if (irq > 0) {
             pw.print(" + ");
-            pw.print((irq*100)/totalTime);
+            printRatio(pw, irq, totalTime);
             pw.print("% irq");
         }
         if (softIrq > 0) {
             pw.print(" + ");
-            pw.print((softIrq*100)/totalTime);
+            printRatio(pw, softIrq, totalTime);
             pw.print("% softirq");
         }
         if (minFaults > 0 || majFaults > 0) {
@@ -696,8 +787,8 @@
     }
 
     private void getName(Stats st, String cmdlineFile) {
-        String newName = st.baseName;
-        if (st.baseName == null || st.baseName.equals("app_process")) {
+        String newName = st.name;
+        if (st.name == null || st.name.equals("app_process")) {
             String cmdName = readFile(cmdlineFile, '\0');
             if (cmdName != null && cmdName.length() > 1) {
                 newName = cmdName;
@@ -706,6 +797,9 @@
                     newName = newName.substring(i+1);
                 }
             }
+            if (newName == null) {
+                newName = st.baseName;
+            }
         }
         if (st.name == null || !newName.equals(st.name)) {
             st.name = newName;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index d44ce97..dffc31c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -431,8 +431,11 @@
             }
 
             try {
-                Slog.i(TAG, "Sip Service");
-                ServiceManager.addService("sip", new SipService(context));
+                SipService sipService = SipService.create(context);
+                if (sipService != null) {
+                    Slog.i(TAG, "Sip Service");
+                    ServiceManager.addService("sip", sipService);
+                }
             } catch (Throwable e) {
                 Slog.e(TAG, "Failure starting SIP Service", e);
             }
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 73234df..0a90a4c 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -19,7 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -92,7 +92,7 @@
 
     private ArrayList<String> mConnectedApns;
 
-    private NetworkProperties mDataConnectionProperties;
+    private LinkProperties mDataConnectionProperties;
 
     private Bundle mCellLocation = new Bundle();
 
@@ -355,7 +355,7 @@
     }
 
     public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
-            String reason, String apn, String apnType, NetworkProperties networkProperties,
+            String reason, String apn, String apnType, LinkProperties linkProperties,
             int networkType) {
         if (!checkNotifyPermission("notifyDataConnection()" )) {
             return;
@@ -383,7 +383,7 @@
             mDataConnectionPossible = isDataConnectivityPossible;
             mDataConnectionReason = reason;
             mDataConnectionApn = apn;
-            mDataConnectionProperties = networkProperties;
+            mDataConnectionProperties = linkProperties;
             if (mDataConnectionNetworkType != networkType) {
                 mDataConnectionNetworkType = networkType;
                 modified = true;
@@ -403,7 +403,7 @@
             }
         }
         broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
-                apnType, networkProperties);
+                apnType, linkProperties);
     }
 
     public void notifyDataConnectionFailed(String reason, String apnType) {
@@ -564,7 +564,7 @@
 
     private void broadcastDataConnectionStateChanged(int state,
             boolean isDataConnectivityPossible,
-            String reason, String apn, String apnType, NetworkProperties networkProperties) {
+            String reason, String apn, String apnType, LinkProperties linkProperties) {
         // Note: not reporting to the battery stats service here, because the
         // status bar takes care of that after taking into account all of the
         // required info.
@@ -577,9 +577,9 @@
         if (reason != null) {
             intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
         }
-        if (networkProperties != null) {
-            intent.putExtra(Phone.DATA_NETWORK_PROPERTIES_KEY, networkProperties);
-            NetworkInterface iface = networkProperties.getInterface();
+        if (linkProperties != null) {
+            intent.putExtra(Phone.DATA_LINK_PROPERTIES_KEY, linkProperties);
+            NetworkInterface iface = linkProperties.getInterface();
             if (iface != null) {
                 intent.putExtra(Phone.DATA_IFACE_NAME_KEY, iface.getName());
             }
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index a742093..1b885f5 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -39,9 +39,6 @@
 import android.util.Slog;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Calendar;
 
@@ -113,8 +110,6 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MONITOR: {
-                    long now = SystemClock.uptimeMillis();
-
                     // See if we should force a reboot.
                     int rebootInterval = mReqRebootInterval >= 0
                             ? mReqRebootInterval : Settings.Secure.getInt(
@@ -418,9 +413,9 @@
                 if (!waitedHalf) {
                     // We've waited half the deadlock-detection interval.  Pull a stack
                     // trace and wait another half.
-                    ArrayList pids = new ArrayList();
+                    ArrayList<Integer> pids = new ArrayList<Integer>();
                     pids.add(Process.myPid());
-                    File stack = ActivityManagerService.dumpStackTraces(true, pids);
+                    ActivityManagerService.dumpStackTraces(true, pids, null, null);
                     waitedHalf = true;
                     continue;
                 }
@@ -430,15 +425,16 @@
             // First collect stack traces from all threads of the system process.
             // Then kill this process so that the system will restart.
 
-            String name = (mCurrentMonitor != null) ? mCurrentMonitor.getClass().getName() : "null";
+            String name = (mCurrentMonitor != null) ?
+                    mCurrentMonitor.getClass().getName() : "null";
             EventLog.writeEvent(EventLogTags.WATCHDOG, name);
 
-            ArrayList pids = new ArrayList();
+            ArrayList<Integer> pids = new ArrayList<Integer>();
             pids.add(Process.myPid());
             if (mPhonePid > 0) pids.add(mPhonePid);
             // Pass !waitedHalf so that just in case we somehow wind up here without having
             // dumped the halfway stacks, we properly re-initialize the trace file.
-            File stack = ActivityManagerService.dumpStackTraces(!waitedHalf, pids);
+            File stack = ActivityManagerService.dumpStackTraces(!waitedHalf, pids, null, null);
 
             // Give some extra time to make sure the stack traces get written.
             // The system's been hanging for a minute, another second or two won't hurt much.
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 4407e96..79bde7c 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -4383,6 +4383,14 @@
         return mInputManager.monitorInput(inputChannelName);
     }
 
+    public InputDevice getInputDevice(int deviceId) {
+        return mInputManager.getInputDevice(deviceId);
+    }
+
+    public int[] getInputDeviceIds() {
+        return mInputManager.getInputDeviceIds();
+    }
+
     public void enableScreenAfterBoot() {
         synchronized(mWindowMap) {
             if (mSystemBooted) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 123dc3e..2ce8c08 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1356,7 +1356,9 @@
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             synchronized (mActivityManagerService.mProcessStatsThread) {
-                pw.print(mActivityManagerService.mProcessStats.printCurrentState());
+                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
+                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
+                        SystemClock.uptimeMillis()));
             }
         }
     }
@@ -2649,10 +2651,12 @@
      * @param clearTraces causes the dump file to be erased prior to the new
      *    traces being written, if true; when false, the new traces will be
      *    appended to any existing file content.
-     * @param pids of dalvik VM processes to dump stack traces for
+     * @param firstPids of dalvik VM processes to dump stack traces for first
+     * @param lastPids of dalvik VM processes to dump stack traces for last
      * @return file containing stack traces, or null if no dump file is configured
      */
-    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> pids) {
+    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
+            ProcessStats processStats, SparseArray<Boolean> lastPids) {
         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
         if (tracesPath == null || tracesPath.length() == 0) {
             return null;
@@ -2680,25 +2684,69 @@
 
         try {
             observer.startWatching();
-            int num = pids.size();
-            for (int i = 0; i < num; i++) {
-                synchronized (observer) {
-                    Process.sendSignal(pids.get(i), Process.SIGNAL_QUIT);
-                    observer.wait(200);  // Wait for write-close, give up after 200msec
+
+            // First collect all of the stacks of the most important pids.
+            try {
+                int num = firstPids.size();
+                for (int i = 0; i < num; i++) {
+                    synchronized (observer) {
+                        Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
+                        observer.wait(200);  // Wait for write-close, give up after 200msec
+                    }
+                }
+            } catch (InterruptedException e) {
+                Log.wtf(TAG, e);
+            }
+
+            // Next measure CPU usage.
+            if (processStats != null) {
+                processStats.init();
+                System.gc();
+                processStats.update();
+                try {
+                    synchronized (processStats) {
+                        processStats.wait(500); // measure over 1/2 second.
+                    }
+                } catch (InterruptedException e) {
+                }
+                processStats.update();
+
+                // We'll take the stack crawls of just the top apps using CPU.
+                final int N = processStats.countWorkingStats();
+                int numProcs = 0;
+                for (int i=0; i<N && numProcs<5; i++) {
+                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
+                    if (lastPids.indexOfKey(stats.pid) >= 0) {
+                        numProcs++;
+                        try {
+                            synchronized (observer) {
+                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
+                                observer.wait(200);  // Wait for write-close, give up after 200msec
+                            }
+                        } catch (InterruptedException e) {
+                            Log.wtf(TAG, e);
+                        }
+
+                    }
                 }
             }
-        } catch (InterruptedException e) {
-            Log.wtf(TAG, e);
+
+            return tracesFile;
+
         } finally {
             observer.stopWatching();
         }
-
-        return tracesFile;
     }
 
     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
             ActivityRecord parent, final String annotation) {
-        ArrayList<Integer> pids = new ArrayList<Integer>(20);
+        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
+        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
+
+        long anrTime = SystemClock.uptimeMillis();
+        if (MONITOR_CPU_USAGE) {
+            updateCpuStatsNow();
+        }
         
         synchronized (this) {
             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
@@ -2722,24 +2770,32 @@
                     annotation);
 
             // Dump thread traces as quickly as we can, starting with "interesting" processes.
-            pids.add(app.pid);
+            firstPids.add(app.pid);
     
             int parentPid = app.pid;
             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
-            if (parentPid != app.pid) pids.add(parentPid);
+            if (parentPid != app.pid) firstPids.add(parentPid);
     
-            if (MY_PID != app.pid && MY_PID != parentPid) pids.add(MY_PID);
+            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
 
             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
                 ProcessRecord r = mLruProcesses.get(i);
                 if (r != null && r.thread != null) {
                     int pid = r.pid;
-                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) pids.add(pid);
+                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
+                        if (r.persistent) {
+                            firstPids.add(pid);
+                        } else {
+                            lastPids.put(pid, Boolean.TRUE);
+                        }
+                    }
                 }
             }
         }
 
-        File tracesFile = dumpStackTraces(true, pids);
+        final ProcessStats processStats = new ProcessStats(true);
+
+        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
 
         // Log the ANR to the main log.
         StringBuilder info = mStringBuilder;
@@ -2760,11 +2816,14 @@
         if (MONITOR_CPU_USAGE) {
             updateCpuStatsNow();
             synchronized (mProcessStatsThread) {
-                cpuInfo = mProcessStats.printCurrentState();
+                cpuInfo = mProcessStats.printCurrentState(anrTime);
             }
+            info.append(processStats.printCurrentLoad());
             info.append(cpuInfo);
         }
 
+        info.append(processStats.printCurrentState(anrTime));
+
         Slog.e(TAG, info.toString());
         if (tracesFile == null) {
             // There is no trace file, so dump (only) the alleged culprit's threads to the log
@@ -6799,7 +6858,7 @@
                                 app.pid, app.getPackageList());
                     currApp.uid = app.info.uid;
                     if (mHeavyWeightProcess == app) {
-                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HEAVY_WEIGHT;
+                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
                     }
                     int adj = app.curAdj;
                     if (adj >= EMPTY_APP_ADJ) {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index c21a221..5f79b85 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2885,7 +2885,8 @@
                     + " res=" + resultCode + " data=" + resultData);
             if (r.info.applicationInfo.uid > 0) {
                 mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
-                        r.packageName, resultData, r.getUriPermissionsLocked());
+                        resultTo.packageName, resultData, 
+                        resultTo.getUriPermissionsLocked());
             }
             resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
                                      resultData);
diff --git a/services/java/com/android/server/sip/SipHelper.java b/services/java/com/android/server/sip/SipHelper.java
index 83eeb84..d9a1bbf 100644
--- a/services/java/com/android/server/sip/SipHelper.java
+++ b/services/java/com/android/server/sip/SipHelper.java
@@ -20,7 +20,6 @@
 import gov.nist.javax.sip.clientauthutils.AccountManager;
 import gov.nist.javax.sip.clientauthutils.AuthenticationHelper;
 
-import android.net.sip.SessionDescription;
 import android.net.sip.SipProfile;
 import android.util.Log;
 
@@ -243,7 +242,7 @@
     }
 
     public ClientTransaction sendInvite(SipProfile caller, SipProfile callee,
-            SessionDescription sessionDescription, String tag)
+            String sessionDescription, String tag)
             throws SipException {
         try {
             FromHeader fromHeader = createFromHeader(caller, tag);
@@ -259,9 +258,9 @@
                     toHeader, viaHeaders, maxForwards);
 
             request.addHeader(createContactHeader(caller));
-            request.setContent(sessionDescription.getContent(),
+            request.setContent(sessionDescription,
                     mHeaderFactory.createContentTypeHeader(
-                            "application", sessionDescription.getType()));
+                            "application", "sdp"));
 
             ClientTransaction clientTransaction =
                     mSipProvider.getNewClientTransaction(request);
@@ -273,12 +272,12 @@
     }
 
     public ClientTransaction sendReinvite(Dialog dialog,
-            SessionDescription sessionDescription) throws SipException {
+            String sessionDescription) throws SipException {
         try {
             Request request = dialog.createRequest(Request.INVITE);
-            request.setContent(sessionDescription.getContent(),
+            request.setContent(sessionDescription,
                     mHeaderFactory.createContentTypeHeader(
-                            "application", sessionDescription.getType()));
+                            "application", "sdp"));
 
             ClientTransaction clientTransaction =
                     mSipProvider.getNewClientTransaction(request);
@@ -326,7 +325,7 @@
      * @param event the INVITE request event
      */
     public ServerTransaction sendInviteOk(RequestEvent event,
-            SipProfile localProfile, SessionDescription sessionDescription,
+            SipProfile localProfile, String sessionDescription,
             ServerTransaction inviteTransaction)
             throws SipException {
         try {
@@ -334,9 +333,9 @@
             Response response = mMessageFactory.createResponse(Response.OK,
                     request);
             response.addHeader(createContactHeader(localProfile));
-            response.setContent(sessionDescription.getContent(),
+            response.setContent(sessionDescription,
                     mHeaderFactory.createContentTypeHeader(
-                            "application", sessionDescription.getType()));
+                            "application", "sdp"));
 
             if (inviteTransaction == null) {
                 inviteTransaction = getServerTransaction(event);
diff --git a/services/java/com/android/server/sip/SipService.java b/services/java/com/android/server/sip/SipService.java
index 3dcaff6..563ce58 100644
--- a/services/java/com/android/server/sip/SipService.java
+++ b/services/java/com/android/server/sip/SipService.java
@@ -54,6 +54,7 @@
 import javax.sip.SipException;
 
 /**
+ * @hide
  */
 public final class SipService extends ISipService.Stub {
     private static final String TAG = "SipService";
@@ -78,7 +79,16 @@
 
     private ConnectivityReceiver mConnectivityReceiver;
 
-    public SipService(Context context) {
+    /**
+     * Creates a {@code SipService} instance. Returns null if SIP API is not
+     * supported.
+     */
+    public static SipService create(Context context) {
+        return (SipManager.isApiSupported(context) ? new SipService(context)
+                                                   : null);
+    }
+
+    private SipService(Context context) {
         Log.v(TAG, " service started!");
         mContext = context;
         mConnectivityReceiver = new ConnectivityReceiver();
@@ -435,7 +445,7 @@
 
         @Override
         public void onRinging(ISipSession session, SipProfile caller,
-                byte[] sessionDescription) {
+                String sessionDescription) {
             synchronized (SipService.this) {
                 try {
                     if (!isRegistered()) {
diff --git a/services/java/com/android/server/sip/SipSessionGroup.java b/services/java/com/android/server/sip/SipSessionGroup.java
index d33558b..8019bfa 100644
--- a/services/java/com/android/server/sip/SipSessionGroup.java
+++ b/services/java/com/android/server/sip/SipSessionGroup.java
@@ -20,6 +20,7 @@
 import gov.nist.javax.sip.clientauthutils.UserCredentials;
 import gov.nist.javax.sip.header.SIPHeaderNames;
 import gov.nist.javax.sip.header.WWWAuthenticate;
+import gov.nist.javax.sip.message.SIPMessage;
 
 import android.net.sip.ISipSession;
 import android.net.sip.ISipSessionListener;
@@ -31,6 +32,7 @@
 import android.util.Log;
 
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.net.DatagramSocket;
 import java.text.ParseException;
 import java.util.Collection;
@@ -284,6 +286,22 @@
         }
     }
 
+    private String extractContent(Message message) {
+        // Currently we do not support secure MIME bodies.
+        byte[] bytes = message.getRawContent();
+        if (bytes != null) {
+            try {
+                if (message instanceof SIPMessage) {
+                    return ((SIPMessage) message).getMessageContent();
+                } else {
+                    return new String(bytes, "UTF-8");
+                }
+            } catch (UnsupportedEncodingException e) {
+            }
+        }
+        return null;
+    }
+
     private class SipSessionCallReceiverImpl extends SipSessionImpl {
         public SipSessionCallReceiverImpl(ISipSessionListener listener) {
             super(listener);
@@ -302,7 +320,7 @@
                 newSession.mPeerProfile = createPeerProfile(event.getRequest());
                 newSession.mState = SipSessionState.INCOMING_CALL;
                 newSession.mPeerSessionDescription =
-                        event.getRequest().getRawContent();
+                        extractContent(event.getRequest());
                 addSipSession(newSession);
                 mProxy.onRinging(newSession, newSession.mPeerProfile,
                         newSession.mPeerSessionDescription);
@@ -321,7 +339,7 @@
         Dialog mDialog;
         ServerTransaction mServerTransaction;
         ClientTransaction mClientTransaction;
-        byte[] mPeerSessionDescription;
+        String mPeerSessionDescription;
         boolean mInCall;
         boolean mReRegisterFlag = false;
 
@@ -401,12 +419,12 @@
         }
 
         public void makeCall(SipProfile peerProfile,
-                SessionDescription sessionDescription) {
+                String sessionDescription) {
             doCommandAsync(
                     new MakeCallCommand(peerProfile, sessionDescription));
         }
 
-        public void answerCall(SessionDescription sessionDescription) {
+        public void answerCall(String sessionDescription) {
             try {
                 processCommand(
                         new MakeCallCommand(mPeerProfile, sessionDescription));
@@ -419,7 +437,7 @@
             doCommandAsync(END_CALL);
         }
 
-        public void changeCall(SessionDescription sessionDescription) {
+        public void changeCall(String sessionDescription) {
             doCommandAsync(
                     new MakeCallCommand(mPeerProfile, sessionDescription));
         }
@@ -726,10 +744,9 @@
             if (evt instanceof MakeCallCommand) {
                 MakeCallCommand cmd = (MakeCallCommand) evt;
                 mPeerProfile = cmd.getPeerProfile();
-                SessionDescription sessionDescription =
-                        cmd.getSessionDescription();
                 mClientTransaction = mSipHelper.sendInvite(mLocalProfile,
-                        mPeerProfile, sessionDescription, generateTag());
+                        mPeerProfile, cmd.getSessionDescription(),
+                        generateTag());
                 mDialog = mClientTransaction.getDialog();
                 addSipSession(this);
                 mState = SipSessionState.OUTGOING_CALL;
@@ -811,7 +828,7 @@
                     return true;
                 case Response.OK:
                     mSipHelper.sendInviteAck(event, mDialog);
-                    mPeerSessionDescription = response.getRawContent();
+                    mPeerSessionDescription = extractContent(response);
                     establishCall();
                     return true;
                 case Response.PROXY_AUTHENTICATION_REQUIRED:
@@ -897,7 +914,7 @@
                 // got Re-INVITE
                 RequestEvent event = mInviteReceived = (RequestEvent) evt;
                 mState = SipSessionState.INCOMING_CALL;
-                mPeerSessionDescription = event.getRequest().getRawContent();
+                mPeerSessionDescription = extractContent(event.getRequest());
                 mServerTransaction = null;
                 mProxy.onRinging(this, mPeerProfile, mPeerSessionDescription);
                 return true;
@@ -1060,10 +1077,10 @@
     }
 
     private class MakeCallCommand extends EventObject {
-        private SessionDescription mSessionDescription;
+        private String mSessionDescription;
 
         public MakeCallCommand(SipProfile peerProfile,
-                SessionDescription sessionDescription) {
+                String sessionDescription) {
             super(peerProfile);
             mSessionDescription = sessionDescription;
         }
@@ -1072,7 +1089,7 @@
             return (SipProfile) getSource();
         }
 
-        public SessionDescription getSessionDescription() {
+        public String getSessionDescription() {
             return mSessionDescription;
         }
     }
diff --git a/services/java/com/android/server/sip/SipSessionListenerProxy.java b/services/java/com/android/server/sip/SipSessionListenerProxy.java
index fd49fd8..7004204 100644
--- a/services/java/com/android/server/sip/SipSessionListenerProxy.java
+++ b/services/java/com/android/server/sip/SipSessionListenerProxy.java
@@ -56,7 +56,7 @@
     }
 
     public void onRinging(final ISipSession session, final SipProfile caller,
-            final byte[] sessionDescription) {
+            final String sessionDescription) {
         if (mListener == null) return;
         proxy(new Runnable() {
             public void run() {
@@ -83,7 +83,7 @@
     }
 
     public void onCallEstablished(final ISipSession session,
-            final byte[] sessionDescription) {
+            final String sessionDescription) {
         if (mListener == null) return;
         proxy(new Runnable() {
             public void run() {
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 3addc0d..a237ee9 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -138,6 +138,7 @@
     jmethodID filterTouchEvents;
     jmethodID filterJumpyTouchEvents;
     jmethodID getVirtualKeyDefinitions;
+    jmethodID getInputDeviceCalibration;
     jmethodID getExcludedDeviceNames;
     jmethodID getMaxEventsPerSecond;
 } gCallbacksClassInfo;
@@ -155,6 +156,13 @@
 static struct {
     jclass clazz;
 
+    jfieldID keys;
+    jfieldID values;
+} gInputDeviceCalibrationClassInfo;
+
+static struct {
+    jclass clazz;
+
     jfieldID inputChannel;
     jfieldID layoutParamsFlags;
     jfieldID layoutParamsType;
@@ -189,6 +197,19 @@
     jclass clazz;
 } gMotionEventClassInfo;
 
+static struct {
+    jclass clazz;
+
+    jmethodID ctor;
+    jmethodID addMotionRange;
+
+    jfieldID mId;
+    jfieldID mName;
+    jfieldID mSources;
+    jfieldID mKeyboardType;
+    jfieldID mMotionRanges;
+} gInputDeviceClassInfo;
+
 // ----------------------------------------------------------------------------
 
 static inline nsecs_t now() {
@@ -235,7 +256,9 @@
     virtual bool filterTouchEvents();
     virtual bool filterJumpyTouchEvents();
     virtual void getVirtualKeyDefinitions(const String8& deviceName,
-            Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions);
+            Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
+    virtual void getInputDeviceCalibration(const String8& deviceName,
+            InputDeviceCalibration& outCalibration);
     virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
 
     /* --- InputDispatcherPolicyInterface implementation --- */
@@ -761,7 +784,9 @@
 }
 
 void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
-        Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions) {
+        Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
+    outVirtualKeyDefinitions.clear();
+
     JNIEnv* env = jniEnv();
 
     jstring deviceNameStr = env->NewStringUTF(deviceName.string());
@@ -793,7 +818,51 @@
     }
 }
 
+void NativeInputManager::getInputDeviceCalibration(const String8& deviceName,
+        InputDeviceCalibration& outCalibration) {
+    outCalibration.clear();
+
+    JNIEnv* env = jniEnv();
+
+    jstring deviceNameStr = env->NewStringUTF(deviceName.string());
+    if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration")) {
+        jobject result = env->CallObjectMethod(mCallbacksObj,
+                gCallbacksClassInfo.getInputDeviceCalibration, deviceNameStr);
+        if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration") && result) {
+            jobjectArray keys = jobjectArray(env->GetObjectField(result,
+                    gInputDeviceCalibrationClassInfo.keys));
+            jobjectArray values = jobjectArray(env->GetObjectField(result,
+                    gInputDeviceCalibrationClassInfo.values));
+
+            jsize length = env->GetArrayLength(keys);
+            for (jsize i = 0; i < length; i++) {
+                jstring keyStr = jstring(env->GetObjectArrayElement(keys, i));
+                jstring valueStr = jstring(env->GetObjectArrayElement(values, i));
+
+                const char* keyChars = env->GetStringUTFChars(keyStr, NULL);
+                String8 key(keyChars);
+                env->ReleaseStringUTFChars(keyStr, keyChars);
+
+                const char* valueChars = env->GetStringUTFChars(valueStr, NULL);
+                String8 value(valueChars);
+                env->ReleaseStringUTFChars(valueStr, valueChars);
+
+                outCalibration.addProperty(key, value);
+
+                env->DeleteLocalRef(keyStr);
+                env->DeleteLocalRef(valueStr);
+            }
+            env->DeleteLocalRef(keys);
+            env->DeleteLocalRef(values);
+            env->DeleteLocalRef(result);
+        }
+        env->DeleteLocalRef(deviceNameStr);
+    }
+}
+
 void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
+    outExcludedDeviceNames.clear();
+
     JNIEnv* env = jniEnv();
 
     jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
@@ -2199,6 +2268,66 @@
     gNativeInputManager->preemptInputDispatch();
 }
 
+static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
+        jclass clazz, jint deviceId) {
+    if (checkInputManagerUnitialized(env)) {
+        return NULL;
+    }
+
+    InputDeviceInfo deviceInfo;
+    status_t status = gNativeInputManager->getInputManager()->getInputDeviceInfo(
+            deviceId, & deviceInfo);
+    if (status) {
+        return NULL;
+    }
+
+    jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
+    if (! deviceObj) {
+        return NULL;
+    }
+
+    jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
+    if (! deviceNameObj) {
+        return NULL;
+    }
+
+    env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
+    env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
+    env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
+    env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
+
+    const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
+    for (size_t i = 0; i < ranges.size(); i++) {
+        int rangeType = ranges.keyAt(i);
+        const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
+        env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
+                rangeType, range.min, range.max, range.flat, range.fuzz);
+        if (env->ExceptionCheck()) {
+            return NULL;
+        }
+    }
+
+    return deviceObj;
+}
+
+static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
+        jclass clazz) {
+    if (checkInputManagerUnitialized(env)) {
+        return NULL;
+    }
+
+    Vector<int> deviceIds;
+    gNativeInputManager->getInputManager()->getInputDeviceIds(deviceIds);
+
+    jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
+    if (! deviceIdsObj) {
+        return NULL;
+    }
+
+    env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
+    return deviceIdsObj;
+}
+
 static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
     if (checkInputManagerUnitialized(env)) {
         return NULL;
@@ -2242,6 +2371,10 @@
             (void*) android_server_InputManager_nativeSetInputDispatchMode },
     { "nativePreemptInputDispatch", "()V",
             (void*) android_server_InputManager_nativePreemptInputDispatch },
+    { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
+            (void*) android_server_InputManager_nativeGetInputDevice },
+    { "nativeGetInputDeviceIds", "()[I",
+            (void*) android_server_InputManager_nativeGetInputDeviceIds },
     { "nativeDump", "()Ljava/lang/String;",
             (void*) android_server_InputManager_nativeDump },
 };
@@ -2311,6 +2444,10 @@
             "getVirtualKeyDefinitions",
             "(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
 
+    GET_METHOD_ID(gCallbacksClassInfo.getInputDeviceCalibration, gCallbacksClassInfo.clazz,
+            "getInputDeviceCalibration",
+            "(Ljava/lang/String;)Lcom/android/server/InputManager$InputDeviceCalibration;");
+
     GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
             "getExcludedDeviceNames", "()[Ljava/lang/String;");
 
@@ -2337,6 +2474,17 @@
     GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
             "height", "I");
 
+    // InputDeviceCalibration
+
+    FIND_CLASS(gInputDeviceCalibrationClassInfo.clazz,
+            "com/android/server/InputManager$InputDeviceCalibration");
+
+    GET_FIELD_ID(gInputDeviceCalibrationClassInfo.keys, gInputDeviceCalibrationClassInfo.clazz,
+            "keys", "[Ljava/lang/String;");
+
+    GET_FIELD_ID(gInputDeviceCalibrationClassInfo.values, gInputDeviceCalibrationClassInfo.clazz,
+            "values", "[Ljava/lang/String;");
+
     // InputWindow
 
     FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
@@ -2407,10 +2555,35 @@
 
     FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
 
-    // MotionEVent
+    // MotionEvent
 
     FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
 
+    // InputDevice
+
+    FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
+
+    GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
+            "<init>", "()V");
+
+    GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
+            "addMotionRange", "(IFFFF)V");
+
+    GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
+            "mId", "I");
+
+    GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
+            "mName", "Ljava/lang/String;");
+
+    GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
+            "mSources", "I");
+
+    GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
+            "mKeyboardType", "I");
+
+    GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
+            "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
+
     return 0;
 }
 
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index b0fa0f5..4f2d90f 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1374,7 +1374,7 @@
         PhoneNumberUtil util = PhoneNumberUtil.getInstance();
         String result = null;
         try {
-            PhoneNumber pn = util.parse(phoneNumber, defaultCountryIso);
+            PhoneNumber pn = util.parseAndKeepRawInput(phoneNumber, defaultCountryIso);
             result = util.formatInOriginalFormat(pn, defaultCountryIso);
         } catch (NumberParseException e) {
         }
@@ -1382,6 +1382,50 @@
     }
 
     /**
+     * Format the phone number only if the given number hasn't been formatted.
+     * <p>
+     * The number which has only dailable character is treated as not being
+     * formatted.
+     *
+     * @param phoneNumber
+     *            the number to be formatted.
+     * @param phoneNumberE164
+     *            the E164 format number whose country code is used if the given
+     *            phoneNumber doesn't have the country code.
+     * @param defaultCountryIso
+     *            the ISO 3166-1 two letters country code whose convention will
+     *            be used if the phoneNumberE164 is null or invalid.
+     * @return the formatted number if the given number has been formatted,
+     *            otherwise, return the given number.
+     *
+     * @hide
+     */
+    public static String formatNumber(
+            String phoneNumber, String phoneNumberE164, String defaultCountryIso) {
+        int len = phoneNumber.length();
+        for (int i = 0; i < len; i++) {
+            if (!isDialable(phoneNumber.charAt(i))) {
+                return phoneNumber;
+            }
+        }
+        PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+        // Get the country code from phoneNumberE164
+        if (phoneNumberE164 != null && phoneNumberE164.length() >= 2
+                && phoneNumberE164.charAt(0) == '+') {
+            try {
+                PhoneNumber pn = util.parse(phoneNumberE164, defaultCountryIso);
+                String regionCode = util.getRegionCodeForNumber(pn);
+                if (!TextUtils.isEmpty(regionCode)) {
+                    defaultCountryIso = regionCode;
+                }
+            } catch (NumberParseException e) {
+            }
+        }
+        String result = formatNumber(phoneNumber, defaultCountryIso);
+        return result != null ? result : phoneNumber;
+    }
+
+    /**
      * Normalize a phone number by removing the characters other than digits. If
      * the given number has keypad letters, the letters will be converted to
      * digits first.
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index 12df44e..c1232e8 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -1108,14 +1108,21 @@
      */
 
     /**
-     * @return list of ringing calls
+     * @return list of all ringing calls
      */
     public ArrayList<Call> getRingingCalls() {
         return mRingingCalls;
     }
 
     /**
-     * @return list of background calls
+     * @return list of all foreground calls
+     */
+    public ArrayList<Call> getForegroundCalls() {
+        return mForegroundCalls;
+    }
+
+    /**
+     * @return list of all background calls
      */
     public ArrayList<Call> getBackgroundCalls() {
         return mBackgroundCalls;
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 7e722cb..521d90c 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -21,7 +21,7 @@
 import com.android.internal.util.HierarchicalState;
 import com.android.internal.util.HierarchicalStateMachine;
 
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.os.AsyncResult;
 import android.os.Message;
 import android.os.SystemProperties;
@@ -261,7 +261,7 @@
     protected int mTag;
     protected PhoneBase phone;
     protected int cid;
-    protected NetworkProperties mNetworkProperties = new NetworkProperties();
+    protected LinkProperties mLinkProperties = new LinkProperties();
     protected long createTime;
     protected long lastFailTime;
     protected FailCause lastFailCause;
@@ -378,7 +378,7 @@
         this.lastFailTime = -1;
         this.lastFailCause = FailCause.NONE;
 
-        mNetworkProperties.clear();
+        mLinkProperties = new LinkProperties();
     }
 
     /**
@@ -416,7 +416,7 @@
 
             // Start with clean network properties and if we have
             // a failure we'll clear again at the bottom of this code.
-            mNetworkProperties.clear();
+            LinkProperties linkProperties = new LinkProperties();
             if (response.length >= 2) {
                 cid = Integer.parseInt(response[0]);
                 String interfaceName = response[1];
@@ -425,23 +425,23 @@
                 try {
                     String prefix = "net." + interfaceName + ".";
 
-                    mNetworkProperties.setInterface(NetworkInterface.getByName(interfaceName));
+                    linkProperties.setInterface(NetworkInterface.getByName(interfaceName));
 
                     // TODO: Get gateway and dns via RIL interface not property?
                     String gatewayAddress = SystemProperties.get(prefix + "gw");
-                    mNetworkProperties.setGateway(InetAddress.getByName(gatewayAddress));
+                    linkProperties.setGateway(InetAddress.getByName(gatewayAddress));
 
                     if (response.length > 2) {
                         String ipAddress = response[2];
-                        mNetworkProperties.addAddress(InetAddress.getByName(ipAddress));
+                        linkProperties.addAddress(InetAddress.getByName(ipAddress));
 
                         // TODO: Get gateway and dns via RIL interface not property?
                         String dnsServers[] = new String[2];
                         dnsServers[0] = SystemProperties.get(prefix + "dns1");
                         dnsServers[1] = SystemProperties.get(prefix + "dns2");
                         if (isDnsOk(dnsServers)) {
-                            mNetworkProperties.addDns(InetAddress.getByName(dnsServers[0]));
-                            mNetworkProperties.addDns(InetAddress.getByName(dnsServers[1]));
+                            linkProperties.addDns(InetAddress.getByName(dnsServers[0]));
+                            linkProperties.addDns(InetAddress.getByName(dnsServers[1]));
                         } else {
                             result = SetupResult.ERR_BadDns;
                         }
@@ -463,15 +463,16 @@
 
             // An error occurred so clear properties
             if (result != SetupResult.SUCCESS) {
-                log("onSetupCompleted with an error clearing NetworkProperties");
-                mNetworkProperties.clear();
+                log("onSetupCompleted with an error clearing LinkProperties");
+                linkProperties.clear();
             }
+            mLinkProperties = linkProperties;
         }
 
         if (DBG) {
             log("DataConnection setup result='" + result + "' on cid=" + cid);
             if (result == SetupResult.SUCCESS) {
-                log("NetworkProperties: " + mNetworkProperties.toString());
+                log("LinkProperties: " + mLinkProperties.toString());
             }
         }
         return result;
@@ -636,7 +637,7 @@
                         case ERR_BadDns:
                             // Connection succeeded but DNS info is bad so disconnect
                             StringBuilder dnsAddressesSb = new StringBuilder();
-                            for (InetAddress addr : mNetworkProperties.getDnses()) {
+                            for (InetAddress addr : mLinkProperties.getDnses()) {
                                 if (dnsAddressesSb.length() != 0) dnsAddressesSb.append(" ");
                                 dnsAddressesSb.append(addr.toString());
                             }
@@ -911,10 +912,10 @@
     }
 
     /**
-     * @return the connections NetworkProperties
+     * @return the connections LinkProperties
      */
-    public NetworkProperties getNetworkProperties() {
-        return mNetworkProperties;
+    public LinkProperties getLinkProperties() {
+        return new LinkProperties(mLinkProperties);
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 14cb584..765f64b 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -17,7 +17,7 @@
 package com.android.internal.telephony;
 
 import android.app.PendingIntent;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
@@ -192,8 +192,8 @@
     /** indication of our availability (preconditions to trysetupData are met) **/
     protected boolean mAvailability = false;
 
-    /** all our network properties (dns, gateway, ip, etc) */
-    protected NetworkProperties mNetworkProperties;
+    /** all our link properties (dns, gateway, ip, etc) */
+    protected LinkProperties mLinkProperties;
 
     /**
      * Default constructor
@@ -420,10 +420,10 @@
 
     protected abstract void setState(State s);
 
-    protected NetworkProperties getNetworkProperties(String apnType) {
+    protected LinkProperties getLinkProperties(String apnType) {
         int id = apnTypeToId(apnType);
         if (isApnIdEnabled(id)) {
-            return mNetworkProperties;
+            return new LinkProperties(mLinkProperties);
         } else {
             return null;
         }
@@ -673,7 +673,7 @@
         }
     }
 
-    protected NetworkProperties getNetworkProperties(DataConnection connection) {
-        return connection.getNetworkProperties();
+    protected LinkProperties getLinkProperties(DataConnection connection) {
+        return connection.getLinkProperties();
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index 382c19f..bf3c4d1 100644
--- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -108,9 +108,9 @@
         // use apnType as the key to which connection we're talking about.
         // pass apnType back up to fetch particular for this one.
         TelephonyManager telephony = TelephonyManager.getDefault();
-        NetworkProperties networkProperties = null;
+        LinkProperties linkProperties = null;
         if (state == Phone.DataState.CONNECTED) {
-            networkProperties = sender.getNetworkProperties(apnType);
+            linkProperties = sender.getLinkProperties(apnType);
         }
         try {
             mRegistry.notifyDataConnection(
@@ -118,7 +118,7 @@
                     sender.isDataConnectivityPossible(), reason,
                     sender.getActiveApn(),
                     apnType,
-                    networkProperties,
+                    linkProperties,
                     ((telephony!=null) ? telephony.getNetworkType() :
                     TelephonyManager.NETWORK_TYPE_UNKNOWN));
         } catch (RemoteException ex) {
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index f7b70ee..eb7e566 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -17,7 +17,7 @@
 package com.android.internal.telephony;
 
 import android.content.Intent;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.os.Bundle;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
@@ -33,7 +33,7 @@
     void notifyCallForwardingChanged(boolean cfi);
     void notifyDataActivity(int state);
     void notifyDataConnection(int state, boolean isDataConnectivityPossible,
-            String reason, String apn, String apnType, in NetworkProperties networkProperties,
+            String reason, String apn, String apnType, in LinkProperties linkProperties,
             int networkType);
     void notifyDataConnectionFailed(String reason, String apnType);
     void notifyCellLocation(in Bundle cellLocation);
diff --git a/telephony/java/com/android/internal/telephony/IccConstants.java b/telephony/java/com/android/internal/telephony/IccConstants.java
index acc9197..b12d2d4 100644
--- a/telephony/java/com/android/internal/telephony/IccConstants.java
+++ b/telephony/java/com/android/internal/telephony/IccConstants.java
@@ -52,6 +52,7 @@
     static final int EF_SPN_CPHS = 0x6f14;
     static final int EF_SPN_SHORT_CPHS = 0x6f18;
     static final int EF_INFO_CPHS = 0x6f16;
+    static final int EF_CSP_CPHS = 0x6f15;
 
     // CDMA RUIM file ids from 3GPP2 C.S0023-0
     static final int EF_CST = 0x6f32;
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 109b4b9..fffe057 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -17,7 +17,7 @@
 package com.android.internal.telephony;
 
 import android.content.Context;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.os.Handler;
 import android.os.Message;
 import android.telephony.CellLocation;
@@ -99,7 +99,7 @@
     static final String STATE_CHANGE_REASON_KEY = "reason";
     static final String DATA_APN_TYPE_KEY = "apnType";
     static final String DATA_APN_KEY = "apn";
-    static final String DATA_NETWORK_PROPERTIES_KEY = "dataProperties";
+    static final String DATA_LINK_PROPERTIES_KEY = "linkProperties";
 
     static final String DATA_IFACE_NAME_KEY = "iface";
     static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
@@ -319,9 +319,9 @@
     String getActiveApn();
 
     /**
-     * Return the NetworkProperties for the named apn or null if not available
+     * Return the LinkProperties for the named apn or null if not available
      */
-    NetworkProperties getNetworkProperties(String apnType);
+    LinkProperties getLinkProperties(String apnType);
 
     /**
      * Get current signal strength. No change notification available on this
@@ -1703,4 +1703,15 @@
     void unsetOnEcbModeExitResponse(Handler h);
 
 
+    /**
+     * TODO: Adding a function for each property is not good.
+     * A fucntion of type getPhoneProp(propType) where propType is an
+     * enum of GSM+CDMA+LTE props would be a better approach.
+     *
+     * Get "Restriction of menu options for manual PLMN selection" bit
+     * status from EF_CSP data, this belongs to "Value Added Services Group".
+     * @return true if this bit is set or EF_CSP data is unavailable,
+     * false otherwise
+     */
+    boolean isCspPlmnEnabled();
 }
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 27e1cb3..78ce473 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -21,7 +21,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.SharedPreferences;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.net.wifi.WifiManager;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -285,7 +285,7 @@
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
         SharedPreferences.Editor editor = sp.edit();
         editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
-        editor.commit();
+        editor.apply();
     }
 
     /**
@@ -938,8 +938,8 @@
         return mDataConnection.getActiveApnTypes();
     }
 
-    public NetworkProperties getNetworkProperties(String apnType) {
-        return mDataConnection.getNetworkProperties(apnType);
+    public LinkProperties getLinkProperties(String apnType) {
+        return mDataConnection.getLinkProperties(apnType);
     }
 
     public String getActiveApn() {
@@ -1024,6 +1024,13 @@
         }
     }
 
+    public boolean isCspPlmnEnabled() {
+        // This function should be overridden by the class GSMPhone.
+        // Not implemented in CDMAPhone.
+        logUnexpectedGsmMethodCall("isCspPlmnEnabled");
+        return false;
+    }
+
     /**
      * Common error logger method for unexpected calls to CDMA-only methods.
      */
@@ -1036,4 +1043,12 @@
     public DataState getDataConnectionState() {
         return getDataConnectionState(APN_TYPE_DEFAULT);
     }
+
+    /**
+     * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
+     */
+    private void logUnexpectedGsmMethodCall(String name) {
+        Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
+                "called, GSMPhone inactive.");
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index c10596d..b6e4cda 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -20,7 +20,7 @@
 import android.app.ActivityManagerNative;
 import android.content.Context;
 import android.content.Intent;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemProperties;
@@ -208,8 +208,8 @@
         return mActivePhone.getActiveApnTypes();
     }
 
-    public NetworkProperties getNetworkProperties(String apnType) {
-        return mActivePhone.getNetworkProperties(apnType);
+    public LinkProperties getLinkProperties(String apnType) {
+        return mActivePhone.getLinkProperties(apnType);
     }
 
     public String getActiveApn() {
@@ -832,4 +832,8 @@
     public void unsetOnEcbModeExitResponse(Handler h){
         mActivePhone.unsetOnEcbModeExitResponse(h);
     }
+
+    public boolean isCspPlmnEnabled() {
+        return mActivePhone.isCspPlmnEnabled();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/SipPhoneNotifier.java b/telephony/java/com/android/internal/telephony/SipPhoneNotifier.java
index 1229d14..30d06d8 100644
--- a/telephony/java/com/android/internal/telephony/SipPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/SipPhoneNotifier.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -110,9 +110,9 @@
         // use apnType as the key to which connection we're talking about.
         // pass apnType back up to fetch particular for this one.
         TelephonyManager telephony = TelephonyManager.getDefault();
-        NetworkProperties networkProperties = null;
+        LinkProperties linkProperties = null;
         if (state == Phone.DataState.CONNECTED) {
-            networkProperties = sender.getNetworkProperties(apnType);
+            linkProperties = sender.getLinkProperties(apnType);
         }
         try {
             mRegistry.notifyDataConnection(
@@ -120,7 +120,7 @@
                     sender.isDataConnectivityPossible(), reason,
                     sender.getActiveApn(),
                     apnType,
-                    networkProperties,
+                    linkProperties,
                     ((telephony!=null) ? telephony.getNetworkType() :
                     TelephonyManager.NETWORK_TYPE_UNKNOWN));
         } catch (RemoteException ex) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 8d77f76..47a170a 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -1406,7 +1406,7 @@
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
         SharedPreferences.Editor editor = sp.edit();
         editor.putString(VM_NUMBER_CDMA, number);
-        editor.commit();
+        editor.apply();
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index c94cfa4..5918245 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -732,7 +732,7 @@
         }
 
         if (ar.exception == null) {
-            mNetworkProperties = getNetworkProperties(mActiveDataConnection);
+            mLinkProperties = getLinkProperties(mActiveDataConnection);
 
             // everything is setup
             notifyDefaultData(reason);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 53d0f20..37a33bc 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -129,7 +129,7 @@
                     mPhone.getContext());
             SharedPreferences.Editor editor = sp.edit();
             editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount);
-            editor.commit();
+            editor.apply();
             ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount);
             handled = true;
         } else if (((SmsEnvelope.TELESERVICE_WMT == teleService) ||
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index 2ae5a3c..d64541b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -809,7 +809,7 @@
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
         SharedPreferences.Editor editor = sp.edit();
         editor.putString(VM_NUMBER, number);
-        editor.commit();
+        editor.apply();
         setVmSimImsi(getSubscriberId());
     }
 
@@ -832,7 +832,7 @@
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
         SharedPreferences.Editor editor = sp.edit();
         editor.putString(VM_SIM_IMSI, imsi);
-        editor.commit();
+        editor.apply();
     }
 
     public String getVoiceMailAlphaTag() {
@@ -1467,4 +1467,7 @@
         Log.e(LOG_TAG, "Error! This functionality is not implemented for GSM.");
     }
 
+    public boolean isCspPlmnEnabled() {
+        return mSIMRecords.isCspPlmnEnabled();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index face581..4414460 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -1098,7 +1098,7 @@
         }
 
         if (ar.exception == null) {
-            mNetworkProperties = getNetworkProperties(mActivePdp);
+            mLinkProperties = getLinkProperties(mActivePdp);
 
             ApnSetting apn = mActivePdp.getApn();
             if (apn.proxy != null && apn.proxy.length() != 0) {
@@ -1106,7 +1106,7 @@
                     ProxyProperties proxy = new ProxyProperties();
                     proxy.setAddress(InetAddress.getByName(apn.proxy));
                     proxy.setPort(Integer.parseInt(apn.port));
-                    mNetworkProperties.setHttpProxy(proxy);
+                    mLinkProperties.setHttpProxy(proxy);
                 } catch (UnknownHostException e) {
                     Log.e(LOG_TAG, "UnknownHostException making ProxyProperties: " + e);
                 } catch (SecurityException e) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
index 206e62f..e8d10f9 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
@@ -81,6 +81,7 @@
         case EF_SPN_CPHS:
         case EF_SPN_SHORT_CPHS:
         case EF_INFO_CPHS:
+        case EF_CSP_CPHS:
             return MF_SIM + DF_GSM;
 
         case EF_PBR:
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 30f38bd..c80c608 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -73,6 +73,7 @@
      *  mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table
      */
     private byte[] mCphsInfo = null;
+    boolean mCspPlmnEnabled = true;
 
     byte[] efMWIS = null;
     byte[] efCPHS_MWI =null;
@@ -141,6 +142,7 @@
     private static final int EVENT_SET_MSISDN_DONE = 30;
     private static final int EVENT_SIM_REFRESH = 31;
     private static final int EVENT_GET_CFIS_DONE = 32;
+    private static final int EVENT_GET_CSP_CPHS_DONE = 33;
 
     // ***** Constructor
 
@@ -1002,6 +1004,22 @@
                 ((GSMPhone) phone).notifyCallForwardingIndicator();
                 break;
 
+            case EVENT_GET_CSP_CPHS_DONE:
+                isRecordLoadResponse = true;
+
+                ar = (AsyncResult)msg.obj;
+
+                if (ar.exception != null) {
+                    Log.e(LOG_TAG,"Exception in fetching EF_CSP data " + ar.exception);
+                    break;
+                }
+
+                data = (byte[])ar.result;
+
+                Log.i(LOG_TAG,"EF_CSP: " + IccUtils.bytesToHexString(data));
+                handleEfCspData(data);
+                break;
+
         }}catch (RuntimeException exc) {
             // I don't want these exceptions to be fatal
             Log.w(LOG_TAG, "Exception parsing SIM record", exc);
@@ -1025,6 +1043,12 @@
                 new AdnRecordLoader(phone).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1,
                         1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
                 break;
+            case EF_CSP_CPHS:
+                recordsToLoad++;
+                Log.i(LOG_TAG, "[CSP] SIM Refresh for EF_CSP_CPHS");
+                phone.getIccFileHandler().loadEFTransparent(EF_CSP_CPHS,
+                        obtainMessage(EVENT_GET_CSP_CPHS_DONE));
+                break;
             default:
                 // For now, fetch all records if this is not a
                 // voicemail number.
@@ -1255,6 +1279,9 @@
         iccFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
         recordsToLoad++;
 
+        iccFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));
+        recordsToLoad++;
+
         // XXX should seek instead of examining them all
         if (false) { // XXX
             iccFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
@@ -1476,4 +1503,53 @@
         Log.d(LOG_TAG, "[SIMRecords] " + s);
     }
 
+    /**
+     * Return true if "Restriction of menu options for manual PLMN selection"
+     * bit is set or EF_CSP data is unavailable, return false otherwise.
+     */
+    public boolean isCspPlmnEnabled() {
+        return mCspPlmnEnabled;
+    }
+
+    /**
+     * Parse EF_CSP data and check if
+     * "Restriction of menu options for manual PLMN selection" is
+     * Enabled/Disabled
+     *
+     * @param data EF_CSP hex data.
+     */
+    private void handleEfCspData(byte[] data) {
+        // As per spec CPHS4_2.WW6, CPHS B.4.7.1, EF_CSP contains CPHS defined
+        // 18 bytes (i.e 9 service groups info) and additional data specific to
+        // operator. The valueAddedServicesGroup is not part of standard
+        // services. This is operator specific and can be programmed any where.
+        // Normally this is programmed as 10th service after the standard
+        // services.
+        int usedCspGroups = data.length / 2;
+        // This is the "Servive Group Number" of "Value Added Services Group".
+        byte valueAddedServicesGroup = (byte)0xC0;
+
+        mCspPlmnEnabled = true;
+        for (int i = 0; i < usedCspGroups; i++) {
+             if (data[2 * i] == valueAddedServicesGroup) {
+                 Log.i(LOG_TAG, "[CSP] found ValueAddedServicesGroup, value "
+                       + data[(2 * i) + 1]);
+                 if ((data[(2 * i) + 1] & 0x80) == 0x80) {
+                     // Bit 8 is for
+                     // "Restriction of menu options for manual PLMN selection".
+                     // Operator Selection menu should be enabled.
+                     mCspPlmnEnabled = true;
+                 } else {
+                     mCspPlmnEnabled = false;
+                     // Operator Selection menu should be disabled.
+                     // Operator Selection Mode should be set to Automatic.
+                     Log.i(LOG_TAG,"[CSP] Set Automatic Network Selection");
+                     phone.setNetworkSelectionModeAutomatic(null);
+                 }
+                 return;
+             }
+        }
+
+        Log.w(LOG_TAG, "[CSP] Value Added Service Group (0xC0), not found!");
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
index 1d33be9..e742887 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -19,7 +19,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -540,7 +540,7 @@
     }
 
     //@Override
-    public NetworkProperties getNetworkProperties(String apnType) {
+    public LinkProperties getLinkProperties(String apnType) {
         // FIXME: what's this for SIP?
         return null;
     }
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index 88aa78ef..c4a6f53 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -20,10 +20,6 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.SpannableStringBuilder;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.content.Context;
-
-import junit.framework.TestCase;
 
 public class PhoneNumberUtilsTest extends AndroidTestCase {
 
@@ -527,4 +523,16 @@
         assertEquals("+16502910000", PhoneNumberUtils.normalizeNumber("+1 650 2910000"));
     }
 
+    @SmallTest
+    public void testFormatDailabeNumber() {
+        // Using the phoneNumberE164's country code
+        assertEquals("(650) 291-0000",
+                PhoneNumberUtils.formatNumber("6502910000", "+16502910000", "CN"));
+        // The phoneNumberE164 is null
+        assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("6502910000", null, "US"));
+        // The given number has a country code.
+        assertEquals("+1 650-291-0000", PhoneNumberUtils.formatNumber("+16502910000", null, "CN"));
+        // The given number was formatted.
+        assertEquals("650-291-0000", PhoneNumberUtils.formatNumber("650-291-0000", null, "US"));
+    }
 }
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index e96173b..f0cbaa0 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -127,6 +127,12 @@
     }
 
     @Override
+    public ProviderInfo getProviderInfo(ComponentName className, int flags)
+    throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public List<PackageInfo> getInstalledPackages(int flags) {
         throw new UnsupportedOperationException();
     }
diff --git a/tests/DumpRenderTree2/AndroidManifest.xml b/tests/DumpRenderTree2/AndroidManifest.xml
index dd0c4e9f..b4dc190 100644
--- a/tests/DumpRenderTree2/AndroidManifest.xml
+++ b/tests/DumpRenderTree2/AndroidManifest.xml
@@ -35,7 +35,8 @@
              It can lead to some weird behaviour in the future. -->
         <activity android:name=".TestsListActivity"
                   android:label="Tests' list activity"
-                  android:launchMode="singleTask">
+                  android:launchMode="singleTask"
+                  android:configChanges="orientation">
         </activity>
 
         <activity android:name=".LayoutTestsExecutor"
diff --git a/tests/DumpRenderTree2/assets/run_apache2.py b/tests/DumpRenderTree2/assets/run_apache2.py
index 5764f0e..74ab850 100755
--- a/tests/DumpRenderTree2/assets/run_apache2.py
+++ b/tests/DumpRenderTree2/assets/run_apache2.py
@@ -76,6 +76,8 @@
   directives += " -c \"Alias /LayoutTests " + layout_tests_path + "\""
   directives += " -c \"Alias /WebKitTools/DumpRenderTree/android " + \
     os.path.join(webkit_path, "WebKitTools", "DumpRenderTree", "android") + "\""
+  directives += " -c \"Alias /WEBKIT_MERGE_REVISION " + \
+    os.path.join(webkit_path, "WEBKIT_MERGE_REVISION") + "\""
 
   # This directive is commented out in apache2-debian-httpd.conf for some reason
   # However, it is useful to browse through tests in the browser, so it's added here.
@@ -90,7 +92,8 @@
     "\""
   directives += " -c \"User ${APACHE_RUN_USER}\""
   directives += " -c \"Group ${APACHE_RUN_GROUP}\""
-  directives += " -C \"TypesConfig " + os.path.join("/etc", "mime.types") + "\""
+  directives += " -C \"TypesConfig " + \
+    os.path.join(android_tree_root, http_conf_path, "mime.types") + "\""
   conf_file_cmd = " -f " + \
     os.path.join(android_tree_root, http_conf_path, "apache2-debian-httpd.conf")
 
diff --git a/tests/DumpRenderTree2/res/menu/gui_menu.xml b/tests/DumpRenderTree2/res/menu/gui_menu.xml
new file mode 100644
index 0000000..a5b2b65
--- /dev/null
+++ b/tests/DumpRenderTree2/res/menu/gui_menu.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/run_all"
+          android:title="@string/run_all_tests" />
+</menu>
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/res/values/strings.xml b/tests/DumpRenderTree2/res/values/strings.xml
index 5fd1eb9..0496404 100644
--- a/tests/DumpRenderTree2/res/values/strings.xml
+++ b/tests/DumpRenderTree2/res/values/strings.xml
@@ -25,4 +25,6 @@
     <string name="dialog_progress_msg">Please wait...</string>
 
     <string name="runner_preloading_title">Preloading tests...</string>
+
+    <string name="run_all_tests">Run all tests in the current directory</string>
 </resources>
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
index d68930c..7cbb397 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
@@ -92,8 +92,16 @@
 
     public abstract void setExpectedImageResult(byte[] expectedResult);
 
+    public abstract void setExpectedImageResultPath(String relativePath);
+
+    public abstract String getExpectedImageResultPath();
+
     public abstract void setExpectedTextResult(String expectedResult);
 
+    public abstract void setExpectedTextResultPath(String relativePath);
+
+    public abstract String getExpectedTextResultPath();
+
     /**
      * Returns result's image data that can be written to the disk. It can be null
      * if there is an error of some sort or for example the test times out.
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/CrashedDummyResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/CrashedDummyResult.java
index a793dab..31da776 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/CrashedDummyResult.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/CrashedDummyResult.java
@@ -22,6 +22,8 @@
 
 /**
  * A dummy class representing test that crashed.
+ *
+ * TODO: All the methods regarding expected results need implementing.
  */
 public class CrashedDummyResult extends AbstractResult {
     String mRelativePath;
@@ -82,4 +84,26 @@
     public void setExpectedTextResult(String expectedResult) {
         /** TODO */
     }
+
+    @Override
+    public String getExpectedImageResultPath() {
+        /** TODO */
+        return null;
+    }
+
+    @Override
+    public String getExpectedTextResultPath() {
+        /** TODO */
+        return null;
+    }
+
+    @Override
+    public void setExpectedImageResultPath(String relativePath) {
+        /** TODO */
+    }
+
+    @Override
+    public void setExpectedTextResultPath(String relativePath) {
+        /** TODO */
+    }
 }
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
index bcc8564..4ab76e3 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
@@ -18,11 +18,18 @@
 
 import android.util.Log;
 
+import com.android.dumprendertree2.forwarder.ForwarderManager;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -38,12 +45,15 @@
     private static final String TEST_EXPECTATIONS_TXT_PATH =
             "platform/android/test_expectations.txt";
 
-    private static final String TOKEN_SKIP = "SKIP";
-    private static final String TOKEN_IGNORE_RESULT = "IGNORE_RESULT";
+    private static final String HTTP_TESTS_PATH = "http/tests/";
+    private static final String SSL_PATH = "ssl/";
+
+    private static final String TOKEN_CRASH = "CRASH";
+    private static final String TOKEN_FAIL = "FAIL";
     private static final String TOKEN_SLOW = "SLOW";
 
-    private final Set<String> mSkipList = new HashSet<String>();
-    private final Set<String> mIgnoreResultList = new HashSet<String>();
+    private final Set<String> mCrashList = new HashSet<String>();
+    private final Set<String> mFailList = new HashSet<String>();
     private final Set<String> mSlowList = new HashSet<String>();
 
     private final String mRootDirPath;
@@ -52,7 +62,7 @@
         /** It may or may not contain a trailing slash */
         this.mRootDirPath = rootDirPath;
 
-        reloadConfiguration();
+        loadTestExpectations();
     }
 
     private static final String trimTrailingSlashIfPresent(String path) {
@@ -60,79 +70,88 @@
         return file.getPath();
     }
 
-    public void reloadConfiguration() {
-        File txt_exp = new File(mRootDirPath, TEST_EXPECTATIONS_TXT_PATH);
-
-        BufferedReader bufferedReader;
+    public void loadTestExpectations() {
+        URL url = null;
         try {
-            bufferedReader =
-                    new BufferedReader(new FileReader(txt_exp));
+            url = new URL(ForwarderManager.getHostSchemePort(false) + "LayoutTests/" +
+                    TEST_EXPECTATIONS_TXT_PATH);
+        } catch (MalformedURLException e) {
+            assert false;
+        }
 
-            String line;
-            String entry;
-            String[] parts;
-            String path;
-            Set<String> tokens;
-            Boolean skipped;
-            while (true) {
-                line = bufferedReader.readLine();
-                if (line == null) {
-                    break;
+        try {
+            InputStream inputStream = null;
+            BufferedReader bufferedReader = null;
+            try {
+                bufferedReader = new BufferedReader(new StringReader(new String(
+                        FsUtils.readDataFromUrl(url))));
+
+                String line;
+                String entry;
+                String[] parts;
+                String path;
+                Set<String> tokens;
+                while (true) {
+                    line = bufferedReader.readLine();
+                    if (line == null) {
+                        break;
+                    }
+
+                    /** Remove the comment and trim */
+                    entry = line.split("//", 2)[0].trim();
+
+                    /** Omit empty lines, advance to next line */
+                    if (entry.isEmpty()) {
+                        continue;
+                    }
+
+                    /** Split on whitespace into path part and the rest */
+                    parts = entry.split("\\s", 2);
+
+                    /** At this point parts.length >= 1 */
+                    if (parts.length == 1) {
+                        Log.w(LOG_TAG + "::reloadConfiguration",
+                                "There are no options specified for the test!");
+                        continue;
+                    }
+
+                    path = trimTrailingSlashIfPresent(parts[0]);
+
+                    /** Split on whitespace */
+                    tokens = new HashSet<String>(Arrays.asList(parts[1].split("\\s", 0)));
+
+                    /** Chose the right collections to add to */
+                    if (tokens.contains(TOKEN_CRASH)) {
+                        mCrashList.add(path);
+
+                        /** If test is on skip list we ignore any further options */
+                        continue;
+                    }
+
+                    if (tokens.contains(TOKEN_FAIL)) {
+                        mFailList.add(path);
+                    }
+                    if (tokens.contains(TOKEN_SLOW)) {
+                        mSlowList.add(path);
+                    }
                 }
-
-                /** Remove the comment and trim */
-                entry = line.split("//", 2)[0].trim();
-
-                /** Omit empty lines, advance to next line */
-                if (entry.isEmpty()) {
-                    continue;
+            } finally {
+                if (inputStream != null) {
+                    inputStream.close();
                 }
-
-                /** Split on whitespace into path part and the rest */
-                parts = entry.split("\\s", 2);
-
-                /** At this point parts.length >= 1 */
-                if (parts.length == 1) {
-                    Log.w(LOG_TAG + "::reloadConfiguration",
-                            "There are no options specified for the test!");
-                    continue;
-                }
-
-                path = trimTrailingSlashIfPresent(parts[0]);
-
-                /** Split on whitespace */
-                tokens = new HashSet<String>(Arrays.asList(parts[1].split("\\s", 0)));
-
-                /** Chose the right collections to add to */
-                skipped = false;
-                if (tokens.contains(TOKEN_SKIP)) {
-                    mSkipList.add(path);
-                    skipped = true;
-                }
-
-                /** If test is on skip list we ignore any further options */
-                if (skipped) {
-                    continue;
-                }
-
-                if (tokens.contains(TOKEN_IGNORE_RESULT)) {
-                    mIgnoreResultList.add(path);
-                }
-
-                if (tokens.contains(TOKEN_SLOW)) {
-                    mSlowList.add(path);
+                if (bufferedReader != null) {
+                    bufferedReader.close();
                 }
             }
         } catch (FileNotFoundException e) {
-            Log.w(LOG_TAG, "mRootDirPath=" + mRootDirPath + ": File not found: " +
-                    txt_exp.getPath(), e);
+            Log.w(LOG_TAG, "reloadConfiguration(): File not found: " + e.getMessage());
         } catch (IOException e) {
-            Log.e(LOG_TAG, "mRootDirPath=" + mRootDirPath, e);
+            Log.e(LOG_TAG, "url=" + url, e);
         }
     }
 
     /**
-     * Checks if test is supposed to be skipped.
+     * Checks if test is expected to crash.
      *
      * <p>
      * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
@@ -141,9 +160,9 @@
      *            - a relative path within LayoutTests folder
      * @return if the test is supposed to be skipped
      */
-    public boolean isSkip(String testPath) {
+    public boolean isCrash(String testPath) {
         for (String prefix : getPrefixes(testPath)) {
-            if (mSkipList.contains(prefix)) {
+            if (mCrashList.contains(prefix)) {
                 return true;
             }
         }
@@ -152,18 +171,18 @@
     }
 
     /**
-     * Checks if test result is supposed to be ignored.
+     * Checks if test result is supposed to be "failed".
      *
      * <p>
      * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
      *
      * @param testPath
      *            - a relative path within LayoutTests folder
-     * @return if the test result is supposed to be ignored
+     * @return if the test result is supposed to be "failed"
      */
-    public boolean isIgnoreRes(String testPath) {
+    public boolean isFail(String testPath) {
         for (String prefix : getPrefixes(testPath)) {
-            if (mIgnoreResultList.contains(prefix)) {
+            if (mFailList.contains(prefix)) {
                 return true;
             }
         }
@@ -237,6 +256,37 @@
     }
 
     /**
+     * Return a URL of the test on the server.
+     *
+     * @param relativePath
+     * @return a URL of the test on the server
+     */
+    public static URL getUrl(String relativePath) {
+        String urlBase = ForwarderManager.getHostSchemePort(false);
+
+        /**
+         * URL is formed differently for HTTP vs non-HTTP tests, because HTTP tests
+         * expect different document root. See run_apache2.py and .conf file for details
+         */
+        if (relativePath.startsWith(HTTP_TESTS_PATH)) {
+            relativePath = relativePath.substring(HTTP_TESTS_PATH.length());
+            if (relativePath.startsWith(SSL_PATH)) {
+                urlBase = ForwarderManager.getHostSchemePort(true);
+            }
+        } else {
+            relativePath = "LayoutTests/" + relativePath;
+        }
+
+        try {
+            return new URL(urlBase + relativePath);
+        } catch (MalformedURLException e) {
+            Log.e(LOG_TAG, "Malformed URL!", e);
+        }
+
+        return null;
+    }
+
+    /**
      * Return the path to the file relative to the tests root dir
      *
      * @param filePath
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FsUtils.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/FsUtils.java
index 0cfe69d..4202668 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FsUtils.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/FsUtils.java
@@ -18,11 +18,23 @@
 
 import android.util.Log;
 
+import com.android.dumprendertree2.forwarder.ForwarderManager;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  *
@@ -30,6 +42,9 @@
 public class FsUtils {
     public static final String LOG_TAG = "FsUtils";
 
+    private static final String SCRIPT_URL = ForwarderManager.getHostSchemePort(false) +
+            "WebKitTools/DumpRenderTree/android/get_layout_tests_dir_contents.php";
+
     public static void writeDataToStorage(File file, byte[] bytes, boolean append) {
         Log.d(LOG_TAG, "writeDataToStorage(): " + file.getAbsolutePath());
         try {
@@ -37,7 +52,7 @@
             try {
                 file.getParentFile().mkdirs();
                 file.createNewFile();
-                Log.d(LOG_TAG, "writeDataToStorage(): File created.");
+                Log.d(LOG_TAG, "writeDataToStorage(): File created: " + file.getAbsolutePath());
                 outputStream = new FileOutputStream(file, append);
                 outputStream.write(bytes);
             } finally {
@@ -46,7 +61,8 @@
                 }
             }
         } catch (IOException e) {
-            Log.e(LOG_TAG, "file.getAbsolutePath=" + file.getAbsolutePath(), e);
+            Log.e(LOG_TAG, "file.getAbsolutePath=" + file.getAbsolutePath() + " append=" + append,
+                    e);
         }
     }
 
@@ -62,7 +78,7 @@
             FileInputStream fis = null;
             try {
                 fis = new FileInputStream(file);
-                bytes = new byte[(int) file.length()];
+                bytes = new byte[(int)file.length()];
                 fis.read(bytes);
             } finally {
                 if (fis != null) {
@@ -75,4 +91,89 @@
 
         return bytes;
     }
+
+    public static byte[] readDataFromUrl(URL url) {
+        if (url == null) {
+            Log.w(LOG_TAG, "readDataFromUrl(): url is null!");
+            return null;
+        }
+
+        byte[] bytes = null;
+        try {
+            InputStream inputStream = null;
+            ByteArrayOutputStream outputStream = null;
+            try {
+                URLConnection urlConnection = url.openConnection();
+                inputStream = urlConnection.getInputStream();
+                outputStream = new ByteArrayOutputStream();
+
+                byte[] buffer = new byte[4096];
+                int length;
+                while ((length = inputStream.read(buffer)) > 0) {
+                    outputStream.write(buffer, 0, length);
+                }
+
+                bytes = outputStream.toByteArray();
+            } finally {
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+            }
+        } catch (FileNotFoundException e) {
+            Log.w(LOG_TAG, "readDataFromUrl(): File not found: " + e.getMessage());
+        } catch (IOException e) {
+            Log.e(LOG_TAG, "url=" + url, e);
+        }
+
+        return bytes;
+    }
+
+    public static List<String> getLayoutTestsDirContents(String dirRelativePath, boolean recurse,
+            boolean mode) {
+        String modeString = (mode ? "folders" : "files");
+
+        List<String> results = new LinkedList<String>();
+
+        URL url = null;
+        try {
+            url = new URL(SCRIPT_URL +
+                    "?path=" + dirRelativePath +
+                    "&recurse=" + recurse +
+                    "&mode=" + modeString);
+        } catch (MalformedURLException e) {
+            Log.e(LOG_TAG, "path=" + dirRelativePath + " recurse=" + recurse + " mode=" +
+                    modeString, e);
+            return results;
+        }
+
+        try {
+            InputStream inputStream = null;
+            BufferedReader bufferedReader = null;
+            try {
+                URLConnection urlConnection = url.openConnection();
+                inputStream = urlConnection.getInputStream();
+                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+
+                String relativePath;
+                while ((relativePath = bufferedReader.readLine()) != null) {
+                    results.add(relativePath);
+                }
+            } finally {
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+                if (bufferedReader != null) {
+                    bufferedReader.close();
+                }
+            }
+        } catch (IOException e) {
+            Log.e(LOG_TAG, "path=" + dirRelativePath + " recurse=" + recurse + " mode=" +
+                    modeString, e);
+        }
+
+        return results;
+    }
 }
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
index d17ec7c..0bd2302 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
@@ -29,6 +29,7 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.PowerManager.WakeLock;
 import android.util.Log;
@@ -44,6 +45,9 @@
 import android.webkit.WebStorage.QuotaUpdater;
 
 import java.io.File;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -254,6 +258,32 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        /**
+         * It detects the crash by catching all the uncaught exceptions. However, we
+         * still have to kill the process, because after catching the exception the
+         * activity remains in a strange state, where intents don't revive it.
+         * However, we send the message to the service to speed up the rebooting
+         * (we don't have to wait for time-out to kick in).
+         */
+        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
+            @Override
+            public void uncaughtException(Thread thread, Throwable e) {
+                Log.w(LOG_TAG,
+                        "onTestCrashed(): " + mCurrentTestRelativePath + " thread=" + thread, e);
+
+                try {
+                    Message serviceMsg =
+                            Message.obtain(null, ManagerService.MSG_CURRENT_TEST_CRASHED);
+
+                    mManagerServiceMessenger.send(serviceMsg);
+                } catch (RemoteException e2) {
+                    Log.e(LOG_TAG, "mCurrentTestRelativePath=" + mCurrentTestRelativePath, e2);
+                }
+
+                Process.killProcess(Process.myPid());
+            }
+        });
+
         requestWindowFeature(Window.FEATURE_PROGRESS);
 
         Intent intent = getIntent();
@@ -306,6 +336,8 @@
          */
         webView.setTouchInterval(-1);
 
+        webView.clearCache(true);
+
         WebSettings webViewSettings = webView.getSettings();
         webViewSettings.setAppCacheEnabled(true);
         webViewSettings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
@@ -353,10 +385,11 @@
         }
 
         mCurrentTestRelativePath = mTestsList.remove(0);
-        Log.d(LOG_TAG + "::runNextTest", "Start: " + mCurrentTestRelativePath +
-                "(" + mCurrentTestIndex + ")");
-        mCurrentTestUri =
-                Uri.fromFile(new File(TESTS_ROOT_DIR_PATH, mCurrentTestRelativePath)).toString();
+
+        Log.i(LOG_TAG, "runNextTest(): Start: " + mCurrentTestRelativePath +
+                " (" + mCurrentTestIndex + ")");
+
+        mCurrentTestUri = FileFilter.getUrl(mCurrentTestRelativePath).toString();
 
         reset();
 
@@ -607,4 +640,4 @@
         mCurrentWebView.setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta,
                 canProvideGamma, gamma);
     }
-}
\ No newline at end of file
+}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
index 951126f..d9da672 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
@@ -38,7 +38,7 @@
 
     private static final String LOG_TAG = "ManagerService";
 
-    private static final int MSG_TEST_CRASHED = 0;
+    private static final int MSG_CRASH_TIMEOUT_EXPIRED = 0;
 
     private static final int CRASH_TIMEOUT_MS = 20 * 1000;
 
@@ -72,6 +72,7 @@
     static final int MSG_PROCESS_ACTUAL_RESULTS = 0;
     static final int MSG_ALL_TESTS_FINISHED = 1;
     static final int MSG_FIRST_TEST = 2;
+    static final int MSG_CURRENT_TEST_CRASHED = 3;
 
     /**
      * This handler is purely for IPC. It is used to create mMessenger
@@ -92,6 +93,11 @@
                     onActualResultsObtained(msg.getData());
                     break;
 
+                case MSG_CURRENT_TEST_CRASHED:
+                    mCrashMessagesHandler.removeMessages(MSG_CRASH_TIMEOUT_EXPIRED);
+                    onTestCrashed();
+                    break;
+
                 case MSG_ALL_TESTS_FINISHED:
                     mSummarizer.setTestsRelativePath(mAllTestsRelativePath);
                     mSummarizer.summarize();
@@ -110,7 +116,7 @@
     private Handler mCrashMessagesHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
-            if (msg.what == MSG_TEST_CRASHED) {
+            if (msg.what == MSG_CRASH_TIMEOUT_EXPIRED) {
                 onTestCrashed();
             }
         }
@@ -122,6 +128,13 @@
     private String mCurrentlyRunningTest;
     private int mCurrentlyRunningTestIndex;
 
+    /**
+     * These are implementation details of getExpectedResultPath() used to reduce the number
+     * of requests required to the host server.
+     */
+    private String mLastExpectedResultPathRequested;
+    private String mLastExpectedResultPathFetched;
+
     private String mAllTestsRelativePath;
 
     @Override
@@ -145,7 +158,7 @@
     }
 
     private void onActualResultsObtained(Bundle bundle) {
-        mCrashMessagesHandler.removeMessages(MSG_TEST_CRASHED);
+        mCrashMessagesHandler.removeMessages(MSG_CRASH_TIMEOUT_EXPIRED);
         ensureNextTestSetup(bundle.getString("nextTest"), bundle.getInt("testIndex") + 1);
 
         AbstractResult results =
@@ -163,7 +176,7 @@
 
         mCurrentlyRunningTest = nextTest;
         mCurrentlyRunningTestIndex = index;
-        mCrashMessagesHandler.sendEmptyMessageDelayed(MSG_TEST_CRASHED, CRASH_TIMEOUT_MS);
+        mCrashMessagesHandler.sendEmptyMessageDelayed(MSG_CRASH_TIMEOUT_EXPIRED, CRASH_TIMEOUT_MS);
     }
 
     /**
@@ -188,7 +201,9 @@
     private void handleResults(AbstractResult results) {
         String relativePath = results.getRelativePath();
         results.setExpectedTextResult(getExpectedTextResult(relativePath));
+        results.setExpectedTextResultPath(getExpectedTextResultPath(relativePath));
         results.setExpectedImageResult(getExpectedImageResult(relativePath));
+        results.setExpectedImageResultPath(getExpectedImageResultPath(relativePath));
 
         dumpActualTextResult(results);
         dumpActualImageResult(results);
@@ -221,7 +236,7 @@
                 actualImageResult, false);
     }
 
-    public static String getExpectedTextResult(String relativePath) {
+    public String getExpectedTextResult(String relativePath) {
         byte[] result = getExpectedResult(relativePath, TEXT_RESULT_EXTENSION);
         if (result != null) {
             return new String(result);
@@ -229,13 +244,14 @@
         return null;
     }
 
-    public static byte[] getExpectedImageResult(String relativePath) {
+    public byte[] getExpectedImageResult(String relativePath) {
         return getExpectedResult(relativePath, IMAGE_RESULT_EXTENSION);
     }
 
-    private static byte[] getExpectedResult(String relativePath, String extension) {
+    private byte[] getExpectedResult(String relativePath, String extension) {
         String originalRelativePath =
                 FileFilter.setPathEnding(relativePath, "-expected." + extension);
+        mLastExpectedResultPathRequested = originalRelativePath;
 
         byte[] bytes = null;
         List<String> locations = EXPECTED_RESULT_LOCATION_RELATIVE_DIR_PREFIXES;
@@ -243,9 +259,28 @@
         int size = EXPECTED_RESULT_LOCATION_RELATIVE_DIR_PREFIXES.size();
         for (int i = 0; bytes == null && i < size; i++) {
             relativePath = locations.get(i) + originalRelativePath;
-            bytes = FsUtils.readDataFromStorage(new File(TESTS_ROOT_DIR_PATH, relativePath));
+            bytes = FsUtils.readDataFromUrl(FileFilter.getUrl(relativePath));
         }
 
+        mLastExpectedResultPathFetched = relativePath;
         return bytes;
     }
+
+    private String getExpectedTextResultPath(String relativePath) {
+        return getExpectedResultPath(relativePath, TEXT_RESULT_EXTENSION);
+    }
+
+    private String getExpectedImageResultPath(String relativePath) {
+        return getExpectedResultPath(relativePath, IMAGE_RESULT_EXTENSION);
+    }
+
+    private String getExpectedResultPath(String relativePath, String extension) {
+        String originalRelativePath =
+            FileFilter.setPathEnding(relativePath, "-expected." + extension);
+        if (!originalRelativePath.equals(mLastExpectedResultPathRequested)) {
+            getExpectedResult(relativePath, extension);
+        }
+
+        return mLastExpectedResultPathFetched;
+    }
 }
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java
index 43bc0b1..d18fb14 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java
@@ -21,8 +21,14 @@
 import android.content.res.Resources;
 import android.os.Build;
 import android.util.DisplayMetrics;
+import android.util.Log;
+
+import com.android.dumprendertree2.forwarder.ForwarderManager;
 
 import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -59,7 +65,8 @@
             "       font-size: 14px;" +
             "       color: black;" +
             "       text-decoration: none;" +
-            "       margin-bottom: 4px;}" +
+            "       margin-top: 4px;" +
+            "       margin-bottom: 2px;}" +
             "h3 a span.path {" +
             "       text-decoration: underline;}" +
             "h3 span.tri {" +
@@ -71,6 +78,15 @@
             "       color: #8ee100;" +
             "       float: left;" +
             "       width: 20px;}" +
+            "span.source {" +
+            "       display: block;" +
+            "       font-size: 10px;" +
+            "       color: #888;" +
+            "       margin-left: 20px;" +
+            "       margin-bottom: 1px;}" +
+            "span.source a {" +
+            "       font-size: 10px;" +
+            "       color: #888;}" +
             "h3 img {" +
             "       width: 8px;" +
             "       margin-right: 4px;}" +
@@ -178,9 +194,10 @@
     private static final String TXT_SUMMARY_RELATIVE_PATH = "summary.txt";
 
     private int mCrashedTestsCount = 0;
-    private List<AbstractResult> mFailedNotIgnoredTests = new ArrayList<AbstractResult>();
-    private List<AbstractResult> mIgnoredTests = new ArrayList<AbstractResult>();
-    private List<String> mPassedNotIgnoredTests = new ArrayList<String>();
+    private List<AbstractResult> mUnexpectedFailures = new ArrayList<AbstractResult>();
+    private List<AbstractResult> mExpectedFailures = new ArrayList<AbstractResult>();
+    private List<AbstractResult> mExpectedPasses = new ArrayList<AbstractResult>();
+    private List<AbstractResult> mUnexpectedPasses = new ArrayList<AbstractResult>();
 
     private FileFilter mFileFilter;
     private String mResultsRootDirPath;
@@ -194,6 +211,11 @@
         mResultsRootDirPath = resultsRootDirPath;
     }
 
+    public static URI getDetailsUri() {
+        return new File(ManagerService.RESULTS_ROOT_DIR_PATH + File.separator +
+                HTML_DETAILS_RELATIVE_PATH).toURI();
+    }
+
     public void appendTest(AbstractResult result) {
         String relativePath = result.getRelativePath();
 
@@ -201,12 +223,18 @@
             mCrashedTestsCount++;
         }
 
-        if (mFileFilter.isIgnoreRes(relativePath)) {
-            mIgnoredTests.add(result);
-        } else if (result.getResultCode() == AbstractResult.ResultCode.PASS) {
-            mPassedNotIgnoredTests.add(relativePath);
+        if (result.getResultCode() == AbstractResult.ResultCode.PASS) {
+            if (mFileFilter.isFail(relativePath)) {
+                mUnexpectedPasses.add(result);
+            } else {
+                mExpectedPasses.add(result);
+            }
         } else {
-            mFailedNotIgnoredTests.add(result);
+            if (mFileFilter.isFail(relativePath)) {
+                mExpectedFailures.add(result);
+            } else {
+                mUnexpectedFailures.add(result);
+            }
         }
     }
 
@@ -221,9 +249,9 @@
 
     public void reset() {
         mCrashedTestsCount = 0;
-        mFailedNotIgnoredTests.clear();
-        mIgnoredTests.clear();
-        mPassedNotIgnoredTests.clear();
+        mUnexpectedFailures.clear();
+        mExpectedFailures.clear();
+        mExpectedPasses.clear();
         mDate = new Date();
     }
 
@@ -235,15 +263,17 @@
         txt.append("Date: " + dateFormat.format(mDate) + "\n");
         txt.append("Build fingerprint: " + Build.FINGERPRINT + "\n");
         txt.append("WebKit version: " + getWebKitVersionFromUserAgentString() + "\n");
+        txt.append("WebKit revision: " + getWebKitRevision() + "\n");
 
         txt.append("TOTAL:   " + getTotalTestCount() + "\n");
         if (mCrashedTestsCount > 0) {
             txt.append("CRASHED (total among all tests): " + mCrashedTestsCount + "\n");
             txt.append("-------------");
         }
-        txt.append("FAILED:  " + mFailedNotIgnoredTests.size() + "\n");
-        txt.append("IGNORED: " + mIgnoredTests.size() + "\n");
-        txt.append("PASSED:  " + mPassedNotIgnoredTests.size() + "\n");
+        txt.append("UNEXPECTED FAILURES: " + mUnexpectedFailures.size() + "\n");
+        txt.append("UNEXPECTED PASSES:   " + mUnexpectedPasses.size() + "\n");
+        txt.append("EXPECTED FAILURES:   " + mExpectedFailures.size() + "\n");
+        txt.append("EXPECTED PASSES:     " + mExpectedPasses.size() + "\n");
 
         FsUtils.writeDataToStorage(new File(mResultsRootDirPath, TXT_SUMMARY_RELATIVE_PATH),
                 txt.toString().getBytes(), false);
@@ -259,11 +289,13 @@
 
         createTopSummaryTable(html);
 
-        createResultsListWithDiff(html, "Failed", mFailedNotIgnoredTests);
+        createResultsListWithDiff(html, "Unexpected failures", mUnexpectedFailures);
 
-        createResultsListWithDiff(html, "Ignored", mIgnoredTests);
+        createResultsListNoDiff(html, "Unexpected passes", mUnexpectedPasses);
 
-        createResultsListNoDiff(html, "Passed", mPassedNotIgnoredTests);
+        createResultsListWithDiff(html, "Expected failures", mExpectedFailures);
+
+        createResultsListNoDiff(html, "Expected passes", mExpectedPasses);
 
         html.append("</body></html>");
 
@@ -272,9 +304,10 @@
     }
 
     private int getTotalTestCount() {
-        return mFailedNotIgnoredTests.size() +
-                mPassedNotIgnoredTests.size() +
-                mIgnoredTests.size();
+        return mUnexpectedFailures.size() +
+                mUnexpectedPasses.size() +
+                mExpectedPasses.size() +
+                mExpectedFailures.size();
     }
 
     private String getWebKitVersionFromUserAgentString() {
@@ -290,6 +323,24 @@
         return "unknown";
     }
 
+    private String getWebKitRevision() {
+        URL url = null;
+        try {
+            url = new URL(ForwarderManager.getHostSchemePort(false) + "WEBKIT_MERGE_REVISION");
+        } catch (MalformedURLException e) {
+            assert false;
+        }
+
+        String webkitMergeRevisionFileContents = new String(FsUtils.readDataFromUrl(url));
+        Matcher matcher =
+            Pattern.compile("http://svn.webkit.org/repository/webkit/trunk@([0-9]+)").matcher(
+                    webkitMergeRevisionFileContents);
+        if (matcher.find()) {
+            return matcher.group(1);
+        }
+        return "unknown";
+    }
+
     private void createTopSummaryTable(StringBuilder html) {
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
         html.append("<h1>" + mTestsRelativePath + "</h1>");
@@ -297,12 +348,19 @@
         html.append("<h3>" + "Build fingerprint: " + Build.FINGERPRINT + "</h3>");
         html.append("<h3>" + "WebKit version: " + getWebKitVersionFromUserAgentString() + "</h3>");
 
+        String webkitRevision = getWebKitRevision();
+        html.append("<h3>" + "WebKit revision: ");
+        html.append("<a href=\"http://trac.webkit.org/browser/trunk?rev=" + webkitRevision +
+                "\" target=\"_blank\"><span class=\"path\">" + webkitRevision + "</span></a>");
+        html.append("</h3>");
+
         html.append("<table class=\"summary\">");
         createSummaryTableRow(html, "TOTAL", getTotalTestCount());
         createSummaryTableRow(html, "CRASHED", mCrashedTestsCount);
-        createSummaryTableRow(html, "FAILED", mFailedNotIgnoredTests.size());
-        createSummaryTableRow(html, "IGNORED", mIgnoredTests.size());
-        createSummaryTableRow(html, "PASSED", mPassedNotIgnoredTests.size());
+        createSummaryTableRow(html, "UNEXPECTED FAILURES", mUnexpectedFailures.size());
+        createSummaryTableRow(html, "UNEXPECTED PASSES", mUnexpectedPasses.size());
+        createSummaryTableRow(html, "EXPECTED FAILURES", mExpectedFailures.size());
+        createSummaryTableRow(html, "EXPECTED PASSES", mExpectedPasses.size());
         html.append("</table>");
     }
 
@@ -324,25 +382,21 @@
         for (AbstractResult result : resultsList) {
             relativePath = result.getRelativePath();
             resultCode = result.getResultCode();
+            assert resultCode != AbstractResult.ResultCode.PASS : "resultCode=" + resultCode;
 
             html.append("<h3>");
 
-            if (resultCode == AbstractResult.ResultCode.PASS) {
-                html.append("<span class=\"sqr\">&#x25a0; </span>");
-                html.append("<span class=\"path\">" + relativePath + "</span>");
-            } else {
-                /**
-                 * Technically, two different paths could end up being the same, because
-                 * ':' is a valid  character in a path. However, it is probably not going
-                 * to cause any problems in this case
-                 */
-                id = relativePath.replace(File.separator, ":");
-                html.append("<a href=\"#\" onClick=\"toggleDisplay('" + id + "');");
-                html.append("return false;\">");
-                html.append("<span class=\"tri\" id=\"tri." + id + "\">&#x25b6; </span>");
-                html.append("<span class=\"path\">" + relativePath + "</span>");
-                html.append("</a>");
-            }
+            /**
+             * Technically, two different paths could end up being the same, because
+             * ':' is a valid  character in a path. However, it is probably not going
+             * to cause any problems in this case
+             */
+            id = relativePath.replace(File.separator, ":");
+            html.append("<a href=\"#\" onClick=\"toggleDisplay('" + id + "');");
+            html.append("return false;\">");
+            html.append("<span class=\"tri\" id=\"tri." + id + "\">&#x25b6; </span>");
+            html.append("<span class=\"path\">" + relativePath + "</span>");
+            html.append("</a>");
 
             html.append(" <span class=\"listItem " + resultCode.name() + "\">");
             html.append(resultCode.toString());
@@ -363,29 +417,69 @@
             }
 
             html.append("</h3>");
+            appendExpectedResultsSources(result, html);
 
-            if (resultCode != AbstractResult.ResultCode.PASS) {
-                html.append("<div class=\"diff\" style=\"display: none;\" id=\"" + id + "\">");
-                html.append(result.getDiffAsHtml());
-                html.append("<a href=\"#\" onClick=\"toggleDisplay('" + id + "');");
-                html.append("return false;\">Hide</a>");
-                html.append("</div>");
-            }
+            html.append("<div class=\"diff\" style=\"display: none;\" id=\"" + id + "\">");
+            html.append(result.getDiffAsHtml());
+            html.append("<a href=\"#\" onClick=\"toggleDisplay('" + id + "');");
+            html.append("return false;\">Hide</a>");
+            html.append(" | ");
+            html.append("<a href=\"" + getViewSourceUrl(relativePath).toString() + "\"");
+            html.append(" target=\"_blank\">Show source</a>");
+            html.append("</div>");
 
             html.append("<div class=\"space\"></div>");
         }
     }
 
     private void createResultsListNoDiff(StringBuilder html, String title,
-            List<String> resultsList) {
+            List<AbstractResult> resultsList) {
         Collections.sort(resultsList);
-        html.append("<h2>Passed [" + resultsList.size() + "]</h2>");
-        for (String result : resultsList) {
+        html.append("<h2>" + title + " [" + resultsList.size() + "]</h2>");
+        for (AbstractResult result : resultsList) {
             html.append("<h3>");
+            html.append("<a href=\"" + getViewSourceUrl(result.getRelativePath()).toString() +
+                    "\"");
+            html.append(" target=\"_blank\">");
             html.append("<span class=\"sqr\">&#x25a0; </span>");
-            html.append("<span class=\"path\">" + result + "</span>");
+            html.append("<span class=\"path\">" + result.getRelativePath() + "</span>");
+            html.append("</a>");
             html.append("</h3>");
+            appendExpectedResultsSources(result, html);
             html.append("<div class=\"space\"></div>");
         }
     }
+
+    private static final void appendExpectedResultsSources(AbstractResult result,
+            StringBuilder html) {
+        String textSource = result.getExpectedTextResultPath();
+        String imageSource = result.getExpectedImageResultPath();
+
+        if (textSource != null) {
+            html.append("<span class=\"source\">Expected textual result from: ");
+            html.append("<a href=\"" + ForwarderManager.getHostSchemePort(false) + "LayoutTests/" +
+                    textSource + "\"");
+            html.append(" target=\"_blank\">");
+            html.append(textSource + "</a></span>");
+        }
+        if (imageSource != null) {
+            html.append("<span class=\"source\">Expected image result from: ");
+            html.append("<a href=\"" + ForwarderManager.getHostSchemePort(false) + "LayoutTests/" +
+                    imageSource + "\"");
+            html.append(" target=\"_blank\">");
+            html.append(imageSource + "</a></span>");
+        }
+    }
+
+    private static final URL getViewSourceUrl(String relativePath) {
+        URL url = null;
+        try {
+            url = new URL("http", "localhost", ForwarderManager.HTTP_PORT,
+                    "/WebKitTools/DumpRenderTree/android/view_source.php?src=" +
+                    relativePath);
+        } catch (MalformedURLException e) {
+            assert false : "relativePath=" + relativePath;
+        }
+        return url;
+    }
 }
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListActivity.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListActivity.java
index 4965fd9..9db4d2b 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListActivity.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListActivity.java
@@ -19,10 +19,14 @@
 import android.app.Activity;
 import android.app.ProgressDialog;
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.view.Gravity;
 import android.view.Window;
+import android.webkit.WebView;
+import android.widget.Toast;
 
 import com.android.dumprendertree2.scriptsupport.OnEverythingFinishedCallback;
 
@@ -124,13 +128,38 @@
     }
 
     private void onEverythingFinishedIntent(Intent intent) {
-        /** TODO: Show some kind of summary to the user */
+        Toast toast = Toast.makeText(this,
+                "All tests finished.\nPress back key to return to the tests' list.",
+                Toast.LENGTH_LONG);
+        toast.setGravity(Gravity.CENTER, -40, 0);
+        toast.show();
+
+        /** Show the details to the user */
+        WebView webView = new WebView(this);
+        webView.getSettings().setJavaScriptEnabled(true);
+        webView.getSettings().setBuiltInZoomControls(true);
+        webView.getSettings().setEnableSmoothTransition(true);
+        /** This enables double-tap to zoom */
+        webView.getSettings().setUseWideViewPort(true);
+
+        setContentView(webView);
+        webView.loadUrl(Summarizer.getDetailsUri().toString());
+
         mEverythingFinished = true;
         if (mOnEverythingFinishedCallback != null) {
             mOnEverythingFinishedCallback.onFinished();
         }
     }
 
+    /**
+     * This, together with android:configChanges="orientation" in manifest file, prevents
+     * the activity from restarting on orientation change.
+     */
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+    }
+
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         outState.putStringArrayList("testsList", mTestsList);
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListPreloaderThread.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListPreloaderThread.java
index 2145af7..c714ec4 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListPreloaderThread.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListPreloaderThread.java
@@ -18,8 +18,6 @@
 
 import android.os.Environment;
 import android.os.Message;
-import android.util.Log;
-
 import java.io.File;
 import java.util.ArrayList;
 import java.util.LinkedList;
@@ -64,17 +62,10 @@
 
     @Override
     public void run() {
-        /** Check if the path is correct */
-        File file = new File(TESTS_ROOT_DIR_PATH, mRelativePath);
-        if (!file.exists()) {
-            Log.e(LOG_TAG + "::run", "Path does not exist: " + mRelativePath);
+        if (FileFilter.isTestFile(mRelativePath)) {
+            mTestsList.add(mRelativePath);
         } else {
-            /** Populate the tests' list accordingly */
-            if (file.isDirectory()) {
-                preloadTests(mRelativePath);
-            } else {
-                mTestsList.add(mRelativePath);
-            }
+            loadTestsFromUrl(mRelativePath);
         }
 
         mDoneMsg.obj = mTestsList;
@@ -87,32 +78,35 @@
      *
      * @param dirRelativePath
      */
-    private void preloadTests(String dirRelativePath) {
+    private void loadTestsFromUrl(String dirRelativePath) {
         LinkedList<String> foldersList = new LinkedList<String>();
         foldersList.add(dirRelativePath);
 
         String relativePath;
-        String currentDirRelativePath;
         String itemName;
-        File[] items;
         while (!foldersList.isEmpty()) {
-            currentDirRelativePath = foldersList.removeFirst();
-            items = new File(TESTS_ROOT_DIR_PATH, currentDirRelativePath).listFiles();
-            for (File item : items) {
-                itemName = item.getName();
-                relativePath = currentDirRelativePath + File.separator + itemName;
+            relativePath = foldersList.removeFirst();
 
-                if (item.isDirectory() && FileFilter.isTestDir(itemName)) {
-                    foldersList.add(relativePath);
-                    continue;
+            for (String folderRelativePath : FsUtils.getLayoutTestsDirContents(relativePath,
+                    false, true)) {
+                itemName = new File(folderRelativePath).getName();
+                if (FileFilter.isTestDir(itemName)) {
+                    foldersList.add(folderRelativePath);
                 }
+            }
 
+            for (String testRelativePath : FsUtils.getLayoutTestsDirContents(relativePath,
+                    false, false)) {
+                itemName = new File(testRelativePath).getName();
                 if (FileFilter.isTestFile(itemName)) {
-                    if (!mFileFilter.isSkip(relativePath)) {
-                        mTestsList.add(relativePath);
+                    /** We chose to skip all the tests that are expected to crash. */
+                    if (!mFileFilter.isCrash(testRelativePath)) {
+                        mTestsList.add(testRelativePath);
                     } else {
-                        //mSummarizer.addSkippedTest(relativePath);
-                        /** TODO: Summarizer is now in service - figure out how to send the info */
+                        /**
+                         * TODO: Summarizer is now in service - figure out how to send the info.
+                         * Previously: mSummarizer.addSkippedTest(relativePath);
+                         */
                     }
                 }
             }
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
index 0f864e5..9664efe 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
@@ -36,6 +36,7 @@
     private static final int MSG_DOCUMENT_AS_TEXT = 0;
 
     private String mExpectedResult;
+    private String mExpectedResultPath;
     private String mActualResult;
     private String mRelativePath;
     private ResultCode mResultCode;
@@ -69,6 +70,7 @@
      */
     public TextResult(Bundle bundle) {
         mExpectedResult = bundle.getString("expectedTextualResult");
+        mExpectedResultPath = bundle.getString("expectedTextualResultPath");
         mActualResult = bundle.getString("actualTextualResult");
         setAdditionalTextOutputString(bundle.getString("additionalTextOutputString"));
         mRelativePath = bundle.getString("relativePath");
@@ -116,6 +118,27 @@
     }
 
     @Override
+    public void setExpectedImageResultPath(String relativePath) {
+        /** This method is not applicable to this type of result */
+    }
+
+    @Override
+    public String getExpectedImageResultPath() {
+        /** This method is not applicable to this type of result */
+        return null;
+    }
+
+    @Override
+    public void setExpectedTextResultPath(String relativePath) {
+        mExpectedResultPath = relativePath;
+    }
+
+    @Override
+    public String getExpectedTextResultPath() {
+        return mExpectedResultPath;
+    }
+
+    @Override
     public void setExpectedTextResult(String expectedResult) {
         mExpectedResult = expectedResult;
     }
@@ -212,6 +235,7 @@
     public Bundle getBundle() {
         Bundle bundle = new Bundle();
         bundle.putString("expectedTextualResult", mExpectedResult);
+        bundle.putString("expectedTextualResultPath", mExpectedResultPath);
         bundle.putString("actualTextualResult", getActualTextResult());
         bundle.putString("additionalTextOutputString", getAdditionalTextOutputString());
         bundle.putString("relativePath", mRelativePath);
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java
index 6a6cb7f..c356a10 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java
@@ -32,6 +32,10 @@
 
     private static final String LOG_TAG = "ConnectionHandler";
 
+    public static interface OnFinishedCallback {
+        public void onFinished();
+    }
+
     private class SocketPipeThread extends Thread {
 
         private Socket mInSocket, mOutSocket;
@@ -59,18 +63,19 @@
             int length;
             while (true) {
                 try {
-                    synchronized (this) {
-                        if ((length = is.read(buffer)) <= 0) {
-                            break;
-                        }
-                        os.write(buffer, 0, length);
+                    if ((length = is.read(buffer)) <= 0) {
+                        break;
                     }
+                    os.write(buffer, 0, length);
                 } catch (IOException e) {
                     /** This exception means one of the streams is closed */
                     Log.v(LOG_TAG, this.toString(), e);
                     break;
                 }
             }
+
+            ConnectionHandler.this.stop();
+            mOnFinishedCallback.onFinished();
         }
 
         @Override
@@ -82,6 +87,8 @@
     private Socket mFromSocket, mToSocket;
     private SocketPipeThread mFromToPipe, mToFromPipe;
 
+    private OnFinishedCallback mOnFinishedCallback;
+
     public ConnectionHandler(Socket fromSocket, Socket toSocket) {
         mFromSocket = fromSocket;
         mToSocket = toSocket;
@@ -89,6 +96,10 @@
         mToFromPipe = new SocketPipeThread(mToSocket, mFromSocket);
     }
 
+    public void registerOnConnectionHandlerFinishedCallback(OnFinishedCallback callback) {
+        mOnFinishedCallback = callback;
+    }
+
     public void start() {
         mFromToPipe.start();
         mToFromPipe.start();
@@ -100,17 +111,31 @@
     }
 
     private void shutdown(Socket socket) {
-        try {
-            synchronized (mFromToPipe) {
-                synchronized (mToFromPipe) {
-                    /** This will stop the while loop in the run method */
-                    socket.shutdownInput();
-                    socket.shutdownOutput();
-                    socket.close();
+        synchronized (mFromToPipe) {
+            synchronized (mToFromPipe) {
+                /** This will stop the while loop in the run method */
+                try {
+                    if (!socket.isInputShutdown()) {
+                        socket.shutdownInput();
+                    }
+                } catch (IOException e) {
+                    Log.e(LOG_TAG, "mFromToPipe=" + mFromToPipe + " mToFromPipe=" + mToFromPipe, e);
+                }
+                try {
+                    if (!socket.isOutputShutdown()) {
+                        socket.shutdownOutput();
+                    }
+                } catch (IOException e) {
+                    Log.e(LOG_TAG, "mFromToPipe=" + mFromToPipe + " mToFromPipe=" + mToFromPipe, e);
+                }
+                try {
+                    if (!socket.isClosed()) {
+                        socket.close();
+                    }
+                } catch (IOException e) {
+                    Log.e(LOG_TAG, "mFromToPipe=" + mFromToPipe + " mToFromPipe=" + mToFromPipe, e);
                 }
             }
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "mFromToPipe=" + mFromToPipe + " mToFromPipe=" + mToFromPipe, e);
         }
     }
 }
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java
index e5ef6da..1b581fc 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java
@@ -47,12 +47,6 @@
     @Override
     public void start() {
         Log.i(LOG_TAG, "start(): Starting fowarder on port: " + mPort);
-        synchronized (this) {
-            if (mIsRunning) {
-                Log.w(LOG_TAG, "start(): Forwarder on port: " + mPort + " already running! NOOP.");
-                return;
-            }
-        }
 
         try {
             mServerSocket = new ServerSocket(mPort);
@@ -82,7 +76,7 @@
                             mPort);
                 } catch (IOException e) {
                     /** This most likely means that mServerSocket is already closed */
-                    Log.w(LOG_TAG + "mPort=" + mPort, e);
+                    Log.w(LOG_TAG, "mPort=" + mPort, e);
                     return;
                 }
 
@@ -98,21 +92,38 @@
                     continue;
                 }
 
-                ConnectionHandler forwarder = new ConnectionHandler(localSocket, remoteSocket);
-                mConnectionHandlers.add(forwarder);
-                forwarder.start();
+                final ConnectionHandler connectionHandler =
+                        new ConnectionHandler(localSocket, remoteSocket);
 
+                /**
+                 * We have to close the sockets after the ConnectionHandler finishes, so we
+                 * don't get "Too may open files" exception. We also remove the ConnectionHandler
+                 * from the collection to avoid memory issues.
+                 * */
+                ConnectionHandler.OnFinishedCallback callback =
+                        new ConnectionHandler.OnFinishedCallback() {
+                    @Override
+                    public void onFinished() {
+                        removeConncetionHandler(connectionHandler);
+                    }
+                };
+                connectionHandler.registerOnConnectionHandlerFinishedCallback(callback);
+
+                mConnectionHandlers.add(connectionHandler);
+                connectionHandler.start();
             }
         }
     }
 
-    public void finish() {
-        synchronized (this) {
-            if (!mIsRunning) {
-                return;
-            }
+    private synchronized void removeConncetionHandler(ConnectionHandler connectionHandler) {
+        if (mConnectionHandlers.remove(connectionHandler)) {
+            Log.d(LOG_TAG, "removeConnectionHandler(): removed");
+        } else {
+            Log.d(LOG_TAG, "removeConnectionHandler(): not in the collection");
         }
+    }
 
+    public void finish() {
         try {
             mServerSocket.close();
         } catch (IOException e) {
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ForwarderManager.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ForwarderManager.java
index 10fee4b..7317a27 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ForwarderManager.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ForwarderManager.java
@@ -16,6 +16,10 @@
 
 package com.android.dumprendertree2.forwarder;
 
+import java.net.MalformedURLException;
+import java.net.URL;
+import android.util.Log;
+
 import java.util.HashSet;
 import java.util.Set;
 
@@ -25,6 +29,8 @@
  * It uses a singleton pattern and is thread safe.
  */
 public class ForwarderManager {
+    private static final String LOG_TAG = "ForwarderManager";
+
     /**
      * The IP address of the server serving the tests.
      */
@@ -37,14 +43,44 @@
     public static final int HTTP_PORT = 8080;
     public static final int HTTPS_PORT = 8443;
 
+    public static final String HOST = "localhost";
+
     private static ForwarderManager forwarderManager;
 
-    private Set<Forwarder> mServers;
+    private Set<Forwarder> mForwarders;
+    private boolean mIsStarted;
 
     private ForwarderManager() {
-        mServers = new HashSet<Forwarder>(2);
-        mServers.add(new Forwarder(HTTP_PORT, HOST_IP));
-        mServers.add(new Forwarder(HTTPS_PORT, HOST_IP));
+        mForwarders = new HashSet<Forwarder>(2);
+        mForwarders.add(new Forwarder(HTTP_PORT, HOST_IP));
+        mForwarders.add(new Forwarder(HTTPS_PORT, HOST_IP));
+    }
+
+    /**
+     * Returns the main part of the URL with the trailing slash
+     *
+     * @param isHttps
+     * @return
+     */
+    public static final String getHostSchemePort(boolean isHttps) {
+        int port;
+        String protocol;
+        if (isHttps) {
+            protocol = "https";
+            port = HTTPS_PORT;
+        } else {
+            protocol = "http";
+            port = HTTP_PORT;
+        }
+
+        URL url = null;
+        try {
+            url = new URL(protocol, HOST, port, "/");
+        } catch (MalformedURLException e) {
+            assert false : "isHttps=" + isHttps;
+        }
+
+        return url.toString();
     }
 
     public static synchronized ForwarderManager getForwarderManager() {
@@ -60,14 +96,30 @@
     }
 
     public synchronized void start() {
-        for (Forwarder server : mServers) {
-            server.start();
+        if (mIsStarted) {
+            Log.w(LOG_TAG, "start(): ForwarderManager already running! NOOP.");
+            return;
         }
+
+        for (Forwarder forwarder : mForwarders) {
+            forwarder.start();
+        }
+
+        mIsStarted = true;
+        Log.i(LOG_TAG, "ForwarderManager started.");
     }
 
     public synchronized void stop() {
-        for (Forwarder server : mServers) {
-            server.finish();
+        if (!mIsStarted) {
+            Log.w(LOG_TAG, "stop(): ForwarderManager already stopped! NOOP.");
+            return;
         }
+
+        for (Forwarder forwarder : mForwarders) {
+            forwarder.finish();
+        }
+
+        mIsStarted = false;
+        Log.i(LOG_TAG, "ForwarderManager stopped.");
     }
 }
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/Starter.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/Starter.java
index e730c8a..6f41a0f 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/Starter.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/Starter.java
@@ -21,6 +21,7 @@
 import android.util.Log;
 
 import com.android.dumprendertree2.TestsListActivity;
+import com.android.dumprendertree2.forwarder.ForwarderManager;
 
 /**
  * A class which provides methods that can be invoked by a script running on the host machine to
@@ -45,6 +46,8 @@
         ScriptTestRunner runner = (ScriptTestRunner)getInstrumentation();
         String relativePath = runner.getTestsRelativePath();
 
+        ForwarderManager.getForwarderManager().start();
+
         Intent intent = new Intent();
         intent.setClassName("com.android.dumprendertree2", "TestsListActivity");
         intent.setAction(Intent.ACTION_RUN);
@@ -70,5 +73,7 @@
                 }
             }
         }
+
+        ForwarderManager.getForwarderManager().stop();
     }
 }
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java
index af0d7d1..b1862ef 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java
@@ -17,8 +17,10 @@
 package com.android.dumprendertree2.ui;
 
 import com.android.dumprendertree2.FileFilter;
+import com.android.dumprendertree2.FsUtils;
 import com.android.dumprendertree2.TestsListActivity;
 import com.android.dumprendertree2.R;
+import com.android.dumprendertree2.forwarder.ForwarderManager;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -33,6 +35,9 @@
 import android.os.Handler;
 import android.os.Message;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
@@ -43,7 +48,6 @@
 
 import java.io.File;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -143,7 +147,7 @@
                 return false;
             }
 
-            return mRelativePath.equals(((ListItem) o).getRelativePath());
+            return mRelativePath.equals(((ListItem)o).getRelativePath());
         }
 
         @Override
@@ -172,10 +176,10 @@
             LayoutInflater inflater = mContext.getLayoutInflater();
             View row = inflater.inflate(R.layout.dirlist_row, null);
 
-            TextView label = (TextView) row.findViewById(R.id.label);
+            TextView label = (TextView)row.findViewById(R.id.label);
             label.setText(mItems[position].getName());
 
-            ImageView icon = (ImageView) row.findViewById(R.id.icon);
+            ImageView icon = (ImageView)row.findViewById(R.id.icon);
             if (mItems[position].isDirectory()) {
                 icon.setImageResource(R.drawable.folder);
             } else {
@@ -190,23 +194,21 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        ForwarderManager.getForwarderManager().start();
+
         mFileFilter = new FileFilter(ROOT_DIR_PATH);
         mListView = getListView();
 
         mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                ListItem item = (ListItem) parent.getItemAtPosition(position);
+                ListItem item = (ListItem)parent.getItemAtPosition(position);
 
                 if (item.isDirectory()) {
                     showDir(item.getRelativePath());
                 } else {
                     /** Run the test */
-                    Intent intent = new Intent();
-                    intent.setClass(DirListActivity.this, TestsListActivity.class);
-                    intent.setAction(Intent.ACTION_RUN);
-                    intent.putExtra(TestsListActivity.EXTRA_TEST_PATH, item.getRelativePath());
-                    startActivity(intent);
+                    runAllTestsUnder(item.getRelativePath());
                 }
             }
         });
@@ -214,7 +216,7 @@
         mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
             @Override
             public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
-                ListItem item = (ListItem) parent.getItemAtPosition(position);
+                ListItem item = (ListItem)parent.getItemAtPosition(position);
 
                 if (item.isDirectory()) {
                     Bundle arguments = new Bundle(1);
@@ -233,6 +235,32 @@
         showDir("");
     }
 
+    private void runAllTestsUnder(String relativePath) {
+        Intent intent = new Intent();
+        intent.setClass(DirListActivity.this, TestsListActivity.class);
+        intent.setAction(Intent.ACTION_RUN);
+        intent.putExtra(TestsListActivity.EXTRA_TEST_PATH, relativePath);
+        startActivity(intent);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.gui_menu, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.run_all:
+                runAllTestsUnder(mCurrentDirPath);
+                return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
     @Override
     /**
      * Moves to the parent directory if one exists. Does not allow to move above
@@ -275,13 +303,7 @@
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                         removeDialog(DIALOG_RUN_ABORT_DIR);
-                        /** Run the tests */
-                        Intent intent = new Intent();
-                        intent.setClass(DirListActivity.this, TestsListActivity.class);
-                        intent.setAction(Intent.ACTION_RUN);
-                        intent.putExtra(TestsListActivity.EXTRA_TEST_PATH,
-                                args.getString("relativePath"));
-                        startActivity(intent);
+                        runAllTestsUnder(args.getString("relativePath"));
                     }
                 });
 
@@ -376,25 +398,22 @@
      * The dirPath is relative.
      */
     private ListItem[] getDirList(String dirPath) {
-        File dir = new File(mRootDirPath, dirPath);
-
-        if (!dir.exists()) {
-            return new ListItem[0];
-        }
-
         List<ListItem> subDirs = new ArrayList<ListItem>();
         List<ListItem> subFiles = new ArrayList<ListItem>();
 
-        for (File item : dir.listFiles()) {
-            if (item.isDirectory() && FileFilter.isTestDir(item.getName())) {
-                subDirs.add(new ListItem(mFileFilter.getRelativePath(item), true));
-            } else if (FileFilter.isTestFile(item.getName())) {
-                subFiles.add(new ListItem(mFileFilter.getRelativePath(item), false));
+        for (String dirRelativePath : FsUtils.getLayoutTestsDirContents(dirPath, false,
+                true)) {
+            if (FileFilter.isTestDir(new File(dirRelativePath).getName())) {
+                subDirs.add(new ListItem(dirRelativePath, true));
             }
         }
 
-        Collections.sort(subDirs);
-        Collections.sort(subFiles);
+        for (String testRelativePath : FsUtils.getLayoutTestsDirContents(dirPath, false,
+                false)) {
+            if (FileFilter.isTestFile(new File(testRelativePath).getName())) {
+                subFiles.add(new ListItem(testRelativePath, false));
+            }
+        }
 
         /** Concatenate the two lists */
         subDirs.addAll(subFiles);
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 6a1f2d5..a1bc241 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -45,7 +45,7 @@
           mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
           mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
           mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL),
-          mMaxResVersion(NULL),
+          mMaxResVersion(NULL), mDebugMode(false),
           mArgc(0), mArgv(NULL)
         {}
     ~Bundle(void) {}
@@ -137,6 +137,8 @@
     void setCustomPackage(const char* val) { mCustomPackage = val; }
     const char* getMaxResVersion() const { return mMaxResVersion; }
     void setMaxResVersion(const char * val) { mMaxResVersion = val; }
+    bool getDebugMode() { return mDebugMode; }
+    void setDebugMode(bool val) { mDebugMode = val; }
 
     /*
      * Set and get the file specification.
@@ -234,6 +236,7 @@
     const char* mVersionName;
     const char* mCustomPackage;
     const char* mMaxResVersion;
+    bool        mDebugMode;
 
     /* file specification */
     int         mArgc;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index b50a393..eaff0f4 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -856,6 +856,15 @@
                                     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 == "") {
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index f457cc8..71c023d 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -57,7 +57,7 @@
     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"
-        "        [--min-sdk-version VAL] [--target-sdk-version VAL] \\\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"
@@ -124,6 +124,9 @@
         "   -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"
@@ -392,7 +395,9 @@
                 }
                 break;
             case '-':
-                if (strcmp(cp, "-min-sdk-version") == 0) {
+                if (strcmp(cp, "-debug-mode") == 0) {
+                    bundle.setDebugMode(true);
+                } else if (strcmp(cp, "-min-sdk-version") == 0) {
                     argc--;
                     argv++;
                     if (!argc) {
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 498b193..01728a1 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -678,6 +678,13 @@
                 bundle->getMaxSdkVersion());
     }
 
+    if (bundle->getDebugMode()) {
+        sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
+        if (application != NULL) {
+            addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true");
+        }
+    }
+
     // Deal with manifest package name overrides
     const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();
     if (manifestPackageNameOverride != NULL) {
diff --git a/voip/java/android/net/sip/ISipSession.aidl b/voip/java/android/net/sip/ISipSession.aidl
index fbcb056..1a23527 100644
--- a/voip/java/android/net/sip/ISipSession.aidl
+++ b/voip/java/android/net/sip/ISipSession.aidl
@@ -115,8 +115,7 @@
      * @param sessionDescription the session description of this call
      * @see ISipSessionListener
      */
-    void makeCall(in SipProfile callee,
-            in SessionDescription sessionDescription);
+    void makeCall(in SipProfile callee, String sessionDescription);
 
     /**
      * Answers an incoming call with the specified session description. The
@@ -125,7 +124,7 @@
      *
      * @param sessionDescription the session description to answer this call
      */
-    void answerCall(in SessionDescription sessionDescription);
+    void answerCall(String sessionDescription);
 
     /**
      * Ends an established call, terminates an outgoing call or rejects an
@@ -143,5 +142,5 @@
      *
      * @param sessionDescription the new session description
      */
-    void changeCall(in SessionDescription sessionDescription);
+    void changeCall(String sessionDescription);
 }
diff --git a/voip/java/android/net/sip/ISipSessionListener.aidl b/voip/java/android/net/sip/ISipSessionListener.aidl
index 8570958..c552a57 100644
--- a/voip/java/android/net/sip/ISipSessionListener.aidl
+++ b/voip/java/android/net/sip/ISipSessionListener.aidl
@@ -39,7 +39,7 @@
      * @param sessionDescription the caller's session description
      */
     void onRinging(in ISipSession session, in SipProfile caller,
-            in byte[] sessionDescription);
+            String sessionDescription);
 
     /**
      * Called when a RINGING response is received for the INVITE request sent
@@ -55,7 +55,7 @@
      * @param sessionDescription the peer's session description
      */
     void onCallEstablished(in ISipSession session,
-            in byte[] sessionDescription);
+            String sessionDescription);
 
     /**
      * Called when the session is terminated.
diff --git a/voip/java/android/net/sip/SdpSessionDescription.java b/voip/java/android/net/sip/SdpSessionDescription.java
index 0c29935..f6ae837 100644
--- a/voip/java/android/net/sip/SdpSessionDescription.java
+++ b/voip/java/android/net/sip/SdpSessionDescription.java
@@ -186,8 +186,8 @@
             }
         }
 
-        public SdpSessionDescription build() {
-            return mSdp;
+        public String build() {
+            return mSdp.toString();
         }
     }
 
diff --git a/voip/java/android/net/sip/SipAudioCall.java b/voip/java/android/net/sip/SipAudioCall.java
index 3cdd114..8254543 100644
--- a/voip/java/android/net/sip/SipAudioCall.java
+++ b/voip/java/android/net/sip/SipAudioCall.java
@@ -168,9 +168,9 @@
      * Attaches an incoming call to this call object.
      *
      * @param session the session that receives the incoming call
-     * @param sdp the session description of the incoming call
+     * @param sessionDescription the session description of the incoming call
      */
-    void attachCall(ISipSession session, SdpSessionDescription sdp)
+    void attachCall(ISipSession session, String sessionDescription)
             throws SipException;
 
     /** Ends a call. */
diff --git a/voip/java/android/net/sip/SipAudioCallImpl.java b/voip/java/android/net/sip/SipAudioCallImpl.java
index b8ac6d7..bd2c1cd 100644
--- a/voip/java/android/net/sip/SipAudioCallImpl.java
+++ b/voip/java/android/net/sip/SipAudioCallImpl.java
@@ -28,14 +28,6 @@
 import android.net.rtp.AudioGroup;
 import android.net.rtp.AudioStream;
 import android.net.rtp.RtpStream;
-import android.net.sip.ISipSession;
-import android.net.sip.SdpSessionDescription;
-import android.net.sip.SessionDescription;
-import android.net.sip.SipAudioCall;
-import android.net.sip.SipManager;
-import android.net.sip.SipProfile;
-import android.net.sip.SipSessionAdapter;
-import android.net.sip.SipSessionState;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.Vibrator;
@@ -196,7 +188,7 @@
 
     @Override
     public synchronized void onRinging(ISipSession session,
-            SipProfile peerProfile, byte[] sessionDescription) {
+            SipProfile peerProfile, String sessionDescription) {
         try {
             if ((mSipSession == null) || !mInCall
                     || !session.getCallId().equals(mSipSession.getCallId())) {
@@ -218,7 +210,7 @@
         }
     }
 
-    private synchronized void establishCall(byte[] sessionDescription) {
+    private synchronized void establishCall(String sessionDescription) {
         stopRingbackTone();
         stopRinging();
         try {
@@ -234,7 +226,7 @@
 
     @Override
     public void onCallEstablished(ISipSession session,
-            byte[] sessionDescription) {
+            String sessionDescription) {
         establishCall(sessionDescription);
         Listener listener = mListener;
         if (listener != null) {
@@ -312,10 +304,10 @@
     }
 
     public synchronized void attachCall(ISipSession session,
-            SdpSessionDescription sdp) throws SipException {
+            String sessionDescription) throws SipException {
         mSipSession = session;
-        mPeerSd = sdp;
         try {
+            mPeerSd = new SdpSessionDescription(sessionDescription);
             session.setListener(this);
         } catch (Throwable e) {
             Log.e(TAG, "attachCall()", e);
@@ -390,12 +382,12 @@
         if (audioGroup != null) audioGroup.setMode(AudioGroup.MODE_NORMAL);
     }
 
-    private SessionDescription createOfferSessionDescription() {
+    private String createOfferSessionDescription() {
         AudioCodec[] codecs = AudioCodec.getSystemSupportedCodecs();
         return createSdpBuilder(true, convert(codecs)).build();
     }
 
-    private SessionDescription createAnswerSessionDescription() {
+    private String createAnswerSessionDescription() {
         try {
             // choose an acceptable media from mPeerSd to answer
             SdpSessionDescription.AudioCodec codec = getCodec(mPeerSd);
@@ -412,7 +404,7 @@
         }
     }
 
-    private SessionDescription createHoldSessionDescription() {
+    private String createHoldSessionDescription() {
         try {
             return createSdpBuilder(false, mCodec)
                     .addMediaAttribute(AUDIO, "sendonly", (String) null)
@@ -422,7 +414,7 @@
         }
     }
 
-    private SessionDescription createContinueSessionDescription() {
+    private String createContinueSessionDescription() {
         return createSdpBuilder(true, mCodec).build();
     }
 
diff --git a/voip/java/android/net/sip/SipManager.java b/voip/java/android/net/sip/SipManager.java
index 287a13a..beec8fe 100644
--- a/voip/java/android/net/sip/SipManager.java
+++ b/voip/java/android/net/sip/SipManager.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
@@ -69,22 +70,42 @@
     private ISipService mSipService;
 
     /**
-     * Creates a manager instance and initializes the background SIP service.
-     * Will be removed once the SIP service is integrated into framework.
+     * Gets a manager instance. Returns null if SIP API is not supported.
      *
-     * @param context context to start the SIP service
-     * @return the manager instance
+     * @param context application context for checking if SIP API is supported
+     * @return the manager instance or null if SIP API is not supported
      */
-    public static SipManager getInstance(final Context context) {
-        final SipManager manager = new SipManager();
-        manager.createSipService(context);
-        return manager;
+    public static SipManager getInstance(Context context) {
+        return (isApiSupported(context) ? new SipManager() : null);
+    }
+
+    /**
+     * Returns true if the SIP API is supported by the system.
+     */
+    public static boolean isApiSupported(Context context) {
+        return true;
+        /* 
+        return context.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_SIP);
+         */
+    }
+
+    /**
+     * Returns true if the system supports SIP-based VoIP.
+     */
+    public static boolean isVoipSupported(Context context) {
+        return true;
+        /* 
+        return context.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_SIP_VOIP) && isApiSupported(context);
+         */
     }
 
     private SipManager() {
+        createSipService();
     }
 
-    private void createSipService(Context context) {
+    private void createSipService() {
         if (mSipService != null) return;
         IBinder b = ServiceManager.getService(Context.SIP_SERVICE);
         mSipService = ISipService.Stub.asInterface(b);
@@ -283,21 +304,19 @@
             throw new SipException("Call ID missing in incoming call intent");
         }
 
-        byte[] offerSd = getOfferSessionDescription(incomingCallIntent);
+        String offerSd = getOfferSessionDescription(incomingCallIntent);
         if (offerSd == null) {
             throw new SipException("Session description missing in incoming "
                     + "call intent");
         }
 
         try {
-            SdpSessionDescription sdp = new SdpSessionDescription(offerSd);
-
             ISipSession session = mSipService.getPendingSession(callId);
             if (session == null) return null;
             SipAudioCall call = new SipAudioCallImpl(
                     context, session.getLocalProfile());
             call.setRingtoneEnabled(ringtoneEnabled);
-            call.attachCall(session, sdp);
+            call.attachCall(session, offerSd);
             call.setListener(listener);
             return call;
         } catch (Throwable t) {
@@ -314,7 +333,7 @@
     public static boolean isIncomingCallIntent(Intent intent) {
         if (intent == null) return false;
         String callId = getCallId(intent);
-        byte[] offerSd = getOfferSessionDescription(intent);
+        String offerSd = getOfferSessionDescription(intent);
         return ((callId != null) && (offerSd != null));
     }
 
@@ -336,8 +355,8 @@
      * @return the offer session description or null if the intent does not
      *      have it
      */
-    public static byte[] getOfferSessionDescription(Intent incomingCallIntent) {
-        return incomingCallIntent.getByteArrayExtra(OFFER_SD_KEY);
+    public static String getOfferSessionDescription(Intent incomingCallIntent) {
+        return incomingCallIntent.getStringExtra(OFFER_SD_KEY);
     }
 
     /**
@@ -350,7 +369,7 @@
      * @hide
      */
     public static Intent createIncomingCallBroadcast(String action,
-            String callId, byte[] sessionDescription) {
+            String callId, String sessionDescription) {
         Intent intent = new Intent(action);
         intent.putExtra(CALL_ID_KEY, callId);
         intent.putExtra(OFFER_SD_KEY, sessionDescription);
diff --git a/voip/java/android/net/sip/SipProfile.java b/voip/java/android/net/sip/SipProfile.java
index 6c99141..aa2da75 100644
--- a/voip/java/android/net/sip/SipProfile.java
+++ b/voip/java/android/net/sip/SipProfile.java
@@ -46,8 +46,7 @@
     private String mProfileName;
     private boolean mSendKeepAlive = false;
     private boolean mAutoRegistration = true;
-    private boolean mAllowOutgoingCall = false;
-    private int mCallingUid = -1;
+    private transient int mCallingUid = 0;
 
     /** @hide */
     public static final Parcelable.Creator<SipProfile> CREATOR =
@@ -245,18 +244,6 @@
         }
 
         /**
-         * Sets the allow-outgoing-call flag.
-         *
-         * @param flag true if allowing to make outgoing call on the profile;
-         *      false otherwise
-         * @return this builder object
-         */
-        public Builder setOutgoingCallAllowed(boolean flag) {
-            mProfile.mAllowOutgoingCall = flag;
-            return this;
-        }
-
-        /**
          * Builds and returns the SIP profile object.
          *
          * @return the profile object created
@@ -293,7 +280,6 @@
         mProfileName = in.readString();
         mSendKeepAlive = (in.readInt() == 0) ? false : true;
         mAutoRegistration = (in.readInt() == 0) ? false : true;
-        mAllowOutgoingCall = (in.readInt() == 0) ? false : true;
         mCallingUid = in.readInt();
     }
 
@@ -307,7 +293,6 @@
         out.writeString(mProfileName);
         out.writeInt(mSendKeepAlive ? 1 : 0);
         out.writeInt(mAutoRegistration ? 1 : 0);
-        out.writeInt(mAllowOutgoingCall ? 1 : 0);
         out.writeInt(mCallingUid);
     }
 
@@ -435,13 +420,6 @@
     }
 
     /**
-     * Returns true if allowing to make outgoing calls on this profile.
-     */
-    public boolean isOutgoingCallAllowed() {
-        return mAllowOutgoingCall;
-    }
-
-    /**
      * Sets the calling process's Uid in the sip service.
      * @hide
      */
diff --git a/voip/java/android/net/sip/SipSessionAdapter.java b/voip/java/android/net/sip/SipSessionAdapter.java
index cfb71d7..770d4eb 100644
--- a/voip/java/android/net/sip/SipSessionAdapter.java
+++ b/voip/java/android/net/sip/SipSessionAdapter.java
@@ -26,14 +26,14 @@
     }
 
     public void onRinging(ISipSession session, SipProfile caller,
-            byte[] sessionDescription) {
+            String sessionDescription) {
     }
 
     public void onRingingBack(ISipSession session) {
     }
 
-    public void onCallEstablished(
-            ISipSession session, byte[] sessionDescription) {
+    public void onCallEstablished(ISipSession session,
+            String sessionDescription) {
     }
 
     public void onCallEnded(ISipSession session) {
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
new file mode 100644
index 0000000..78d5b7e
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -0,0 +1,682 @@
+/*
+ * 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.net.wifi;
+
+import android.app.ActivityManagerNative;
+import android.content.Context;
+import android.content.Intent;
+import android.net.wifi.WifiConfiguration.Status;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+
+/**
+ * This class provides the API to manage configured
+ * wifi networks. The API is not thread safe is being
+ * used only from WifiStateMachine.
+ *
+ * It deals with the following
+ * - Add/update/remove a WifiConfiguration
+ * - Maintain a list of configured networks for quick access
+ * TODO:
+ * - handle static IP per configuration
+ * - handle proxy per configuration
+ */
+class WifiConfigStore {
+
+    private static Context sContext;
+    private static final String TAG = "WifiConfigStore";
+
+    private static List<WifiConfiguration> sConfiguredNetworks = new ArrayList<WifiConfiguration>();
+    /* Tracks the highest priority of configured networks */
+    private static int sLastPriority = -1;
+
+    /**
+     * Initialize context, fetch the list of configured networks
+     * and enable all stored networks in supplicant.
+     */
+    static void initialize(Context context) {
+        Log.d(TAG, "Updating config and enabling all networks");
+        sContext = context;
+        updateConfiguredNetworks();
+        enableAllNetworks();
+    }
+
+    /**
+     * Fetch the list of currently configured networks
+     * @return List of networks
+     */
+    static List<WifiConfiguration> getConfiguredNetworks() {
+        List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
+        synchronized (sConfiguredNetworks) {
+            for (WifiConfiguration config : sConfiguredNetworks) {
+                networks.add(config.clone());
+            }
+        }
+        return networks;
+    }
+
+    /**
+     * enable all networks and save config. This will be a no-op if the list
+     * of configured networks indicates all networks as being enabled
+     */
+    static void enableAllNetworks() {
+        for (WifiConfiguration config : sConfiguredNetworks) {
+            if(config != null && config.status == Status.DISABLED) {
+                WifiNative.enableNetworkCommand(config.networkId, false);
+            }
+        }
+
+        WifiNative.saveConfigCommand();
+        updateConfigAndSendChangeBroadcast();
+    }
+
+    /**
+     * Selects the specified network config for connection. This involves
+     * addition/update of the specified config, updating the priority of
+     * all the networks and enabling the given network while disabling others.
+     *
+     * Selecting a network will leave the other networks disabled and
+     * a call to enableAllNetworks() needs to be issued upon a connection
+     * or a failure event from supplicant
+     *
+     * @param config The configuration details in WifiConfiguration
+     */
+    static void selectNetwork(WifiConfiguration config) {
+        if (config != null) {
+            int netId = addOrUpdateNetworkNative(config);
+            selectNetwork(netId);
+        }
+    }
+
+    /**
+     * Selects the specified network for connection. This involves
+     * updating the priority of all the networks and enabling the given
+     * network while disabling others.
+     *
+     * Selecting a network will leave the other networks disabled and
+     * a call to enableAllNetworks() needs to be issued upon a connection
+     * or a failure event from supplicant
+     *
+     * @param netId network to select for connection
+     */
+    static void selectNetwork(int netId) {
+        // Reset the priority of each network at start or if it goes too high.
+        if (sLastPriority == -1 || sLastPriority > 1000000) {
+            for (WifiConfiguration conf : sConfiguredNetworks) {
+                if (conf.networkId != -1) {
+                    conf.priority = 0;
+                    addOrUpdateNetworkNative(conf);
+                }
+            }
+            sLastPriority = 0;
+        }
+
+        // Set to the highest priority and save the configuration.
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = netId;
+        config.priority = ++sLastPriority;
+
+        addOrUpdateNetworkNative(config);
+        WifiNative.saveConfigCommand();
+
+        /* Enable the given network while disabling all other networks */
+        WifiNative.enableNetworkCommand(netId, true);
+
+        /* update the configured networks list but not send a
+         * broadcast to avoid a fetch from settings
+         * during this temporary disabling of networks
+         */
+        updateConfiguredNetworks();
+    }
+
+    /**
+     * Add/update the specified configuration and save config
+     *
+     * @param config WifiConfiguration to be saved
+     */
+    static void saveNetwork(WifiConfiguration config) {
+        int netId = addOrUpdateNetworkNative(config);
+        /* enable a new network */
+        if (config.networkId < 0) {
+            WifiNative.enableNetworkCommand(netId, false);
+        }
+        WifiNative.saveConfigCommand();
+        updateConfigAndSendChangeBroadcast();
+    }
+
+    /**
+     * Forget the specified network and save config
+     *
+     * @param netId network to forget
+     */
+    static void forgetNetwork(int netId) {
+        WifiNative.removeNetworkCommand(netId);
+        WifiNative.saveConfigCommand();
+        updateConfigAndSendChangeBroadcast();
+    }
+
+    /**
+     * Add/update a network. Note that there is no saveConfig operation.
+     * This function is retained for compatibility with the public
+     * API. The more powerful saveNetwork() is used by the
+     * state machine
+     *
+     * @param config wifi configuration to add/update
+     */
+    static int addOrUpdateNetwork(WifiConfiguration config) {
+        int ret = addOrUpdateNetworkNative(config);
+        updateConfigAndSendChangeBroadcast();
+        return ret;
+    }
+
+    /**
+     * Remove a network. Note that there is no saveConfig operation.
+     * This function is retained for compatibility with the public
+     * API. The more powerful forgetNetwork() is used by the
+     * state machine for network removal
+     *
+     * @param netId network to be removed
+     */
+    static boolean removeNetwork(int netId) {
+        boolean ret = WifiNative.removeNetworkCommand(netId);
+        updateConfigAndSendChangeBroadcast();
+        return ret;
+    }
+
+    /**
+     * Enable a network. Note that there is no saveConfig operation.
+     * This function is retained for compatibility with the public
+     * API. The more powerful selectNetwork()/saveNetwork() is used by the
+     * state machine for connecting to a network
+     *
+     * @param netId network to be removed
+     */
+    static boolean enableNetwork(int netId, boolean disableOthers) {
+        boolean ret = WifiNative.enableNetworkCommand(netId, disableOthers);
+        updateConfigAndSendChangeBroadcast();
+        return ret;
+    }
+
+    /**
+     * Disable a network. Note that there is no saveConfig operation.
+     * @param netId network to be disabled
+     */
+    static boolean disableNetwork(int netId) {
+        boolean ret = WifiNative.disableNetworkCommand(netId);
+        updateConfigAndSendChangeBroadcast();
+        return ret;
+    }
+
+    /**
+     * Save the configured networks in supplicant to disk
+     */
+    static boolean saveConfig() {
+        return WifiNative.saveConfigCommand();
+    }
+
+    private static void updateConfigAndSendChangeBroadcast() {
+        updateConfiguredNetworks();
+        if (!ActivityManagerNative.isSystemReady()) return;
+        Intent intent = new Intent(WifiManager.SUPPLICANT_CONFIG_CHANGED_ACTION);
+        sContext.sendBroadcast(intent);
+    }
+
+    private static void updateConfiguredNetworks() {
+        String listStr = WifiNative.listNetworksCommand();
+        sLastPriority = 0;
+
+        synchronized (sConfiguredNetworks) {
+            sConfiguredNetworks.clear();
+
+            if (listStr == null)
+                return;
+
+            String[] lines = listStr.split("\n");
+            // Skip the first line, which is a header
+            for (int i = 1; i < lines.length; i++) {
+                String[] result = lines[i].split("\t");
+                // network-id | ssid | bssid | flags
+                WifiConfiguration config = new WifiConfiguration();
+                try {
+                    config.networkId = Integer.parseInt(result[0]);
+                } catch(NumberFormatException e) {
+                    continue;
+                }
+                if (result.length > 3) {
+                    if (result[3].indexOf("[CURRENT]") != -1)
+                        config.status = WifiConfiguration.Status.CURRENT;
+                    else if (result[3].indexOf("[DISABLED]") != -1)
+                        config.status = WifiConfiguration.Status.DISABLED;
+                    else
+                        config.status = WifiConfiguration.Status.ENABLED;
+                } else {
+                    config.status = WifiConfiguration.Status.ENABLED;
+                }
+                readNetworkVariables(config);
+                if (config.priority > sLastPriority) {
+                    sLastPriority = config.priority;
+                }
+                sConfiguredNetworks.add(config);
+            }
+        }
+    }
+
+    private static int addOrUpdateNetworkNative(WifiConfiguration config) {
+        /*
+         * If the supplied networkId is -1, we create a new empty
+         * network configuration. Otherwise, the networkId should
+         * refer to an existing configuration.
+         */
+        int netId = config.networkId;
+        boolean newNetwork = netId == -1;
+        // networkId of -1 means we want to create a new network
+
+        if (newNetwork) {
+            netId = WifiNative.addNetworkCommand();
+            if (netId < 0) {
+                Log.e(TAG, "Failed to add a network!");
+                return -1;
+          }
+        }
+
+        setVariables: {
+
+            if (config.SSID != null &&
+                    !WifiNative.setNetworkVariableCommand(
+                        netId,
+                        WifiConfiguration.ssidVarName,
+                        config.SSID)) {
+                Log.d(TAG, "failed to set SSID: "+config.SSID);
+                break setVariables;
+            }
+
+            if (config.BSSID != null &&
+                    !WifiNative.setNetworkVariableCommand(
+                        netId,
+                        WifiConfiguration.bssidVarName,
+                        config.BSSID)) {
+                Log.d(TAG, "failed to set BSSID: "+config.BSSID);
+                break setVariables;
+            }
+
+            String allowedKeyManagementString =
+                makeString(config.allowedKeyManagement, WifiConfiguration.KeyMgmt.strings);
+            if (config.allowedKeyManagement.cardinality() != 0 &&
+                    !WifiNative.setNetworkVariableCommand(
+                        netId,
+                        WifiConfiguration.KeyMgmt.varName,
+                        allowedKeyManagementString)) {
+                Log.d(TAG, "failed to set key_mgmt: "+
+                        allowedKeyManagementString);
+                break setVariables;
+            }
+
+            String allowedProtocolsString =
+                makeString(config.allowedProtocols, WifiConfiguration.Protocol.strings);
+            if (config.allowedProtocols.cardinality() != 0 &&
+                    !WifiNative.setNetworkVariableCommand(
+                        netId,
+                        WifiConfiguration.Protocol.varName,
+                        allowedProtocolsString)) {
+                Log.d(TAG, "failed to set proto: "+
+                        allowedProtocolsString);
+                break setVariables;
+            }
+
+            String allowedAuthAlgorithmsString =
+                makeString(config.allowedAuthAlgorithms, WifiConfiguration.AuthAlgorithm.strings);
+            if (config.allowedAuthAlgorithms.cardinality() != 0 &&
+                    !WifiNative.setNetworkVariableCommand(
+                        netId,
+                        WifiConfiguration.AuthAlgorithm.varName,
+                        allowedAuthAlgorithmsString)) {
+                Log.d(TAG, "failed to set auth_alg: "+
+                        allowedAuthAlgorithmsString);
+                break setVariables;
+            }
+
+            String allowedPairwiseCiphersString =
+                    makeString(config.allowedPairwiseCiphers,
+                    WifiConfiguration.PairwiseCipher.strings);
+            if (config.allowedPairwiseCiphers.cardinality() != 0 &&
+                    !WifiNative.setNetworkVariableCommand(
+                        netId,
+                        WifiConfiguration.PairwiseCipher.varName,
+                        allowedPairwiseCiphersString)) {
+                Log.d(TAG, "failed to set pairwise: "+
+                        allowedPairwiseCiphersString);
+                break setVariables;
+            }
+
+            String allowedGroupCiphersString =
+                makeString(config.allowedGroupCiphers, WifiConfiguration.GroupCipher.strings);
+            if (config.allowedGroupCiphers.cardinality() != 0 &&
+                    !WifiNative.setNetworkVariableCommand(
+                        netId,
+                        WifiConfiguration.GroupCipher.varName,
+                        allowedGroupCiphersString)) {
+                Log.d(TAG, "failed to set group: "+
+                        allowedGroupCiphersString);
+                break setVariables;
+            }
+
+            // Prevent client screw-up by passing in a WifiConfiguration we gave it
+            // by preventing "*" as a key.
+            if (config.preSharedKey != null && !config.preSharedKey.equals("*") &&
+                    !WifiNative.setNetworkVariableCommand(
+                        netId,
+                        WifiConfiguration.pskVarName,
+                        config.preSharedKey)) {
+                Log.d(TAG, "failed to set psk: "+config.preSharedKey);
+                break setVariables;
+            }
+
+            boolean hasSetKey = false;
+            if (config.wepKeys != null) {
+                for (int i = 0; i < config.wepKeys.length; i++) {
+                    // Prevent client screw-up by passing in a WifiConfiguration we gave it
+                    // by preventing "*" as a key.
+                    if (config.wepKeys[i] != null && !config.wepKeys[i].equals("*")) {
+                        if (!WifiNative.setNetworkVariableCommand(
+                                    netId,
+                                    WifiConfiguration.wepKeyVarNames[i],
+                                    config.wepKeys[i])) {
+                            Log.d(TAG,
+                                    "failed to set wep_key"+i+": " +
+                                    config.wepKeys[i]);
+                            break setVariables;
+                        }
+                        hasSetKey = true;
+                    }
+                }
+            }
+
+            if (hasSetKey) {
+                if (!WifiNative.setNetworkVariableCommand(
+                            netId,
+                            WifiConfiguration.wepTxKeyIdxVarName,
+                            Integer.toString(config.wepTxKeyIndex))) {
+                    Log.d(TAG,
+                            "failed to set wep_tx_keyidx: "+
+                            config.wepTxKeyIndex);
+                    break setVariables;
+                }
+            }
+
+            if (!WifiNative.setNetworkVariableCommand(
+                        netId,
+                        WifiConfiguration.priorityVarName,
+                        Integer.toString(config.priority))) {
+                Log.d(TAG, config.SSID + ": failed to set priority: "
+                        +config.priority);
+                break setVariables;
+            }
+
+            if (config.hiddenSSID && !WifiNative.setNetworkVariableCommand(
+                        netId,
+                        WifiConfiguration.hiddenSSIDVarName,
+                        Integer.toString(config.hiddenSSID ? 1 : 0))) {
+                Log.d(TAG, config.SSID + ": failed to set hiddenSSID: "+
+                        config.hiddenSSID);
+                break setVariables;
+            }
+
+            for (WifiConfiguration.EnterpriseField field
+                    : config.enterpriseFields) {
+                String varName = field.varName();
+                String value = field.value();
+                if (value != null) {
+                    if (field != config.eap) {
+                        value = (value.length() == 0) ? "NULL" : convertToQuotedString(value);
+                    }
+                    if (!WifiNative.setNetworkVariableCommand(
+                                netId,
+                                varName,
+                                value)) {
+                        Log.d(TAG, config.SSID + ": failed to set " + varName +
+                                ": " + value);
+                        break setVariables;
+                    }
+                }
+            }
+            return netId;
+        }
+
+        if (newNetwork) {
+            WifiNative.removeNetworkCommand(netId);
+            Log.d(TAG,
+                    "Failed to set a network variable, removed network: "
+                    + netId);
+        }
+
+        return -1;
+    }
+
+    /**
+     * Read the variables from the supplicant daemon that are needed to
+     * fill in the WifiConfiguration object.
+     *
+     * @param config the {@link WifiConfiguration} object to be filled in.
+     */
+    private static void readNetworkVariables(WifiConfiguration config) {
+
+        int netId = config.networkId;
+        if (netId < 0)
+            return;
+
+        /*
+         * TODO: maybe should have a native method that takes an array of
+         * variable names and returns an array of values. But we'd still
+         * be doing a round trip to the supplicant daemon for each variable.
+         */
+        String value;
+
+        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.ssidVarName);
+        if (!TextUtils.isEmpty(value)) {
+            config.SSID = removeDoubleQuotes(value);
+        } else {
+            config.SSID = null;
+        }
+
+        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.bssidVarName);
+        if (!TextUtils.isEmpty(value)) {
+            config.BSSID = value;
+        } else {
+            config.BSSID = null;
+        }
+
+        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.priorityVarName);
+        config.priority = -1;
+        if (!TextUtils.isEmpty(value)) {
+            try {
+                config.priority = Integer.parseInt(value);
+            } catch (NumberFormatException ignore) {
+            }
+        }
+
+        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.hiddenSSIDVarName);
+        config.hiddenSSID = false;
+        if (!TextUtils.isEmpty(value)) {
+            try {
+                config.hiddenSSID = Integer.parseInt(value) != 0;
+            } catch (NumberFormatException ignore) {
+            }
+        }
+
+        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.wepTxKeyIdxVarName);
+        config.wepTxKeyIndex = -1;
+        if (!TextUtils.isEmpty(value)) {
+            try {
+                config.wepTxKeyIndex = Integer.parseInt(value);
+            } catch (NumberFormatException ignore) {
+            }
+        }
+
+        for (int i = 0; i < 4; i++) {
+            value = WifiNative.getNetworkVariableCommand(netId,
+                    WifiConfiguration.wepKeyVarNames[i]);
+            if (!TextUtils.isEmpty(value)) {
+                config.wepKeys[i] = value;
+            } else {
+                config.wepKeys[i] = null;
+            }
+        }
+
+        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.pskVarName);
+        if (!TextUtils.isEmpty(value)) {
+            config.preSharedKey = value;
+        } else {
+            config.preSharedKey = null;
+        }
+
+        value = WifiNative.getNetworkVariableCommand(config.networkId,
+                WifiConfiguration.Protocol.varName);
+        if (!TextUtils.isEmpty(value)) {
+            String vals[] = value.split(" ");
+            for (String val : vals) {
+                int index =
+                    lookupString(val, WifiConfiguration.Protocol.strings);
+                if (0 <= index) {
+                    config.allowedProtocols.set(index);
+                }
+            }
+        }
+
+        value = WifiNative.getNetworkVariableCommand(config.networkId,
+                WifiConfiguration.KeyMgmt.varName);
+        if (!TextUtils.isEmpty(value)) {
+            String vals[] = value.split(" ");
+            for (String val : vals) {
+                int index =
+                    lookupString(val, WifiConfiguration.KeyMgmt.strings);
+                if (0 <= index) {
+                    config.allowedKeyManagement.set(index);
+                }
+            }
+        }
+
+        value = WifiNative.getNetworkVariableCommand(config.networkId,
+                WifiConfiguration.AuthAlgorithm.varName);
+        if (!TextUtils.isEmpty(value)) {
+            String vals[] = value.split(" ");
+            for (String val : vals) {
+                int index =
+                    lookupString(val, WifiConfiguration.AuthAlgorithm.strings);
+                if (0 <= index) {
+                    config.allowedAuthAlgorithms.set(index);
+                }
+            }
+        }
+
+        value = WifiNative.getNetworkVariableCommand(config.networkId,
+                WifiConfiguration.PairwiseCipher.varName);
+        if (!TextUtils.isEmpty(value)) {
+            String vals[] = value.split(" ");
+            for (String val : vals) {
+                int index =
+                    lookupString(val, WifiConfiguration.PairwiseCipher.strings);
+                if (0 <= index) {
+                    config.allowedPairwiseCiphers.set(index);
+                }
+            }
+        }
+
+        value = WifiNative.getNetworkVariableCommand(config.networkId,
+                WifiConfiguration.GroupCipher.varName);
+        if (!TextUtils.isEmpty(value)) {
+            String vals[] = value.split(" ");
+            for (String val : vals) {
+                int index =
+                    lookupString(val, WifiConfiguration.GroupCipher.strings);
+                if (0 <= index) {
+                    config.allowedGroupCiphers.set(index);
+                }
+            }
+        }
+
+        for (WifiConfiguration.EnterpriseField field :
+                config.enterpriseFields) {
+            value = WifiNative.getNetworkVariableCommand(netId,
+                    field.varName());
+            if (!TextUtils.isEmpty(value)) {
+                if (field != config.eap) value = removeDoubleQuotes(value);
+                field.setValue(value);
+            }
+        }
+    }
+
+    private static String removeDoubleQuotes(String string) {
+        if (string.length() <= 2) return "";
+        return string.substring(1, string.length() - 1);
+    }
+
+    private static String convertToQuotedString(String string) {
+        return "\"" + string + "\"";
+    }
+
+    private static String makeString(BitSet set, String[] strings) {
+        StringBuffer buf = new StringBuffer();
+        int nextSetBit = -1;
+
+        /* Make sure all set bits are in [0, strings.length) to avoid
+         * going out of bounds on strings.  (Shouldn't happen, but...) */
+        set = set.get(0, strings.length);
+
+        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
+            buf.append(strings[nextSetBit].replace('_', '-')).append(' ');
+        }
+
+        // remove trailing space
+        if (set.cardinality() > 0) {
+            buf.setLength(buf.length() - 1);
+        }
+
+        return buf.toString();
+    }
+
+    private static int lookupString(String string, String[] strings) {
+        int size = strings.length;
+
+        string = string.replace('-', '_');
+
+        for (int i = 0; i < size; i++)
+            if (string.equals(strings[i]))
+                return i;
+
+        // if we ever get here, we should probably add the
+        // value to WifiConfiguration to reflect that it's
+        // supported by the WPA supplicant
+        Log.w(TAG, "Failed to look-up a string: " + string);
+
+        return -1;
+    }
+
+    static String dump() {
+        StringBuffer sb = new StringBuffer();
+        String LS = System.getProperty("line.separator");
+        sb.append("sLastPriority ").append(sLastPriority).append(LS);
+        sb.append("Configured networks ").append(LS);
+        for (WifiConfiguration conf : getConfiguredNetworks()) {
+            sb.append(conf).append(LS);
+        }
+        return sb.toString();
+    }
+}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 21671f1..8c3ec5f 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -307,19 +307,19 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String CONFIG_CHANGED_ACTION = "android.net.wifi.CONFIG_CHANGED";
     /**
-     * The lookup key for a {@link android.net.NetworkProperties} object associated with the
+     * The lookup key for a {@link android.net.LinkProperties} object associated with the
      * Wi-Fi network. Retrieve with
      * {@link android.content.Intent#getParcelableExtra(String)}.
      * @hide
      */
-    public static final String EXTRA_NETWORK_PROPERTIES = "networkProperties";
+    public static final String EXTRA_LINK_PROPERTIES = "linkProperties";
 
     /**
      * The network IDs of the configured networks could have changed.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
-    
+
     /**
      * Activity Action: Pick a Wi-Fi network to connect to.
      * <p>Input: Nothing.
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 47f8813..862a61b 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -111,6 +111,10 @@
 
     public native static boolean setPowerModeCommand(int mode);
 
+    public native static int getBandCommand();
+
+    public native static boolean setBandCommand(int band);
+
     public native static int getPowerModeCommand();
 
     public native static boolean setNumAllowedChannelsCommand(int numChannels);
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 69e8f2e..e1cbf5b 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -43,7 +43,7 @@
 import android.net.NetworkUtils;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.net.wifi.WifiConfiguration.Status;
 import android.os.Binder;
 import android.os.Message;
@@ -127,7 +127,6 @@
     private int mReconnectCount = 0;
     private boolean mIsScanMode = false;
     private boolean mConfigChanged = false;
-    private List<WifiConfiguration> mConfiguredNetworks = new ArrayList<WifiConfiguration>();
 
     /**
      * Instance of the bluetooth headset helper. This needs to be created
@@ -143,7 +142,7 @@
      * Observes the static IP address settings.
      */
     private SettingsObserver mSettingsObserver;
-    private NetworkProperties mNetworkProperties;
+    private LinkProperties mLinkProperties;
 
     // Held during driver load and unload
     private static PowerManager.WakeLock sWakeLock;
@@ -154,11 +153,11 @@
     private WifiInfo mWifiInfo;
     private NetworkInfo mNetworkInfo;
     private SupplicantStateTracker mSupplicantStateTracker;
-    /* Tracks the highest priority of configured networks */
-    private int mLastPriority = -1;
-    /* Tracks if all networks need to be enabled */
+    /* Connection to a specific network involves disabling all networks,
+     * this flag tracks if networks need to be re-enabled */
     private boolean mEnableAllNetworks = false;
 
+
     // Event log tags (must be in sync with event-log-tags)
     private static final int EVENTLOG_WIFI_STATE_CHANGED        = 50021;
     private static final int EVENTLOG_WIFI_EVENT_HANDLED        = 50022;
@@ -321,6 +320,13 @@
     private static final int SCAN_ACTIVE = 1;
     private static final int SCAN_PASSIVE = 2;
 
+    /* Auto allows 802.11A/B/G operation */
+    private static final int BAND_AUTO = 0;
+    /* 5GHz allows 802.11A operation */
+    private static final int BAND_5G = 1;
+    /* 2.4GHz allows 802.11B/G operation */
+    private static final int BAND_2G = 2;
+
     /**
      * The maximum number of times we will retry a connection to an access point
      * for which we have failed in acquiring an IP address from DHCP. A value of
@@ -421,10 +427,10 @@
         mSupplicantStateTracker = new SupplicantStateTracker(context, getHandler());
 
         mBluetoothHeadset = new BluetoothHeadset(mContext, null);
-        mNetworkProperties = new NetworkProperties();
+        mLinkProperties = new LinkProperties();
 
         mNetworkInfo.setIsAvailable(false);
-        mNetworkProperties.clear();
+        mLinkProperties.clear();
         mLastBssid = null;
         mLastNetworkId = -1;
         mLastSignalLevel = -1;
@@ -664,14 +670,7 @@
     }
 
     public List<WifiConfiguration> syncGetConfiguredNetworks() {
-        List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
-        synchronized (mConfiguredNetworks) {
-            Iterator<WifiConfiguration> iterator = mConfiguredNetworks.iterator();
-            while(iterator.hasNext()) {
-                networks.add(iterator.next().clone());
-            }
-        }
-        return networks;
+        return WifiConfigStore.getConfiguredNetworks();
     }
 
     /**
@@ -899,7 +898,7 @@
         StringBuffer sb = new StringBuffer();
         String LS = System.getProperty("line.separator");
         sb.append("current HSM state: ").append(getCurrentState().getName()).append(LS);
-        sb.append("mNetworkProperties ").append(mNetworkProperties).append(LS);
+        sb.append("mLinkProperties ").append(mLinkProperties).append(LS);
         sb.append("mWifiInfo ").append(mWifiInfo).append(LS);
         sb.append("mDhcpInfo ").append(mDhcpInfo).append(LS);
         sb.append("mNetworkInfo ").append(mNetworkInfo).append(LS);
@@ -907,7 +906,6 @@
         sb.append("mLastSignalLevel ").append(mLastSignalLevel).append(LS);
         sb.append("mLastBssid ").append(mLastBssid).append(LS);
         sb.append("mLastNetworkId ").append(mLastNetworkId).append(LS);
-        sb.append("mLastPriority ").append(mLastPriority).append(LS);
         sb.append("mEnableAllNetworks ").append(mEnableAllNetworks).append(LS);
         sb.append("mEnableRssiPolling ").append(mEnableRssiPolling).append(LS);
         sb.append("mPasswordKeyMayBeIncorrect ").append(mPasswordKeyMayBeIncorrect).append(LS);
@@ -917,11 +915,8 @@
         sb.append("mConfigChanged ").append(mConfigChanged).append(LS).append(LS);
         sb.append("Supplicant status").append(LS)
                 .append(WifiNative.statusCommand()).append(LS).append(LS);
-        sb.append("mConfigChanged ").append(mConfigChanged).append(LS);
-        sb.append("Configured networks ").append(LS);
-        for (WifiConfiguration conf : mConfiguredNetworks) {
-            sb.append(conf).append(LS);
-        }
+
+        sb.append(WifiConfigStore.dump());
         return sb.toString();
     }
 
@@ -1189,9 +1184,9 @@
         return null;
     }
 
-    private void configureNetworkProperties() {
+    private void configureLinkProperties() {
         try {
-            mNetworkProperties.setInterface(NetworkInterface.getByName(mInterfaceName));
+            mLinkProperties.setInterface(NetworkInterface.getByName(mInterfaceName));
         } catch (SocketException e) {
             Log.e(TAG, "SocketException creating NetworkInterface from " + mInterfaceName +
                     ". e=" + e);
@@ -1201,10 +1196,10 @@
             return;
         }
         // TODO - fix this for v6
-        mNetworkProperties.addAddress(NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress));
-        mNetworkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
-        mNetworkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
-        mNetworkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
+        mLinkProperties.addAddress(NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress));
+        mLinkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
+        mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
+        mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
         // TODO - add proxy info
     }
 
@@ -1381,7 +1376,7 @@
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
         intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
-        intent.putExtra(WifiManager.EXTRA_NETWORK_PROPERTIES, mNetworkProperties);
+        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
         if (bssid != null)
             intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
         mContext.sendStickyBroadcast(intent);
@@ -1390,7 +1385,7 @@
     private void sendConfigChangeBroadcast() {
         if (!ActivityManagerNative.isSystemReady()) return;
         Intent intent = new Intent(WifiManager.CONFIG_CHANGED_ACTION);
-        intent.putExtra(WifiManager.EXTRA_NETWORK_PROPERTIES, mNetworkProperties);
+        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
         mContext.sendBroadcast(intent);
     }
 
@@ -1407,13 +1402,6 @@
         mContext.sendStickyBroadcast(intent);
     }
 
-    private void updateConfigAndSendChangeBroadcast() {
-        updateConfiguredNetworks();
-        if (!ActivityManagerNative.isSystemReady()) return;
-        Intent intent = new Intent(WifiManager.SUPPLICANT_CONFIG_CHANGED_ACTION);
-        mContext.sendBroadcast(intent);
-    }
-
     private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
         if (!ActivityManagerNative.isSystemReady()) return;
 
@@ -1434,448 +1422,6 @@
         }
     }
 
-    private static String removeDoubleQuotes(String string) {
-      if (string.length() <= 2) return "";
-      return string.substring(1, string.length() - 1);
-    }
-
-    private static String convertToQuotedString(String string) {
-        return "\"" + string + "\"";
-    }
-
-    private static String makeString(BitSet set, String[] strings) {
-        StringBuffer buf = new StringBuffer();
-        int nextSetBit = -1;
-
-        /* Make sure all set bits are in [0, strings.length) to avoid
-         * going out of bounds on strings.  (Shouldn't happen, but...) */
-        set = set.get(0, strings.length);
-
-        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
-            buf.append(strings[nextSetBit].replace('_', '-')).append(' ');
-        }
-
-        // remove trailing space
-        if (set.cardinality() > 0) {
-            buf.setLength(buf.length() - 1);
-        }
-
-        return buf.toString();
-    }
-
-    private static int lookupString(String string, String[] strings) {
-        int size = strings.length;
-
-        string = string.replace('-', '_');
-
-        for (int i = 0; i < size; i++)
-            if (string.equals(strings[i]))
-                return i;
-
-        // if we ever get here, we should probably add the
-        // value to WifiConfiguration to reflect that it's
-        // supported by the WPA supplicant
-        Log.w(TAG, "Failed to look-up a string: " + string);
-
-        return -1;
-    }
-
-    private void enableAllNetworks() {
-        for (WifiConfiguration config : mConfiguredNetworks) {
-            if(config != null && config.status == Status.DISABLED) {
-                WifiNative.enableNetworkCommand(config.networkId, false);
-            }
-        }
-        WifiNative.saveConfigCommand();
-        updateConfigAndSendChangeBroadcast();
-    }
-
-    private int addOrUpdateNetworkNative(WifiConfiguration config) {
-        /*
-         * If the supplied networkId is -1, we create a new empty
-         * network configuration. Otherwise, the networkId should
-         * refer to an existing configuration.
-         */
-        int netId = config.networkId;
-        boolean newNetwork = netId == -1;
-        // networkId of -1 means we want to create a new network
-
-        if (newNetwork) {
-            netId = WifiNative.addNetworkCommand();
-            if (netId < 0) {
-                Log.e(TAG, "Failed to add a network!");
-                return -1;
-          }
-        }
-
-        setVariables: {
-
-            if (config.SSID != null &&
-                    !WifiNative.setNetworkVariableCommand(
-                        netId,
-                        WifiConfiguration.ssidVarName,
-                        config.SSID)) {
-                Log.d(TAG, "failed to set SSID: "+config.SSID);
-                break setVariables;
-            }
-
-            if (config.BSSID != null &&
-                    !WifiNative.setNetworkVariableCommand(
-                        netId,
-                        WifiConfiguration.bssidVarName,
-                        config.BSSID)) {
-                Log.d(TAG, "failed to set BSSID: "+config.BSSID);
-                break setVariables;
-            }
-
-            String allowedKeyManagementString =
-                makeString(config.allowedKeyManagement, WifiConfiguration.KeyMgmt.strings);
-            if (config.allowedKeyManagement.cardinality() != 0 &&
-                    !WifiNative.setNetworkVariableCommand(
-                        netId,
-                        WifiConfiguration.KeyMgmt.varName,
-                        allowedKeyManagementString)) {
-                Log.d(TAG, "failed to set key_mgmt: "+
-                        allowedKeyManagementString);
-                break setVariables;
-            }
-
-            String allowedProtocolsString =
-                makeString(config.allowedProtocols, WifiConfiguration.Protocol.strings);
-            if (config.allowedProtocols.cardinality() != 0 &&
-                    !WifiNative.setNetworkVariableCommand(
-                        netId,
-                        WifiConfiguration.Protocol.varName,
-                        allowedProtocolsString)) {
-                Log.d(TAG, "failed to set proto: "+
-                        allowedProtocolsString);
-                break setVariables;
-            }
-
-            String allowedAuthAlgorithmsString =
-                makeString(config.allowedAuthAlgorithms, WifiConfiguration.AuthAlgorithm.strings);
-            if (config.allowedAuthAlgorithms.cardinality() != 0 &&
-                    !WifiNative.setNetworkVariableCommand(
-                        netId,
-                        WifiConfiguration.AuthAlgorithm.varName,
-                        allowedAuthAlgorithmsString)) {
-                Log.d(TAG, "failed to set auth_alg: "+
-                        allowedAuthAlgorithmsString);
-                break setVariables;
-            }
-
-            String allowedPairwiseCiphersString =
-                    makeString(config.allowedPairwiseCiphers,
-                    WifiConfiguration.PairwiseCipher.strings);
-            if (config.allowedPairwiseCiphers.cardinality() != 0 &&
-                    !WifiNative.setNetworkVariableCommand(
-                        netId,
-                        WifiConfiguration.PairwiseCipher.varName,
-                        allowedPairwiseCiphersString)) {
-                Log.d(TAG, "failed to set pairwise: "+
-                        allowedPairwiseCiphersString);
-                break setVariables;
-            }
-
-            String allowedGroupCiphersString =
-                makeString(config.allowedGroupCiphers, WifiConfiguration.GroupCipher.strings);
-            if (config.allowedGroupCiphers.cardinality() != 0 &&
-                    !WifiNative.setNetworkVariableCommand(
-                        netId,
-                        WifiConfiguration.GroupCipher.varName,
-                        allowedGroupCiphersString)) {
-                Log.d(TAG, "failed to set group: "+
-                        allowedGroupCiphersString);
-                break setVariables;
-            }
-
-            // Prevent client screw-up by passing in a WifiConfiguration we gave it
-            // by preventing "*" as a key.
-            if (config.preSharedKey != null && !config.preSharedKey.equals("*") &&
-                    !WifiNative.setNetworkVariableCommand(
-                        netId,
-                        WifiConfiguration.pskVarName,
-                        config.preSharedKey)) {
-                Log.d(TAG, "failed to set psk: "+config.preSharedKey);
-                break setVariables;
-            }
-
-            boolean hasSetKey = false;
-            if (config.wepKeys != null) {
-                for (int i = 0; i < config.wepKeys.length; i++) {
-                    // Prevent client screw-up by passing in a WifiConfiguration we gave it
-                    // by preventing "*" as a key.
-                    if (config.wepKeys[i] != null && !config.wepKeys[i].equals("*")) {
-                        if (!WifiNative.setNetworkVariableCommand(
-                                    netId,
-                                    WifiConfiguration.wepKeyVarNames[i],
-                                    config.wepKeys[i])) {
-                            Log.d(TAG,
-                                    "failed to set wep_key"+i+": " +
-                                    config.wepKeys[i]);
-                            break setVariables;
-                        }
-                        hasSetKey = true;
-                    }
-                }
-            }
-
-            if (hasSetKey) {
-                if (!WifiNative.setNetworkVariableCommand(
-                            netId,
-                            WifiConfiguration.wepTxKeyIdxVarName,
-                            Integer.toString(config.wepTxKeyIndex))) {
-                    Log.d(TAG,
-                            "failed to set wep_tx_keyidx: "+
-                            config.wepTxKeyIndex);
-                    break setVariables;
-                }
-            }
-
-            if (!WifiNative.setNetworkVariableCommand(
-                        netId,
-                        WifiConfiguration.priorityVarName,
-                        Integer.toString(config.priority))) {
-                Log.d(TAG, config.SSID + ": failed to set priority: "
-                        +config.priority);
-                break setVariables;
-            }
-
-            if (config.hiddenSSID && !WifiNative.setNetworkVariableCommand(
-                        netId,
-                        WifiConfiguration.hiddenSSIDVarName,
-                        Integer.toString(config.hiddenSSID ? 1 : 0))) {
-                Log.d(TAG, config.SSID + ": failed to set hiddenSSID: "+
-                        config.hiddenSSID);
-                break setVariables;
-            }
-
-            for (WifiConfiguration.EnterpriseField field
-                    : config.enterpriseFields) {
-                String varName = field.varName();
-                String value = field.value();
-                if (value != null) {
-                    if (field != config.eap) {
-                        value = (value.length() == 0) ? "NULL" : convertToQuotedString(value);
-                    }
-                    if (!WifiNative.setNetworkVariableCommand(
-                                netId,
-                                varName,
-                                value)) {
-                        Log.d(TAG, config.SSID + ": failed to set " + varName +
-                                ": " + value);
-                        break setVariables;
-                    }
-                }
-            }
-            return netId;
-        }
-
-        if (newNetwork) {
-            WifiNative.removeNetworkCommand(netId);
-            Log.d(TAG,
-                    "Failed to set a network variable, removed network: "
-                    + netId);
-        }
-
-        return -1;
-    }
-
-    private void updateConfiguredNetworks() {
-        String listStr = WifiNative.listNetworksCommand();
-        mLastPriority = 0;
-
-        synchronized (mConfiguredNetworks) {
-            mConfiguredNetworks.clear();
-
-            if (listStr == null)
-                return;
-
-            String[] lines = listStr.split("\n");
-            // Skip the first line, which is a header
-            for (int i = 1; i < lines.length; i++) {
-                String[] result = lines[i].split("\t");
-                // network-id | ssid | bssid | flags
-                WifiConfiguration config = new WifiConfiguration();
-                try {
-                    config.networkId = Integer.parseInt(result[0]);
-                } catch(NumberFormatException e) {
-                    continue;
-                }
-                if (result.length > 3) {
-                    if (result[3].indexOf("[CURRENT]") != -1)
-                        config.status = WifiConfiguration.Status.CURRENT;
-                    else if (result[3].indexOf("[DISABLED]") != -1)
-                        config.status = WifiConfiguration.Status.DISABLED;
-                    else
-                        config.status = WifiConfiguration.Status.ENABLED;
-                } else {
-                    config.status = WifiConfiguration.Status.ENABLED;
-                }
-                readNetworkVariables(config);
-                if (config.priority > mLastPriority) {
-                    mLastPriority = config.priority;
-                }
-                mConfiguredNetworks.add(config);
-            }
-        }
-    }
-
-
-    /**
-     * Read the variables from the supplicant daemon that are needed to
-     * fill in the WifiConfiguration object.
-     *
-     * @param config the {@link WifiConfiguration} object to be filled in.
-     */
-    private void readNetworkVariables(WifiConfiguration config) {
-
-        int netId = config.networkId;
-        if (netId < 0)
-            return;
-
-        /*
-         * TODO: maybe should have a native method that takes an array of
-         * variable names and returns an array of values. But we'd still
-         * be doing a round trip to the supplicant daemon for each variable.
-         */
-        String value;
-
-        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.ssidVarName);
-        if (!TextUtils.isEmpty(value)) {
-            config.SSID = removeDoubleQuotes(value);
-        } else {
-            config.SSID = null;
-        }
-
-        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.bssidVarName);
-        if (!TextUtils.isEmpty(value)) {
-            config.BSSID = value;
-        } else {
-            config.BSSID = null;
-        }
-
-        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.priorityVarName);
-        config.priority = -1;
-        if (!TextUtils.isEmpty(value)) {
-            try {
-                config.priority = Integer.parseInt(value);
-            } catch (NumberFormatException ignore) {
-            }
-        }
-
-        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.hiddenSSIDVarName);
-        config.hiddenSSID = false;
-        if (!TextUtils.isEmpty(value)) {
-            try {
-                config.hiddenSSID = Integer.parseInt(value) != 0;
-            } catch (NumberFormatException ignore) {
-            }
-        }
-
-        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.wepTxKeyIdxVarName);
-        config.wepTxKeyIndex = -1;
-        if (!TextUtils.isEmpty(value)) {
-            try {
-                config.wepTxKeyIndex = Integer.parseInt(value);
-            } catch (NumberFormatException ignore) {
-            }
-        }
-
-        for (int i = 0; i < 4; i++) {
-            value = WifiNative.getNetworkVariableCommand(netId,
-                    WifiConfiguration.wepKeyVarNames[i]);
-            if (!TextUtils.isEmpty(value)) {
-                config.wepKeys[i] = value;
-            } else {
-                config.wepKeys[i] = null;
-            }
-        }
-
-        value = WifiNative.getNetworkVariableCommand(netId, WifiConfiguration.pskVarName);
-        if (!TextUtils.isEmpty(value)) {
-            config.preSharedKey = value;
-        } else {
-            config.preSharedKey = null;
-        }
-
-        value = WifiNative.getNetworkVariableCommand(config.networkId,
-                WifiConfiguration.Protocol.varName);
-        if (!TextUtils.isEmpty(value)) {
-            String vals[] = value.split(" ");
-            for (String val : vals) {
-                int index =
-                    lookupString(val, WifiConfiguration.Protocol.strings);
-                if (0 <= index) {
-                    config.allowedProtocols.set(index);
-                }
-            }
-        }
-
-        value = WifiNative.getNetworkVariableCommand(config.networkId,
-                WifiConfiguration.KeyMgmt.varName);
-        if (!TextUtils.isEmpty(value)) {
-            String vals[] = value.split(" ");
-            for (String val : vals) {
-                int index =
-                    lookupString(val, WifiConfiguration.KeyMgmt.strings);
-                if (0 <= index) {
-                    config.allowedKeyManagement.set(index);
-                }
-            }
-        }
-
-        value = WifiNative.getNetworkVariableCommand(config.networkId,
-                WifiConfiguration.AuthAlgorithm.varName);
-        if (!TextUtils.isEmpty(value)) {
-            String vals[] = value.split(" ");
-            for (String val : vals) {
-                int index =
-                    lookupString(val, WifiConfiguration.AuthAlgorithm.strings);
-                if (0 <= index) {
-                    config.allowedAuthAlgorithms.set(index);
-                }
-            }
-        }
-
-        value = WifiNative.getNetworkVariableCommand(config.networkId,
-                WifiConfiguration.PairwiseCipher.varName);
-        if (!TextUtils.isEmpty(value)) {
-            String vals[] = value.split(" ");
-            for (String val : vals) {
-                int index =
-                    lookupString(val, WifiConfiguration.PairwiseCipher.strings);
-                if (0 <= index) {
-                    config.allowedPairwiseCiphers.set(index);
-                }
-            }
-        }
-
-        value = WifiNative.getNetworkVariableCommand(config.networkId,
-                WifiConfiguration.GroupCipher.varName);
-        if (!TextUtils.isEmpty(value)) {
-            String vals[] = value.split(" ");
-            for (String val : vals) {
-                int index =
-                    lookupString(val, WifiConfiguration.GroupCipher.strings);
-                if (0 <= index) {
-                    config.allowedGroupCiphers.set(index);
-                }
-            }
-        }
-
-        for (WifiConfiguration.EnterpriseField field :
-                config.enterpriseFields) {
-            value = WifiNative.getNetworkVariableCommand(netId,
-                    field.varName());
-            if (!TextUtils.isEmpty(value)) {
-                if (field != config.eap) value = removeDoubleQuotes(value);
-                field.setValue(value);
-            }
-        }
-
-    }
-
     /**
      * Poll for info not reported via events
      * RSSI & Linkspeed
@@ -1945,7 +1491,7 @@
         mWifiInfo.setNetworkId(-1);
 
         /* Clear network properties */
-        mNetworkProperties.clear();
+        mLinkProperties.clear();
 
         mLastBssid= null;
         mLastNetworkId = -1;
@@ -2413,8 +1959,7 @@
 
                     mWifiInfo.setMacAddress(WifiNative.getMacAddressCommand());
 
-                    updateConfiguredNetworks();
-                    enableAllNetworks();
+                    WifiConfigStore.initialize(mContext);
 
                     //TODO: initialize and fix multicast filtering
                     //mWM.initializeMulticastFiltering();
@@ -2513,33 +2058,29 @@
                     EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
                     syncParams = (SyncParams) message.obj;
                     config = (WifiConfiguration) syncParams.mParameter;
-                    syncParams.mSyncReturn.intValue = addOrUpdateNetworkNative(config);
-                    updateConfigAndSendChangeBroadcast();
+                    syncParams.mSyncReturn.intValue = WifiConfigStore.addOrUpdateNetwork(config);
                     notifyOnMsgObject(message);
                     break;
                 case CMD_REMOVE_NETWORK:
                     EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
                     syncParams = (SyncParams) message.obj;
-                    syncParams.mSyncReturn.boolValue = WifiNative.removeNetworkCommand(
-                            message.arg1);
-                    updateConfigAndSendChangeBroadcast();
+                    syncParams.mSyncReturn.boolValue = WifiConfigStore.removeNetwork(
+                                message.arg1);
                     notifyOnMsgObject(message);
                     break;
                 case CMD_ENABLE_NETWORK:
                     EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
                     syncParams = (SyncParams) message.obj;
                     EnableNetParams enableNetParams = (EnableNetParams) syncParams.mParameter;
-                    syncParams.mSyncReturn.boolValue = WifiNative.enableNetworkCommand(
+                    syncParams.mSyncReturn.boolValue = WifiConfigStore.enableNetwork(
                             enableNetParams.netId, enableNetParams.disableOthers);
-                    updateConfigAndSendChangeBroadcast();
                     notifyOnMsgObject(message);
                     break;
                 case CMD_DISABLE_NETWORK:
                     EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
                     syncParams = (SyncParams) message.obj;
-                    syncParams.mSyncReturn.boolValue = WifiNative.disableNetworkCommand(
+                    syncParams.mSyncReturn.boolValue = WifiConfigStore.disableNetwork(
                             message.arg1);
-                    updateConfigAndSendChangeBroadcast();
                     notifyOnMsgObject(message);
                     break;
                 case CMD_BLACKLIST_NETWORK:
@@ -2551,7 +2092,7 @@
                     break;
                 case CMD_SAVE_CONFIG:
                     syncParams = (SyncParams) message.obj;
-                    syncParams.mSyncReturn.boolValue = WifiNative.saveConfigCommand();
+                    syncParams.mSyncReturn.boolValue = WifiConfigStore.saveConfig();
                     notifyOnMsgObject(message);
                     // Inform the backup manager about a data change
                     IBackupManager ibm = IBackupManager.Stub.asInterface(
@@ -2580,18 +2121,10 @@
                     break;
                 case CMD_SAVE_NETWORK:
                     config = (WifiConfiguration) message.obj;
-                    int netId = addOrUpdateNetworkNative(config);
-                    /* enable a new network */
-                    if (config.networkId < 0) {
-                        WifiNative.enableNetworkCommand(netId, false);
-                    }
-                    WifiNative.saveConfigCommand();
-                    updateConfigAndSendChangeBroadcast();
+                    WifiConfigStore.saveNetwork(config);
                     break;
                 case CMD_FORGET_NETWORK:
-                    WifiNative.removeNetworkCommand(message.arg1);
-                    WifiNative.saveConfigCommand();
-                    updateConfigAndSendChangeBroadcast();
+                    WifiConfigStore.forgetNetwork(message.arg1);
                     break;
                 default:
                     return NOT_HANDLED;
@@ -2653,6 +2186,14 @@
 
             /* Initialize channel count */
             setNumAllowedChannels();
+            /*
+             * STOPSHIP
+             * TODO: We are having 11A issues that Broadcom is looking
+             * to resolve, this is a temporary fix to allow only 11B/G
+             * and help improve GoogleGuest connectivity
+             * We also need to add the UI for band control
+             */
+            WifiNative.setBandCommand(BAND_2G);
 
             if (mIsScanMode) {
                 WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
@@ -2863,46 +2404,29 @@
                 case CMD_CONNECT_NETWORK:
                     int netId = message.arg1;
                     WifiConfiguration config = (WifiConfiguration) message.obj;
-                    if (config != null) {
-                        netId = addOrUpdateNetworkNative(config);
-                    }
-                    // Reset the priority of each network at start or if it goes too high.
-                    if (mLastPriority == -1 || mLastPriority > 1000000) {
-                        for (WifiConfiguration conf : mConfiguredNetworks) {
-                            if (conf.networkId != -1) {
-                                conf.priority = 0;
-                                addOrUpdateNetworkNative(conf);
-                            }
-                        }
-                        mLastPriority = 0;
-                    }
 
-                    // Set to the highest priority and save the configuration.
-                    config = new WifiConfiguration();
-                    config.networkId = netId;
-                    config.priority = ++mLastPriority;
-
-                    addOrUpdateNetworkNative(config);
-                    WifiNative.saveConfigCommand();
-
-                    /* We connect to a specific network by first enabling that network
-                     * and disabling all other networks in the supplicant. Disabling a
-                     * connected network will cause a disconnection from the network.
-                     * A reconnectCommand() will then initiate a connection to the enabled
-                     * network.
+                    /* We connect to a specific network by issuing a select
+                     * to the WifiConfigStore. This enables the network,
+                     * while disabling all other networks in the supplicant.
+                     * Disabling a connected network will cause a disconnection
+                     * from the network. A reconnectCommand() will then initiate
+                     * a connection to the enabled network.
                      */
-                    WifiNative.enableNetworkCommand(netId, true);
+                    if (config != null) {
+                        WifiConfigStore.selectNetwork(config);
+                    } else {
+                        WifiConfigStore.selectNetwork(netId);
+                    }
+
                     /* Save a flag to indicate that we need to enable all
                      * networks after supplicant indicates a network
                      * state change event
                      */
                     mEnableAllNetworks = true;
+
                     WifiNative.reconnectCommand();
-                    /* update the configured networks but not send a
-                     * broadcast to avoid a fetch from settings
-                     * during this temporary disabling of networks
-                     */
-                    updateConfiguredNetworks();
+
+                    /* Expect a disconnection from the old connection */
                     transitionTo(mDisconnectingState);
                     break;
                 case SCAN_RESULTS_EVENT:
@@ -3036,7 +2560,7 @@
                   mLastSignalLevel = -1; // force update of signal strength
                   mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
                   Log.d(TAG, "IP configuration: " + mDhcpInfo);
-                  configureNetworkProperties();
+                  configureLinkProperties();
                   setDetailedState(DetailedState.CONNECTED);
                   sendNetworkStateChangeBroadcast(mLastBssid);
                   //TODO: we could also detect an IP config change
@@ -3059,8 +2583,7 @@
                   if (++mReconnectCount > getMaxDhcpRetries()) {
                           Log.e(TAG, "Failed " +
                                   mReconnectCount + " times, Disabling " + mLastNetworkId);
-                      WifiNative.disableNetworkCommand(mLastNetworkId);
-                      updateConfigAndSendChangeBroadcast();
+                      WifiConfigStore.disableNetwork(mLastNetworkId);
                   }
 
                   /* DHCP times out after about 30 seconds, we do a
@@ -3197,7 +2720,7 @@
         public void exit() {
             if (mEnableAllNetworks) {
                 mEnableAllNetworks = false;
-                enableAllNetworks();
+                WifiConfigStore.enableAllNetworks();
             }
         }
     }
@@ -3491,10 +3014,9 @@
                  if (mPasswordKeyMayBeIncorrect) {
                      Log.d(TAG, "Failed to authenticate, disabling network " +
                              mWifiInfo.getNetworkId());
-                     WifiNative.disableNetworkCommand(mWifiInfo.getNetworkId());
+                     WifiConfigStore.disableNetwork(mWifiInfo.getNetworkId());
                      mPasswordKeyMayBeIncorrect = false;
                      sendSupplicantStateChangedBroadcast(stateChangeResult, true);
-                     updateConfigAndSendChangeBroadcast();
                  }
                  else {
                      sendSupplicantStateChangedBroadcast(stateChangeResult, false);
@@ -3553,8 +3075,7 @@
                      mLoopDetectCount++;
                  }
                  if (mLoopDetectCount > MAX_SUPPLICANT_LOOP_ITERATIONS) {
-                     WifiNative.disableNetworkCommand(stateChangeResult.networkId);
-                     updateConfigAndSendChangeBroadcast();
+                     WifiConfigStore.disableNetwork(stateChangeResult.networkId);
                      mLoopDetectCount = 0;
                  }
 
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 147e2dc..9cc44b5 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -24,7 +24,7 @@
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
-import android.net.NetworkProperties;
+import android.net.LinkProperties;
 import android.net.NetworkStateTracker;
 import android.os.Handler;
 import android.os.Message;
@@ -47,7 +47,7 @@
     private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
     private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
 
-    private NetworkProperties mNetworkProperties;
+    private LinkProperties mLinkProperties;
     private NetworkInfo mNetworkInfo;
 
     /* For sending events to connectivity service handler */
@@ -58,10 +58,10 @@
 
     public WifiStateTracker() {
         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
-        mNetworkProperties = new NetworkProperties();
+        mLinkProperties = new LinkProperties();
 
         mNetworkInfo.setIsAvailable(false);
-        mNetworkProperties.clear();
+        mLinkProperties.clear();
         setTeardownRequested(false);
     }
 
@@ -83,10 +83,8 @@
 
         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
         IntentFilter filter = new IntentFilter();
-        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.CONFIG_CHANGED_ACTION);
-        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
 
         mWifiStateReceiver = new WifiStateReceiver();
         mContext.registerReceiver(mWifiStateReceiver, filter);
@@ -191,10 +189,10 @@
     }
 
     /**
-     * Fetch NetworkProperties for the network
+     * Fetch LinkProperties for the network
      */
-    public NetworkProperties getNetworkProperties() {
-        return mNetworkProperties;
+    public LinkProperties getLinkProperties() {
+        return new LinkProperties(mLinkProperties);
     }
 
     /**
@@ -232,13 +230,13 @@
            if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                 mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
                         WifiManager.EXTRA_NETWORK_INFO);
-                mNetworkProperties = (NetworkProperties) intent.getParcelableExtra(
-                        WifiManager.EXTRA_NETWORK_PROPERTIES);
+                mLinkProperties = (LinkProperties) intent.getParcelableExtra(
+                        WifiManager.EXTRA_LINK_PROPERTIES);
                 Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
                 msg.sendToTarget();
             } else if (intent.getAction().equals(WifiManager.CONFIG_CHANGED_ACTION)) {
-                mNetworkProperties = (NetworkProperties) intent.getParcelableExtra(
-                        WifiManager.EXTRA_NETWORK_PROPERTIES);
+                mLinkProperties = (LinkProperties) intent.getParcelableExtra(
+                        WifiManager.EXTRA_LINK_PROPERTIES);
                 Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
                 msg.sendToTarget();
             }
