diff --git a/Android.mk b/Android.mk
index 1a29924..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)
 
@@ -497,12 +498,11 @@
 
 LOCAL_DROIDDOC_OPTIONS:=\
 		$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
-		-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_stubs_current_intermediates/src \
-		-apixml $(INTERNAL_PLATFORM_API_FILE) \
 		-parsecomments
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
-LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=assets-sdk
+
+LOCAL_UNINSTALLABLE_MODULE := true
 
 include $(BUILD_DROIDDOC)
 
@@ -532,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)
 
@@ -574,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)
 
@@ -595,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 ab4d72c..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="apply"
- 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"
@@ -104972,7 +105569,7 @@
  type="android.net.SSLCertificateSocketFactory"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="handshakeTimeoutMillis" type="int">
@@ -107109,7 +107706,7 @@
  type="android.net.http.SslCertificate"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="issuedTo" type="java.lang.String">
@@ -107176,7 +107773,7 @@
  synchronized="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </method>
@@ -107198,7 +107795,7 @@
  synchronized="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </method>
@@ -139519,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"
@@ -144199,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"
@@ -146683,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"
@@ -146793,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"
@@ -148578,7 +149205,7 @@
  value="1"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -167112,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"
@@ -182028,7 +182672,7 @@
  abstract="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <constructor name="EventLogTags"
@@ -192703,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"
@@ -192747,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"
@@ -194326,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"
@@ -195415,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"
@@ -197019,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"
@@ -197287,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"
@@ -197495,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"
@@ -197737,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"
@@ -197921,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"
@@ -198983,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"
@@ -200811,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"
@@ -213651,7 +214478,7 @@
  synchronized="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </method>
@@ -213662,7 +214489,7 @@
  synchronized="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </method>
@@ -214199,7 +215026,7 @@
  synchronized="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="flag" type="boolean">
@@ -214212,7 +215039,7 @@
  synchronized="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="pluginsPath" type="java.lang.String">
@@ -215953,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"
@@ -216401,7 +217241,7 @@
  synchronized="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="view" type="android.webkit.WebView">
@@ -232236,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>
@@ -232253,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"
@@ -264420,7 +265288,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="lng" type="long">
+<parameter name="l" type="long">
 </parameter>
 </method>
 <method name="append"
@@ -264498,7 +265366,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="ch" type="char[]">
+<parameter name="chars" type="char[]">
 </parameter>
 </method>
 <method name="append"
@@ -319069,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"
@@ -416825,7 +417693,7 @@
  synchronized="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="protected"
 >
 <parameter name="pattern" type="java.lang.String">
@@ -424206,7 +425074,7 @@
  abstract="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <method name="getLength"
@@ -424695,7 +425563,7 @@
  abstract="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <method name="characters"
@@ -424910,7 +425778,7 @@
  abstract="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <implements name="org.xml.sax.DTDHandler">
@@ -425377,7 +426245,7 @@
  abstract="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <method name="parse"
@@ -426809,7 +427677,7 @@
  abstract="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <implements name="org.xml.sax.AttributeList">
@@ -428298,7 +429166,7 @@
  abstract="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <method name="makeParser"
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 9082626..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 04f198c..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 dc45372..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 d643ce7..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/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 00d769f..18ecc24 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1869,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();
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/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/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/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 0498fff..63bdf8d 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -105,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;
@@ -160,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;
                 }
@@ -169,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= " +
@@ -194,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 {
@@ -253,7 +250,6 @@
                         " broadcast" + reason == null ? "" : "(" + reason + ")");
                 setDetailedState(DetailedState.FAILED, reason, apnName);
             }
-            TelephonyManager tm = TelephonyManager.getDefault();
         }
     }
 
@@ -267,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();
     }
 
     /**
@@ -357,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
@@ -391,10 +351,6 @@
         }
     }
 
-    private void setDetailedStateInternal(NetworkInfo.DetailedState state) {
-        mNetworkInfo.setDetailedState(state, null, null);
-    }
-
     public void setTeardownRequested(boolean isRequested) {
         mTeardownRequested = isRequested;
     }
diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java
index ba27221..bce7ec0 100644
--- a/core/java/android/net/ProxyProperties.java
+++ b/core/java/android/net/ProxyProperties.java
@@ -41,13 +41,17 @@
         if (source != null) {
             mProxy = source.getAddress();
             mPort = source.getPort();
-            mExclusionList = new String(source.getExclusionList());
+            String exclusionList = source.getExclusionList();
+            if (exclusionList != null) {
+                mExclusionList = new String(exclusionList);
+            }
         }
     }
 
     public InetAddress getAddress() {
         return mProxy;
     }
+
     public void setAddress(InetAddress proxy) {
         mProxy = proxy;
     }
@@ -55,6 +59,7 @@
     public int getPort() {
         return mPort;
     }
+
     public void setPort(int port) {
         mPort = port;
     }
@@ -62,6 +67,7 @@
     public String getExclusionList() {
         return mExclusionList;
     }
+
     public void setExclusionList(String exclusionList) {
         mExclusionList = exclusionList;
     }
@@ -69,8 +75,12 @@
     @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();
     }
 
@@ -121,5 +131,4 @@
                 return new ProxyProperties[size];
             }
         };
-
-};
+}
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/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 9f9a4d4..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 {
             /**
@@ -4250,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 0a111a7..34f2f0d 100644
--- a/core/java/android/provider/DrmStore.java
+++ b/core/java/android/provider/DrmStore.java
@@ -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 fa5f156..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;
         }
     }
 
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 65cb182..11a5d69 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -320,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/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/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..af0438c 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/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/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-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/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/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..952d078
--- /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/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/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/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/ui/Input.h b/include/ui/Input.h
index 49347d3..3fa825f 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -466,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/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/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 02f5dc5..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);
@@ -175,7 +176,7 @@
 }
 
 int OpenGLRenderer::save(int flags) {
-    return saveSnapshot();
+    return saveSnapshot(flags);
 }
 
 void OpenGLRenderer::restore() {
@@ -192,8 +193,8 @@
     }
 }
 
-int OpenGLRenderer::saveSnapshot() {
-    mSnapshot = new Snapshot(mSnapshot);
+int OpenGLRenderer::saveSnapshot(int flags) {
+    mSnapshot = new Snapshot(mSnapshot, flags);
     return mSaveCount++;
 }
 
@@ -231,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;
@@ -258,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,
@@ -272,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) {
@@ -290,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;
 }
@@ -323,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;
@@ -355,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);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -384,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());
 }
 
@@ -396,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) {
@@ -405,7 +412,7 @@
     if (clipped) {
         setScissorFromClip();
     }
-    return !mSnapshot->clipRect.isEmpty();
+    return !mSnapshot->clipRect->isEmpty();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -501,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);
 }
 
@@ -538,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);
     }
@@ -747,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++;
@@ -852,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);
@@ -900,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 d0e04b2..0e90d20 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -108,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..59fd319 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/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/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/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_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/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index d3bb96e9..7297811 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -258,16 +258,24 @@
         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
@@ -375,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--;
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/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index bbbf45c..f1b8334 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -24,6 +24,7 @@
 #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>
@@ -532,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());
@@ -631,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());
     }
@@ -1079,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;
@@ -1122,7 +1181,9 @@
 
 status_t StagefrightRecorder::setupMPEG4Recording(
         bool useSplitCameraSource,
-        int outputFd, int32_t audioBitRate, int32_t videoBitRate,
+        int outputFd,
+        int32_t videoWidth, int32_t videoHeight,
+        int32_t videoBitRate,
         int32_t *totalBitRate,
         sp<MediaWriter> *mediaWriter) {
     mediaWriter->clear();
@@ -1134,7 +1195,7 @@
     if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) {
         err = setupAudioEncoder(writer);
         if (err != OK) return err;
-        *totalBitRate += audioBitRate;
+        *totalBitRate += mAudioBitRate;
     }
     if (mVideoSource == VIDEO_SOURCE_DEFAULT
             || mVideoSource == VIDEO_SOURCE_CAMERA) {
@@ -1148,6 +1209,13 @@
             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;
         }
@@ -1207,7 +1275,8 @@
 
     int32_t totalBitRate;
     status_t err = setupMPEG4Recording(mCaptureAuxVideo,
-            mOutputFd, mAudioBitRate, mVideoBitRate, &totalBitRate, &mWriter);
+            mOutputFd, mVideoWidth, mVideoHeight,
+            mVideoBitRate, &totalBitRate, &mWriter);
     if (err != OK) {
         return err;
     }
@@ -1230,7 +1299,8 @@
 
         int32_t totalBitrateAux;
         err = setupMPEG4Recording(mCaptureAuxVideo,
-                mOutputFdAux, mAudioBitRateAux, mVideoBitRateAux, &totalBitrateAux, &mWriterAux);
+                mOutputFdAux, mAuxVideoWidth, mAuxVideoHeight,
+                mAuxVideoBitRate, &totalBitrateAux, &mWriterAux);
         if (err != OK) {
             return err;
         }
@@ -1326,13 +1396,14 @@
     mVideoEncoder  = VIDEO_ENCODER_H263;
     mVideoWidth    = 176;
     mVideoHeight   = 144;
+    mAuxVideoWidth    = 176;
+    mAuxVideoHeight   = 144;
     mFrameRate     = 20;
     mVideoBitRate  = 192000;
-    mVideoBitRateAux = 20000000;
+    mAuxVideoBitRate = 192000;
     mSampleRate    = 8000;
     mAudioChannels = 1;
     mAudioBitRate  = 12200;
-    mAudioBitRateAux  = 12200;
     mInterleaveDurationUs = 0;
     mIFramesIntervalSec = 1;
     mAudioSourceNode = 0;
@@ -1414,8 +1485,6 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "     Bit rate (bps): %d\n", mAudioBitRate);
     result.append(buffer);
-    snprintf(buffer, SIZE, "     Bit rate auxiliary (bps): %d\n", mAudioBitRateAux);
-    result.append(buffer);
     snprintf(buffer, SIZE, "     Sampling rate (hz): %d\n", mSampleRate);
     result.append(buffer);
     snprintf(buffer, SIZE, "     Number of channels: %d\n", mAudioChannels);
@@ -1440,11 +1509,13 @@
     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, "     Bit rate Auxiliary (bps): %d\n", mVideoBitRateAux);
+    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 d75a540..d50a393 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -79,9 +79,10 @@
     video_encoder mVideoEncoder;
     bool mUse64BitFileOffset;
     int32_t mVideoWidth, mVideoHeight;
+    int32_t mAuxVideoWidth, mAuxVideoHeight;
     int32_t mFrameRate;
-    int32_t mVideoBitRate, mVideoBitRateAux;
-    int32_t mAudioBitRate, mAudioBitRateAux;
+    int32_t mVideoBitRate, mAuxVideoBitRate;
+    int32_t mAudioBitRate;
     int32_t mAudioChannels;
     int32_t mSampleRate;
     int32_t mInterleaveDurationUs;
@@ -109,8 +110,10 @@
     MediaProfiles *mEncoderProfiles;
 
     status_t setupMPEG4Recording(
-        bool useAuxiliaryCameraSource,
-        int outputFd, int32_t audioBitRate, int32_t videoBitRate,
+        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,
@@ -137,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/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 085e92d..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) {
@@ -1428,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);
@@ -1482,8 +1550,6 @@
     mFlags |= PREPARED;
     mAsyncPrepareEvent = NULL;
     mPreparedCondition.broadcast();
-
-    postBufferingEvent_l();
 }
 
 status_t AwesomePlayer::suspend() {
@@ -1523,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) {
@@ -1584,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/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/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/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 f34eb45..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 12f8f32..10c9e02 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -362,7 +362,6 @@
     if (receiveRTP) {
         err = parseRTP(s, buffer);
     } else {
-        ++s->mNumRTCPPacketsReceived;
         err = parseRTCP(s, buffer);
     }
 
@@ -456,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();
 
@@ -626,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 f60c1a9..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));
 
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/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 3d8d86b..0aefd58 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -82,7 +82,8 @@
           mFirstAccessUnitNTP(0),
           mNumAccessUnitsReceived(0),
           mCheckPending(false),
-          mTryTCPInterleaving(false) {
+          mTryTCPInterleaving(false),
+          mReceivedFirstRTCPPacket(false) {
         mNetLooper->setName("rtsp net");
         mNetLooper->start(false /* runOnCallingThread */,
                           false /* canCallJava */,
@@ -199,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);
                 }
@@ -247,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) {
@@ -256,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;
@@ -355,6 +362,12 @@
                     }
                 }
                 mTracks.clear();
+                mSetupTracksSuccessful = false;
+                mSeekPending = false;
+                mFirstAccessUnit = true;
+                mFirstAccessUnitNTP = 0;
+                mNumAccessUnitsReceived = 0;
+                mReceivedFirstRTCPPacket = false;
 
                 sp<AMessage> reply = new AMessage('tear', id());
 
@@ -424,6 +437,12 @@
 
             case 'accu':
             {
+                int32_t firstRTCP;
+                if (msg->findInt32("first-rtcp", &firstRTCP)) {
+                    mReceivedFirstRTCPPacket = true;
+                    break;
+                }
+
                 ++mNumAccessUnitsReceived;
 
                 if (!mCheckPending) {
@@ -612,7 +631,7 @@
 
             case 'tiou':
             {
-                if (mFirstAccessUnit) {
+                if (!mReceivedFirstRTCPPacket) {
                     if (mTryTCPInterleaving) {
                         LOG(WARNING) << "Never received any data, disconnecting.";
                         (new AMessage('abor', id()))->post();
@@ -747,6 +766,7 @@
     int64_t mNumAccessUnitsReceived;
     bool mCheckPending;
     bool mTryTCPInterleaving;
+    bool mReceivedFirstRTCPPacket;
 
     struct TrackInfo {
         AString mURL;
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 d9486e5..418f609 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -662,62 +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);
-
 #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 72bd776..5e48461 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -2,4 +2,5 @@
   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 9a66db3..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 3c5a708..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..eea927a
--- /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/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 a0c2c95..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,34 +102,27 @@
         </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/recent"
-            android:src="@drawable/status_bar_menu"
+            android:src="@drawable/ic_sysbar_menu"
+            android:background="@drawable/ic_sysbar_icon_bg"
             android:paddingLeft="4dip"
             android:paddingRight="4dip"
             systemui:keyCode="82"
             />
-        <Button android:id="@+id/recent"
+        <ImageButton android:id="@+id/recent"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:layout_toLeftOf="@+id/home"
-            android:background="@drawable/status_bar_recent"
+            android:src="@drawable/ic_sysbar_recent"
+            android:background="@drawable/ic_sysbar_icon_bg"
             android:paddingLeft="4dip"
             android:paddingRight="4dip"
             android:onClick="recentButtonClicked"
@@ -136,11 +130,36 @@
         <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 a32b01f..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;
@@ -84,7 +86,6 @@
     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 312c5f44..5dc46d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -33,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;
@@ -58,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;
@@ -78,6 +82,10 @@
 
     ImageView mBatteryMeter;
     ImageView mSignalMeter;
+    ImageView mSignalIcon;
+
+    View mBarContents;
+    View mCurtains;
 
     NotificationIconArea.IconLayout mIconLayout;
 
@@ -90,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,
@@ -116,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
@@ -147,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);
 
@@ -158,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();
@@ -209,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
         }
     }
 
@@ -710,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/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/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 6f23805..b6d725f 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -33,6 +33,7 @@
 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();
 
@@ -1469,12 +1452,20 @@
             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);
@@ -1557,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/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 12ae4ff..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;
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/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/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/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/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 36a2fcf..78ce473 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -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();
     }
 
     /**
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/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 7331e05..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() {
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 dd0c4e9..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/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 7554bd1..e1cbf5b 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -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
@@ -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
@@ -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();
     }
 
     /**
@@ -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();
     }
 
@@ -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
@@ -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:
@@ -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 5a20736..9cc44b5 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -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);
