Merge "Fix nullness annotation"
diff --git a/adtproductbuild/build.xml b/adtproductbuild/build.xml
index 7c1529b..e032e33 100644
--- a/adtproductbuild/build.xml
+++ b/adtproductbuild/build.xml
@@ -82,11 +82,11 @@
         <mkdir dir="${targetDir}/deltapack" />
         <mkdir dir="${targetDir}/repos" />
 
-        <unzip src="${deltaPackTargetSrcDir}/deltapack/eclipse-3.7.2-delta-pack.zip" dest="${targetDir}/deltapack" overwrite="false" />
-        <unzip src="${targetSrcDir}/platform/org.eclipse.platform-3.8.zip" dest="${targetDir}/repos/platform" overwrite="false" />
+        <unzip src="${deltaPackTargetSrcDir}/deltapack/eclipse-4.2.2-delta-pack.zip" dest="${targetDir}/deltapack" overwrite="false" />
+        <unzip src="${targetSrcDir}/platform/org.eclipse.platform-4.2.2.zip" dest="${targetDir}/repos/platform" overwrite="false" />
         <unzip src="${targetSrcDir}/cdt/cdt-master-8.0.2.zip" dest="${targetDir}/repos/cdt" overwrite="false" />
         <unzip src="${targetSrcDir}/emf/emf-xsd-SDK-M201201231045.zip" dest="${targetDir}/repos/emf" overwrite="false" />
-        <unzip src="${targetSrcDir}/jdt/org.eclipse.jdt.source-3.7.2.zip" dest="${targetDir}/repos/jdt" overwrite="false" />
+        <unzip src="${targetSrcDir}/jdt/org.eclipse.jdt.source-4.2.2.zip" dest="${targetDir}/repos/jdt" overwrite="false" />
         <unzip src="${targetSrcDir}/wtp/wtp-repo-R-3.3.2-20120210195245.zip" dest="${targetDir}/repos/wtp" overwrite="false" />
         <unzip src="${targetSrcDir}/gef/GEF-SDK-3.7.2.zip" dest="${targetDir}/repos/gef" overwrite="false" />
         <unzip src="${targetSrcDir}/pde/org.eclipse.pde-3.8.zip" dest="${targetDir}/repos/pde" overwrite="false" />
diff --git a/assetstudio/Android.mk b/assetstudio/Android.mk
index 17f9415..19e2d3c 100644
--- a/assetstudio/Android.mk
+++ b/assetstudio/Android.mk
@@ -34,7 +34,7 @@
 LOCAL_JAR_MANIFEST := etc/manifest.txt
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/build/tools.atree b/build/tools.atree
index b5a7edd..6772d69 100644
--- a/build/tools.atree
+++ b/build/tools.atree
@@ -23,107 +23,107 @@
 ##############################################################################
 
 # version files for the SDK updater, from sdk.git
-sdk/files/tools_source.properties tools/source.properties
+sdk/files/tools_source.properties                   tools/source.properties
 
 # copy plugin.prop from sdk.git
-sdk/files/plugin.prop tools/lib/plugin.prop
+sdk/files/plugin.prop                               tools/lib/plugin.prop
 
 # readme regarding adb move to platform-tools
-sdk/files/adb_has_moved.txt tools/adb_has_moved.txt
+sdk/files/adb_has_moved.txt                         tools/adb_has_moved.txt
 
 # native host tools from out/host/$(HOST_OS)-$(HOST_ARCH)/
-bin/sqlite3      strip tools/sqlite3
-bin/dmtracedump  strip tools/dmtracedump
-bin/etc1tool     strip tools/etc1tool
-bin/hprof-conv   strip tools/hprof-conv
-bin/mksdcard     strip tools/mksdcard
-bin/zipalign     strip tools/zipalign
+bin/sqlite3                                   strip tools/sqlite3
+bin/dmtracedump                               strip tools/dmtracedump
+bin/etc1tool                                  strip tools/etc1tool
+bin/hprof-conv                                strip tools/hprof-conv
+bin/mksdcard                                  strip tools/mksdcard
+bin/zipalign                                  strip tools/zipalign
 
 # emulator
-bin/emulator                         strip tools/emulator
-bin/emulator-x86                     strip tools/emulator-x86
-bin/emulator-arm                     strip tools/emulator-arm
-bin/emulator-mips                    strip tools/emulator-mips
-bin/emulator64-x86                   strip tools/emulator64-x86
-bin/emulator64-arm                   strip tools/emulator64-arm
-bin/emulator64-mips                  strip tools/emulator64-mips
-sdk/emulator/snapshot/snapshots.img  tools/lib/emulator/snapshots.img
-usr/share/pc-bios/bios.bin           tools/lib/pc-bios/bios.bin
-usr/share/pc-bios/vgabios-cirrus.bin tools/lib/pc-bios/vgabios-cirrus.bin
-sdk/emulator/skins/dynamic           tools/lib/emulator/skins/dynamic
+bin/emulator                                  strip tools/emulator
+bin/emulator-x86                              strip tools/emulator-x86
+bin/emulator-arm                              strip tools/emulator-arm
+bin/emulator-mips                             strip tools/emulator-mips
+bin/emulator64-x86                            strip tools/emulator64-x86
+bin/emulator64-arm                            strip tools/emulator64-arm
+bin/emulator64-mips                           strip tools/emulator64-mips
+sdk/emulator/snapshot/snapshots.img                 tools/lib/emulator/snapshots.img
+usr/share/pc-bios/bios.bin                          tools/lib/pc-bios/bios.bin
+usr/share/pc-bios/vgabios-cirrus.bin                tools/lib/pc-bios/vgabios-cirrus.bin
+sdk/emulator/skins/dynamic                          tools/lib/emulator/skins/dynamic
 
 # OpenGLES emulation libraries
-lib/libOpenglRender${DLL_EXTENSION}         strip tools/lib/libOpenglRender${DLL_EXTENSION}
-lib/libGLES_CM_translator${DLL_EXTENSION}   strip tools/lib/libGLES_CM_translator${DLL_EXTENSION}
-lib/libGLES_V2_translator${DLL_EXTENSION}   strip tools/lib/libGLES_V2_translator${DLL_EXTENSION}
-lib/libEGL_translator${DLL_EXTENSION}       strip tools/lib/libEGL_translator${DLL_EXTENSION}
-lib/lib64OpenglRender${DLL_EXTENSION}       strip tools/lib/lib64OpenglRender${DLL_EXTENSION}
-lib/lib64GLES_CM_translator${DLL_EXTENSION} strip tools/lib/lib64GLES_CM_translator${DLL_EXTENSION}
-lib/lib64GLES_V2_translator${DLL_EXTENSION} strip tools/lib/lib64GLES_V2_translator${DLL_EXTENSION}
-lib/lib64EGL_translator${DLL_EXTENSION}     strip tools/lib/lib64EGL_translator${DLL_EXTENSION}
+lib/libOpenglRender${DLL_EXTENSION}           strip tools/lib/libOpenglRender${DLL_EXTENSION}
+lib/libGLES_CM_translator${DLL_EXTENSION}     strip tools/lib/libGLES_CM_translator${DLL_EXTENSION}
+lib/libGLES_V2_translator${DLL_EXTENSION}     strip tools/lib/libGLES_V2_translator${DLL_EXTENSION}
+lib/libEGL_translator${DLL_EXTENSION}         strip tools/lib/libEGL_translator${DLL_EXTENSION}
+lib/lib64OpenglRender${DLL_EXTENSION}         strip tools/lib/lib64OpenglRender${DLL_EXTENSION}
+lib/lib64GLES_CM_translator${DLL_EXTENSION}   strip tools/lib/lib64GLES_CM_translator${DLL_EXTENSION}
+lib/lib64GLES_V2_translator${DLL_EXTENSION}   strip tools/lib/lib64GLES_V2_translator${DLL_EXTENSION}
+lib/lib64EGL_translator${DLL_EXTENSION}       strip tools/lib/lib64EGL_translator${DLL_EXTENSION}
 
 # Java-Based SDK Tools
-bin/ddms                            tools/ddms
-bin/hierarchyviewer                 tools/hierarchyviewer
-bin/draw9patch                      tools/draw9patch
-bin/traceview                       tools/traceview
-bin/android                         tools/android
-bin/monkeyrunner                    tools/monkeyrunner
-bin/uiautomatorviewer               tools/uiautomatorviewer
-prebuilts/devtools/etc/jobb         tools/jobb
-prebuilts/devtools/etc/lint         tools/lint
+bin/ddms                                            tools/ddms
+bin/hierarchyviewer                                 tools/hierarchyviewer
+bin/draw9patch                                      tools/draw9patch
+bin/traceview                                       tools/traceview
+bin/android                                         tools/android
+bin/monkeyrunner                                    tools/monkeyrunner
+bin/uiautomatorviewer                               tools/uiautomatorviewer
+prebuilts/devtools/tools/jobb                       tools/jobb
+prebuilts/devtools/tools/lint                       tools/lint
 
 # sdk.git Ant templates for project build files
-sdk/templates/build.template        tools/lib/build.template
-sdk/templates/uibuild.template      tools/lib/uibuild.template
-sdk/files/proguard-project.txt      tools/lib/proguard-project.txt
-sdk/files/proguard-android.txt      tools/proguard/proguard-android.txt
-sdk/files/proguard-android-optimize.txt      tools/proguard/proguard-android-optimize.txt
+sdk/templates/build.template                        tools/lib/build.template
+sdk/templates/uibuild.template                      tools/lib/uibuild.template
+sdk/files/proguard-project.txt                      tools/lib/proguard-project.txt
+sdk/files/proguard-android.txt                      tools/proguard/proguard-android.txt
+sdk/files/proguard-android-optimize.txt             tools/proguard/proguard-android-optimize.txt
 
 # Ant Build Rules
-sdk/files/ant                       tools/ant
-sdk/files/sdk_files_NOTICE.txt      tools/ant/NOTICE.txt
+sdk/files/ant                                       tools/ant
+sdk/files/sdk_files_NOTICE.txt                      tools/ant/NOTICE.txt
 
 # layout device definition
-sdk/files/devices.xml               tools/lib/devices.xml
+sdk/files/devices.xml                               tools/lib/devices.xml
 
 # AVD Hardware property list
-external/qemu/android/avd/hardware-properties.ini tools/lib/hardware-properties.ini
+external/qemu/android/avd/hardware-properties.ini   tools/lib/hardware-properties.ini
 
 # emacs support from sdk.git
 sdk/files/android.el tools/lib/android.el
 
 # Java Libraries for the tools
-prebuilts/devtools/common.jar             tools/lib/common.jar
-prebuilts/devtools/swtmenubar.jar         tools/lib/swtmenubar.jar
-sdk/apkbuilder/etc/apkbuilder             tools/apkbuilder
-framework/sdkstats.jar                    tools/lib/sdkstats.jar
-framework/archquery.jar                   tools/lib/archquery.jar
-framework/ddms.jar                        tools/lib/ddms.jar
-prebuilts/devtools/ddmlib.jar             tools/lib/ddmlib.jar
-framework/ddmuilib.jar                    tools/lib/ddmuilib.jar
-framework/hierarchyviewer2.jar            tools/lib/hierarchyviewer2.jar
-framework/hierarchyviewerlib.jar          tools/lib/hierarchyviewerlib.jar
-framework/draw9patch.jar                  tools/lib/draw9patch.jar
-framework/traceview.jar                   tools/lib/traceview.jar
-framework/anttasks.jar                    tools/lib/anttasks.jar
-prebuilts/devtools/sdklib.jar             tools/lib/sdklib.jar
-prebuilts/devtools/sdkuilib.jar           tools/lib/sdkuilib.jar
-framework/sdkmanager.jar                  tools/lib/sdkmanager.jar
-framework/monkeyrunner.jar                tools/lib/monkeyrunner.jar
-framework/chimpchat.jar                   tools/lib/chimpchat.jar
-framework/guava-tools.jar                 tools/lib/guava-tools.jar
-framework/jsilver.jar                     tools/lib/jsilver.jar
-framework/jython.jar                      tools/lib/jython.jar
-prebuilts/devtools/lint.jar               tools/lib/lint.jar
-prebuilts/devtools/lint_api.jar           tools/lib/lint_api.jar
-prebuilts/devtools/lint_checks.jar        tools/lib/lint_checks.jar
-prebuilts/devtools/manifmerger.jar        tools/lib/manifmerger.jar
-prebuilts/devtools/dvlib.jar              tools/lib/dvlib.jar
-prebuilts/devtools/layoutlib_api.jar      tools/lib/layoutlib_api.jar
-framework/uiautomatorviewer.jar           tools/lib/uiautomatorviewer.jar
-prebuilts/devtools/jobb.jar               tools/lib/jobb.jar
-framework/fat32lib.jar                    tools/lib/fat32lib.jar
+prebuilts/devtools/tools/lib/common.jar             tools/lib/common.jar
+prebuilts/devtools/tools/lib/swtmenubar.jar         tools/lib/swtmenubar.jar
+sdk/apkbuilder/etc/apkbuilder                       tools/apkbuilder
+framework/sdkstats.jar                              tools/lib/sdkstats.jar
+framework/archquery.jar                             tools/lib/archquery.jar
+framework/ddms.jar                                  tools/lib/ddms.jar
+prebuilts/devtools/tools/lib/ddmlib.jar             tools/lib/ddmlib.jar
+framework/ddmuilib.jar                              tools/lib/ddmuilib.jar
+framework/hierarchyviewer2.jar                      tools/lib/hierarchyviewer2.jar
+framework/hierarchyviewerlib.jar                    tools/lib/hierarchyviewerlib.jar
+framework/draw9patch.jar                            tools/lib/draw9patch.jar
+framework/traceview.jar                             tools/lib/traceview.jar
+framework/anttasks.jar                              tools/lib/anttasks.jar
+prebuilts/devtools/tools/lib/sdklib.jar             tools/lib/sdklib.jar
+prebuilts/devtools/tools/lib/sdkuilib.jar           tools/lib/sdkuilib.jar
+framework/sdkmanager.jar                            tools/lib/sdkmanager.jar
+framework/monkeyrunner.jar                          tools/lib/monkeyrunner.jar
+framework/chimpchat.jar                             tools/lib/chimpchat.jar
+framework/guava-tools.jar                           tools/lib/guava-tools.jar
+framework/jsilver.jar                               tools/lib/jsilver.jar
+framework/jython.jar                                tools/lib/jython.jar
+prebuilts/devtools/tools/lib/lint.jar               tools/lib/lint.jar
+prebuilts/devtools/tools/lib/lint_api.jar           tools/lib/lint_api.jar
+prebuilts/devtools/tools/lib/lint_checks.jar        tools/lib/lint_checks.jar
+prebuilts/devtools/tools/lib/manifmerger.jar        tools/lib/manifmerger.jar
+prebuilts/devtools/tools/lib/dvlib.jar              tools/lib/dvlib.jar
+prebuilts/devtools/tools/lib/layoutlib_api.jar      tools/lib/layoutlib_api.jar
+framework/uiautomatorviewer.jar                     tools/lib/uiautomatorviewer.jar
+prebuilts/devtools/tools/lib/jobb.jar               tools/lib/jobb.jar
+framework/fat32lib.jar                              tools/lib/fat32lib.jar
 prebuilts/tools/common/mkidentity/mkidentity-prebuilt.jar tools/lib/mkidentity.jar
 
 # 3rd Party java libraries
@@ -163,31 +163,31 @@
 prebuilts/tools/common/proguard/proguard4.7/src/proguard/ant/task.properties  tools/proguard/ant/task.properties
 
 # Templates
-sdk/templates/projects                   tools/templates/projects
-sdk/templates/activities                 tools/templates/activities
-sdk/templates/other                      tools/templates/other
+sdk/templates/projects                  tools/templates/projects
+sdk/templates/activities                tools/templates/activities
+sdk/templates/other                     tools/templates/other
 
 # SDK Controller
-sdk/apps/SdkController       tools/apps/SdkController
+sdk/apps/SdkController                  tools/apps/SdkController
 
 # tools specific support jar
-framework/annotations.jar   tools/support/annotations.jar
+framework/annotations.jar               tools/support/annotations.jar
 
 # systrace
-external/chromium-trace/systrace.py    tools/systrace/systrace.py
-external/chromium-trace/script.js      tools/systrace/script.js
-external/chromium-trace/style.css      tools/systrace/style.css
-external/chromium-trace/LICENSE        tools/systrace/LICENSE
-external/chromium-trace/AUTHORS        tools/systrace/AUTHORS
-external/chromium-trace/NOTICE         tools/systrace/NOTICE
+external/chromium-trace/systrace.py     tools/systrace/systrace.py
+external/chromium-trace/script.js       tools/systrace/script.js
+external/chromium-trace/style.css       tools/systrace/style.css
+external/chromium-trace/LICENSE         tools/systrace/LICENSE
+external/chromium-trace/AUTHORS         tools/systrace/AUTHORS
+external/chromium-trace/NOTICE          tools/systrace/NOTICE
 
 # Misspelling databases for lint
-sdk/files/typos                        tools/support
+sdk/files/typos                         tools/support
 
 ##############################################################################
 # Tests Component
 ##############################################################################
 
-sdk/testapps                      tests/testapps
-framework/ninepatch-tests.jar     tests/libtests/ninepatch-tests.jar
+sdk/testapps                            tests/testapps
+framework/ninepatch-tests.jar           tests/libtests/ninepatch-tests.jar
 
diff --git a/build/tools.windows.atree b/build/tools.windows.atree
index 3a84ff8..f64b374 100755
--- a/build/tools.windows.atree
+++ b/build/tools.windows.atree
@@ -37,10 +37,10 @@
 sdk/draw9patch/etc/draw9patch.bat                 tools/draw9patch.bat
 
 rm tools/lint
-prebuilts/devtools/etc/lint.bat                   tools/lint.bat
+prebuilts/devtools/tools/lint.bat                 tools/lint.bat
 
 rm tools/jobb
-prebuilts/devtools/etc/jobb.bat                   tools/jobb.bat
+prebuilts/devtools/tools/jobb.bat                 tools/jobb.bat
 
 
 rm tools/emulator
@@ -56,10 +56,10 @@
 rm tools/lib/libGLES_CM_translator.so
 rm tools/lib/libGLES_V2_translator.so
 rm tools/lib/libEGL_translator.so
-lib/libOpenglRender.dll          tools/lib/libOpenglRender.dll
-lib/libGLES_CM_translator.dll    tools/lib/libGLES_CM_translator.dll
-lib/libGLES_V2_translator.dll    tools/lib/libGLES_V2_translator.dll
-lib/libEGL_translator.dll        tools/lib/libEGL_translator.dll
+lib/libOpenglRender.dll                           tools/lib/libOpenglRender.dll
+lib/libGLES_CM_translator.dll                     tools/lib/libGLES_CM_translator.dll
+lib/libGLES_V2_translator.dll                     tools/lib/libGLES_V2_translator.dll
+lib/libEGL_translator.dll                         tools/lib/libEGL_translator.dll
 # Copy the emulator NOTICE in the tools dir
 external/qemu/NOTICE                              tools/emulator_NOTICE.txt
 
diff --git a/common/Android.mk b/common/Android.mk
index dc098fd..f7ba3c1 100644
--- a/common/Android.mk
+++ b/common/Android.mk
@@ -30,7 +30,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/ddms/libs/ddmlib/Android.mk b/ddms/libs/ddmlib/Android.mk
index c5ad99e..74ee46a 100644
--- a/ddms/libs/ddmlib/Android.mk
+++ b/ddms/libs/ddmlib/Android.mk
@@ -26,7 +26,7 @@
 LOCAL_JAVA_LIBRARIES := kxml2-2.3.0
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/device_validator/dvlib/Android.mk b/device_validator/dvlib/Android.mk
index 8d07043..658c69b 100644
--- a/device_validator/dvlib/Android.mk
+++ b/device_validator/dvlib/Android.mk
@@ -27,7 +27,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlAutoEditStrategy.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlAutoEditStrategy.java
index c5aa8cd..8a078ef 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlAutoEditStrategy.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlAutoEditStrategy.java
@@ -24,7 +24,7 @@
 
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences;
 import com.android.utils.Pair;
 
 import org.eclipse.jface.text.BadLocationException;
@@ -148,7 +148,7 @@
 
                         StringBuilder sb = new StringBuilder(c.text);
                         sb.append(lineIndent);
-                        String oneIndentUnit = XmlFormatPreferences.create().getOneIndentUnit();
+                        String oneIndentUnit = EclipseXmlFormatPreferences.create().getOneIndentUnit();
                         if (addIndent) {
                             sb.append(oneIndentUnit);
                         }
@@ -276,7 +276,7 @@
                                     }
 
                                     if (addIndent) {
-                                        sb.append(XmlFormatPreferences.create()
+                                        sb.append(EclipseXmlFormatPreferences.create()
                                                 .getOneIndentUnit());
                                     }
                                     c.text = sb.toString();
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategy.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategy.java
index 7c7b2cb..94c5299 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategy.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategy.java
@@ -29,6 +29,9 @@
 
 import com.android.SdkConstants;
 import com.android.annotations.VisibleForTesting;
+import com.android.ide.common.xml.XmlFormatPreferences;
+import com.android.ide.common.xml.XmlFormatStyle;
+import com.android.ide.common.xml.XmlPrettyPrinter;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.AdtUtils;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
@@ -78,7 +81,7 @@
  * Formatter which formats XML content according to the established Android coding
  * conventions. It performs the format by computing the smallest set of DOM nodes
  * overlapping the formatted region, then it pretty-prints that XML region
- * using the {@link XmlPrettyPrinter}, and then it replaces the affected region
+ * using the {@link EclipseXmlPrettyPrinter}, and then it replaces the affected region
  * by the pretty-printed region.
  * <p>
  * This strategy is also used for delegation. If the user has chosen to use the
@@ -332,7 +335,7 @@
         }
 
         XmlFormatStyle style = guessStyle(model, domDocument);
-        XmlFormatPreferences prefs = XmlFormatPreferences.create();
+        XmlFormatPreferences prefs = EclipseXmlFormatPreferences.create();
         String delimiter = TextUtilities.getDefaultLineDelimiter(document);
         XmlPrettyPrinter printer = new XmlPrettyPrinter(prefs, style, delimiter);
 
@@ -517,7 +520,10 @@
     static XmlFormatStyle guessStyle(IStructuredModel model, Document domDocument) {
         // The "layout" style is used for most XML resource file types:
         // layouts, color-lists and state-lists, animations, drawables, menus, etc
-        XmlFormatStyle style = XmlFormatStyle.LAYOUT;
+        XmlFormatStyle style = XmlFormatStyle.get(domDocument);
+        if (style == XmlFormatStyle.FILE) {
+            style = XmlFormatStyle.LAYOUT;
+        }
 
         // The "resource" style is used for most value-based XML files:
         // strings, dimensions, booleans, colors, integers, plurals,
@@ -546,7 +552,7 @@
                     String[] segments = resourceFolder.split("-"); //$NON-NLS-1$
                     ResourceType type = ResourceType.getEnum(segments[0]);
                     if (type != null) {
-                        style = XmlFormatStyle.get(type);
+                        style = EclipseXmlPrettyPrinter.get(type);
                     }
                 }
             }
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlFormatPreferences.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlFormatPreferences.java
similarity index 70%
rename from eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlFormatPreferences.java
rename to eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlFormatPreferences.java
index 05c8a7f..6c00b8e 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlFormatPreferences.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlFormatPreferences.java
@@ -16,61 +16,40 @@
 package com.android.ide.eclipse.adt.internal.editors.formatting;
 
 import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
 import com.android.annotations.VisibleForTesting;
+import com.android.ide.common.xml.XmlFormatPreferences;
 import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
-import com.android.ide.eclipse.adt.internal.preferences.AttributeSortOrder;
+import com.android.ide.common.xml.XmlAttributeSortOrder;
 
 import org.eclipse.core.runtime.Preferences;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.ui.internal.editors.text.EditorsPlugin;
 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
 import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
 import org.eclipse.wst.xml.core.internal.preferences.XMLCorePreferenceNames;
+import org.w3c.dom.Attr;
+
+import java.util.Comparator;
 
 /**
  * Formatting preferences used by the Android XML formatter.
  */
-public class XmlFormatPreferences {
-    /** Use the Eclipse indent (tab/space, indent size) settings? */
-    public boolean useEclipseIndent = false;
-
-    /** Remove empty lines in all cases? */
-    public boolean removeEmptyLines = false;
-
-    /** Reformat the text and comment blocks? */
-    public boolean reflowText = false;
-
-    /** Join lines when reformatting text and comment blocks? */
-    public boolean joinLines = false;
-
-    /** Can attributes appear on the same line as the opening line if there is just one of them? */
-    public boolean oneAttributeOnFirstLine = true;
-
-    /** The sorting order to use when formatting */
-    public AttributeSortOrder sortAttributes = AttributeSortOrder.LOGICAL;
-
-    /** Should there be a space before the closing > or /> ? */
-    public boolean spaceBeforeClose = true;
-
-    /** The string to insert for each indentation level */
-    private String mOneIndentUnit = "    "; //$NON-NLS-1$
-
-    /** Tab width (number of spaces to display for a tab) */
-    private int mTabWidth = -1; // -1: uninitialized
-
+public class EclipseXmlFormatPreferences extends XmlFormatPreferences {
     @VisibleForTesting
-    protected XmlFormatPreferences() {
+    protected EclipseXmlFormatPreferences() {
     }
 
     /**
-     * Creates a new {@link XmlFormatPreferences} based on the current settings
+     * Creates a new {@link EclipseXmlFormatPreferences} based on the current settings
      * in {@link AdtPrefs}
      *
-     * @return an {@link XmlFormatPreferences} object
+     * @return an {@link EclipseXmlFormatPreferences} object
      */
     @NonNull
-    public static XmlFormatPreferences create() {
-        XmlFormatPreferences p = new XmlFormatPreferences();
+    public static EclipseXmlFormatPreferences create() {
+        EclipseXmlFormatPreferences p = new EclipseXmlFormatPreferences();
         AdtPrefs prefs = AdtPrefs.getPrefs();
 
         p.useEclipseIndent = prefs.isUseEclipseIndent();
@@ -82,24 +61,37 @@
         return p;
     }
 
-    /**
-     * Returns a new preferences object initialized with the defaults
-     *
-     * @return an {@link XmlFormatPreferences} object
-     */
-    @NonNull
-    static XmlFormatPreferences defaults() {
-        return new XmlFormatPreferences();
+    @Override
+    @Nullable
+    public Comparator<Attr> getAttributeComparator() {
+        // Can't just skip sorting; the attribute table moves attributes out of order
+        // due to hashing, so sort by node positions
+        if (sortAttributes == XmlAttributeSortOrder.NO_SORTING) {
+            return EXISTING_ORDER_COMPARATOR;
+        }
+        return sortAttributes.getAttributeComparator();
     }
 
+    private static final Comparator<Attr> EXISTING_ORDER_COMPARATOR = new Comparator<Attr>() {
+        @Override
+        public int compare(Attr attr1, Attr attr2) {
+            IndexedRegion region1 = (IndexedRegion) attr1;
+            IndexedRegion region2 = (IndexedRegion) attr2;
+
+            return region1.getStartOffset() - region2.getStartOffset();
+        }
+    };
+
     // The XML module settings do not have a public API. We should replace this with JDT
     // settings anyway since that's more likely what users have configured and want applied
     // to their XML files
+
     /**
      * Returns the string to use to indent one indentation level
      *
      * @return the string used to indent one indentation level
      */
+    @Override
     @SuppressWarnings({
             "restriction", "deprecation"
     })
@@ -131,6 +123,7 @@
      *
      * @return the number of spaces used to display a single tab character
      */
+    @Override
     @SuppressWarnings("restriction") // Editor settings
     public int getTabWidth() {
         if (mTabWidth == -1) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinter.java
new file mode 100644
index 0000000..2051e5a
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinter.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ide.eclipse.adt.internal.editors.formatting;
+
+import com.android.SdkConstants;
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.ide.common.xml.XmlFormatPreferences;
+import com.android.ide.common.xml.XmlFormatStyle;
+import com.android.ide.common.xml.XmlPrettyPrinter;
+import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
+import com.android.resources.ResourceFolderType;
+import com.android.resources.ResourceType;
+import com.android.utils.SdkUtils;
+import com.android.utils.XmlUtils;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Eclipse customization of the {@link EclipseXmlPrettyPrinter} which takes advantage of the
+ * Eclipse DOM Api to track additional information, such as whether an element with no children
+ * was of the open form ({@code <foo></foo>}) or the closed form ({@code <foo/>}), the ability to
+ * look up the original source (for proper entity handling), the ability to preserve attribute
+ * source order, etc.
+ */
+@SuppressWarnings("restriction") // WST XML API
+public class EclipseXmlPrettyPrinter extends XmlPrettyPrinter {
+
+    /**
+     * Creates a new {@link com.android.ide.common.xml.XmlPrettyPrinter}
+     *
+     * @param prefs         the preferences to format with
+     * @param style         the style to format with
+     * @param lineSeparator the line separator to use, such as "\n" (can be null, in which case the
+     *                      system default is looked up via the line.separator property)
+     */
+    public EclipseXmlPrettyPrinter(
+            XmlFormatPreferences prefs,
+            XmlFormatStyle style,
+            String lineSeparator) {
+        super(prefs, style, lineSeparator);
+    }
+
+    /**
+     * Pretty-prints the given XML document, which must be well-formed. If it is not,
+     * the original unformatted XML document is returned
+     *
+     * @param xml the XML content to format
+     * @param prefs the preferences to format with
+     * @param style the style to format with
+     * @param lineSeparator the line separator to use, such as "\n" (can be null, in which
+     *     case the system default is looked up via the line.separator property)
+     * @return the formatted document (or if a parsing error occurred, returns the
+     *     unformatted document)
+     */
+    @NonNull
+    public static String prettyPrint(
+            @NonNull String xml,
+            @NonNull XmlFormatPreferences prefs,
+            @NonNull XmlFormatStyle style,
+            @Nullable String lineSeparator) {
+        Document document = DomUtilities.parseStructuredDocument(xml);
+        if (document != null) {
+            EclipseXmlPrettyPrinter printer = new EclipseXmlPrettyPrinter(prefs, style,
+                    lineSeparator);
+            StringBuilder sb = new StringBuilder(3 * xml.length() / 2);
+            printer.prettyPrint(-1, document, null, null, sb, false /*openTagOnly*/);
+            return sb.toString();
+        } else {
+            // Parser error: just return the unformatted content
+            return xml;
+        }
+    }
+
+    @NonNull
+    public static String prettyPrint(@NonNull Node node) {
+        return prettyPrint(node, EclipseXmlFormatPreferences.create(), XmlFormatStyle.get(node),
+                SdkUtils.getLineSeparator());
+    }
+
+    /**
+     * Pretty prints the given node
+     *
+     * @param node the node, usually a document, to be printed
+     * @param prefs the formatting preferences
+     * @param style the formatting style to use
+     * @param lineSeparator the line separator to use, or null to use the
+     *            default
+     * @return a formatted string
+     */
+    @NonNull
+    public static String prettyPrint(
+            @NonNull Node node,
+            @NonNull XmlFormatPreferences prefs,
+            @NonNull XmlFormatStyle style,
+            @Nullable String lineSeparator) {
+        XmlPrettyPrinter printer = new EclipseXmlPrettyPrinter(prefs, style, lineSeparator);
+        StringBuilder sb = new StringBuilder(1000);
+        printer.prettyPrint(-1, node, null, null, sb, false /*openTagOnly*/);
+        String xml = sb.toString();
+        if (node.getNodeType() == Node.DOCUMENT_NODE && !xml.startsWith("<?")) { //$NON-NLS-1$
+            xml = XmlUtils.XML_PROLOG + xml;
+        }
+        return xml;
+    }
+
+    @Nullable
+    @Override
+    protected String getSource(@NonNull Node node) {
+        // In Eclipse, org.w3c.dom.DocumentType.getTextContent() returns null
+        if (node instanceof IDOMNode) {
+            // Get the original source string. This will contain the actual entities
+            // such as "&gt;" instead of ">" which it gets turned into for the DOM nodes.
+            // By operating on source we can preserve the user's entities rather than
+            // having &gt; for example always turned into >.
+            IDOMNode textImpl = (IDOMNode) node;
+            return textImpl.getSource();
+        }
+
+        return super.getSource(node);
+    }
+
+    @Override
+    protected boolean isEmptyTag(Element element) {
+        if (element instanceof IDOMElement) {
+            IDOMElement elementImpl = (IDOMElement) element;
+            if (elementImpl.isEmptyTag()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the {@link XmlFormatStyle} to use for a resource of the given type
+     *
+     * @param resourceType the type of resource to be formatted
+     * @return the suitable format style to use
+     */
+    public static XmlFormatStyle get(ResourceType resourceType) {
+        switch (resourceType) {
+            case ARRAY:
+            case ATTR:
+            case BOOL:
+            case DECLARE_STYLEABLE:
+            case DIMEN:
+            case FRACTION:
+            case ID:
+            case INTEGER:
+            case STRING:
+            case PLURALS:
+            case STYLE:
+            case STYLEABLE:
+            case COLOR:
+                return XmlFormatStyle.RESOURCE;
+
+            case LAYOUT:
+                return XmlFormatStyle.LAYOUT;
+
+            case DRAWABLE:
+            case MENU:
+            case ANIM:
+            case ANIMATOR:
+            case INTERPOLATOR:
+            default:
+                return XmlFormatStyle.FILE;
+        }
+    }
+
+    /**
+     * Returns the {@link XmlFormatStyle} to use for resource files in the given resource
+     * folder
+     *
+     * @param folderType the type of folder containing the resource file
+     * @return the suitable format style to use
+     */
+    public static XmlFormatStyle getForFolderType(ResourceFolderType folderType) {
+        switch (folderType) {
+            case LAYOUT:
+                return XmlFormatStyle.LAYOUT;
+            case COLOR:
+            case VALUES:
+                return XmlFormatStyle.RESOURCE;
+            case ANIM:
+            case ANIMATOR:
+            case DRAWABLE:
+            case INTERPOLATOR:
+            case MENU:
+            default:
+                return XmlFormatStyle.FILE;
+        }
+    }
+
+    /**
+     * Returns the {@link XmlFormatStyle} to use for resource files of the given path.
+     *
+     * @param path the path to the resource file
+     * @return the suitable format style to use
+     */
+    public static XmlFormatStyle getForFile(IPath path) {
+        if (SdkConstants.FN_ANDROID_MANIFEST_XML.equals(path.lastSegment())) {
+            return XmlFormatStyle.MANIFEST;
+        }
+
+        if (path.segmentCount() > 2) {
+            String parentName = path.segment(path.segmentCount() - 2);
+            ResourceFolderType folderType = ResourceFolderType.getFolderType(parentName);
+            return getForFolderType(folderType);
+        }
+
+        return XmlFormatStyle.FILE;
+    }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlFormatStyle.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlFormatStyle.java
deleted file mode 100644
index cb6ee5d..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlFormatStyle.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ide.eclipse.adt.internal.editors.formatting;
-
-import com.android.SdkConstants;
-import com.android.resources.ResourceFolderType;
-import com.android.resources.ResourceType;
-
-import org.eclipse.core.runtime.IPath;
-
-/**
- * Style to use when printing the XML. Different types of Android XML files use slightly
- * different preferred formats. For example, in layout files there is typically always a
- * newline between successive elements, whereas in a manifest file there is typically only
- * newlines between different types of elements. As another example, in resource files,
- * the format is typically much more compact: the text content of {@code <item>} tags is
- * included on the same line whereas for other layout styles the children are typically
- * placed on a line of their own.
- */
-public enum XmlFormatStyle {
-    /** Layout formatting style: blank lines between elements, attributes on separate lines */
-    LAYOUT,
-
-    /** Similar to layout formatting style, but no blank lines inside opening elements */
-    FILE,
-
-    /** Resource style: one line per complete element including text child content */
-    RESOURCE,
-
-    /**
-     * Similar to layout style, but no newlines between related elements such as
-     * successive {@code <uses-permission>} declarations, and no newlines inside
-     * the second level elements (so an {@code <activity>} declaration appears as a
-     * single block with no whitespace within it)
-     */
-    MANIFEST;
-
-    /**
-     * Returns the {@link XmlFormatStyle} to use for a resource of the given type
-     *
-     * @param resourceType the type of resource to be formatted
-     * @return the suitable format style to use
-     */
-    public static XmlFormatStyle get(ResourceType resourceType) {
-        switch (resourceType) {
-            case ARRAY:
-            case ATTR:
-            case BOOL:
-            case DECLARE_STYLEABLE:
-            case DIMEN:
-            case FRACTION:
-            case ID:
-            case INTEGER:
-            case STRING:
-            case PLURALS:
-            case STYLE:
-            case STYLEABLE:
-            case COLOR:
-                return RESOURCE;
-
-            case LAYOUT:
-                return LAYOUT;
-
-            case DRAWABLE:
-            case MENU:
-            case ANIM:
-            case ANIMATOR:
-            case INTERPOLATOR:
-            default:
-                return FILE;
-        }
-    }
-
-    /**
-     * Returns the {@link XmlFormatStyle} to use for resource files in the given resource
-     * folder
-     *
-     * @param folderType the type of folder containing the resource file
-     * @return the suitable format style to use
-     */
-    public static XmlFormatStyle getForFolderType(ResourceFolderType folderType) {
-        switch (folderType) {
-            case LAYOUT:
-                return LAYOUT;
-            case COLOR:
-            case VALUES:
-                return RESOURCE;
-            case ANIM:
-            case ANIMATOR:
-            case DRAWABLE:
-            case INTERPOLATOR:
-            case MENU:
-            default:
-                return FILE;
-        }
-    }
-
-    /**
-     * Returns the {@link XmlFormatStyle} to use for resource files of the given path.
-     *
-     * @param path the path to the resource file
-     * @return the suitable format style to use
-     */
-    public static XmlFormatStyle getForFile(IPath path) {
-        if (SdkConstants.FN_ANDROID_MANIFEST_XML.equals(path.lastSegment())) {
-            return MANIFEST;
-        }
-
-        if (path.segmentCount() > 2) {
-            String parentName = path.segment(path.segmentCount() - 2);
-            ResourceFolderType folderType = ResourceFolderType.getFolderType(parentName);
-            return getForFolderType(folderType);
-        }
-
-        return FILE;
-    }
-}
\ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlPrettyPrinter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlPrettyPrinter.java
deleted file mode 100644
index 969d45a..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlPrettyPrinter.java
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ide.eclipse.adt.internal.editors.formatting;
-
-import static com.android.SdkConstants.TAG_COLOR;
-import static com.android.SdkConstants.TAG_DIMEN;
-import static com.android.SdkConstants.TAG_ITEM;
-import static com.android.SdkConstants.TAG_STRING;
-import static com.android.SdkConstants.TAG_STYLE;
-import static com.android.SdkConstants.XMLNS;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
-import com.android.utils.SdkUtils;
-import com.android.utils.XmlUtils;
-
-import org.eclipse.wst.xml.core.internal.document.DocumentTypeImpl;
-import org.eclipse.wst.xml.core.internal.document.ElementImpl;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
-import org.w3c.dom.Attr;
-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 java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Visitor which walks over the subtree of the DOM to be formatted and pretty prints
- * the DOM into the given {@link StringBuilder}
- */
-@SuppressWarnings("restriction")
-public class XmlPrettyPrinter {
-    private static final String COMMENT_BEGIN = "<!--"; //$NON-NLS-1$
-    private static final String COMMENT_END = "-->";    //$NON-NLS-1$
-
-    /** The style to print the XML in */
-    private final XmlFormatStyle mStyle;
-    /** Formatting preferences to use when formatting the XML */
-    private final XmlFormatPreferences mPrefs;
-    /** Start node to start formatting at */
-    private Node mStartNode;
-    /** Start node to stop formatting after */
-    private Node mEndNode;
-    /** Whether the visitor is currently in range */
-    private boolean mInRange;
-    /** Output builder */
-    private StringBuilder mOut;
-    /** String to insert for a single indentation level */
-    private String mIndentString;
-    /** Line separator to use */
-    private String mLineSeparator;
-    /** If true, we're only formatting an open tag */
-    private boolean mOpenTagOnly;
-    /** List of indentation to use for each given depth */
-    private String[] mIndentationLevels;
-
-    /**
-     * Creates a new {@link XmlPrettyPrinter}
-     *
-     * @param prefs the preferences to format with
-     * @param style the style to format with
-     * @param lineSeparator the line separator to use, such as "\n" (can be null, in which
-     *            case the system default is looked up via the line.separator property)
-     */
-    public XmlPrettyPrinter(XmlFormatPreferences prefs, XmlFormatStyle style,
-            String lineSeparator) {
-        mPrefs = prefs;
-        mStyle = style;
-        if (lineSeparator == null) {
-            lineSeparator = SdkUtils.getLineSeparator();
-        }
-        mLineSeparator = lineSeparator;
-    }
-
-    /**
-     * Sets the indentation levels to use (indentation string to use for each depth,
-     * indexed by depth
-     *
-     * @param indentationLevels an array of strings to use for the various indentation
-     *            levels
-     */
-    public void setIndentationLevels(String[] indentationLevels) {
-        mIndentationLevels = indentationLevels;
-    }
-
-    /**
-     * Pretty-prints the given XML document, which must be well-formed. If it is not,
-     * the original unformatted XML document is returned
-     *
-     * @param xml the XML content to format
-     * @param prefs the preferences to format with
-     * @param style the style to format with
-     * @param lineSeparator the line separator to use, such as "\n" (can be null, in which
-     *     case the system default is looked up via the line.separator property)
-     * @return the formatted document (or if a parsing error occurred, returns the
-     *     unformatted document)
-     */
-    @NonNull
-    public static String prettyPrint(
-            @NonNull String xml,
-            @NonNull XmlFormatPreferences prefs,
-            @NonNull XmlFormatStyle style,
-            @Nullable String lineSeparator) {
-        Document document = DomUtilities.parseStructuredDocument(xml);
-        if (document != null) {
-            XmlPrettyPrinter printer = new XmlPrettyPrinter(prefs, style, lineSeparator);
-            StringBuilder sb = new StringBuilder(3 * xml.length() / 2);
-            printer.prettyPrint(-1, document, null, null, sb, false /*openTagOnly*/);
-            return sb.toString();
-        } else {
-            // Parser error: just return the unformatted content
-            return xml;
-        }
-    }
-
-    /**
-     * Pretty prints the given node
-     *
-     * @param node the node, usually a document, to be printed
-     * @param prefs the formatting preferences
-     * @param style the formatting style to use
-     * @param lineSeparator the line separator to use, or null to use the
-     *            default
-     * @return a formatted string
-     */
-    @NonNull
-    public static String prettyPrint(
-            @NonNull Node node,
-            @NonNull XmlFormatPreferences prefs,
-            @NonNull XmlFormatStyle style,
-            @Nullable String lineSeparator) {
-        XmlPrettyPrinter printer = new XmlPrettyPrinter(prefs, style, lineSeparator);
-        StringBuilder sb = new StringBuilder(1000);
-        printer.prettyPrint(-1, node, null, null, sb, false /*openTagOnly*/);
-        String xml = sb.toString();
-        if (node.getNodeType() == Node.DOCUMENT_NODE && !xml.startsWith("<?")) { //$NON-NLS-1$
-            xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + xml; //$NON-NLS-1$
-        }
-        return xml;
-    }
-
-    /**
-     * Pretty prints the given node using default styles
-     *
-     * @param node the node, usually a document, to be printed
-     * @return the resulting formatted string
-     */
-    @NonNull
-    public static String prettyPrint(@NonNull Node node) {
-        return prettyPrint(node, XmlFormatPreferences.create(), XmlFormatStyle.FILE,
-                SdkUtils.getLineSeparator());
-    }
-
-    /**
-     * Start pretty-printing at the given node, which must either be the
-     * startNode or contain it as a descendant.
-     *
-     * @param rootDepth the depth of the given node, used to determine indentation
-     * @param root the node to start pretty printing from (which may not itself be
-     *            included in the start to end node range but should contain it)
-     * @param startNode the node to start formatting at
-     * @param endNode the node to end formatting at
-     * @param out the {@link StringBuilder} to pretty print into
-     * @param openTagOnly if true, only format the open tag of the startNode (and nothing
-     *     else)
-     */
-    public void prettyPrint(int rootDepth, Node root, Node startNode, Node endNode,
-            StringBuilder out, boolean openTagOnly) {
-        if (startNode == null) {
-            startNode = root;
-        }
-        if (endNode == null) {
-            endNode = root;
-        }
-        assert !openTagOnly || startNode == endNode;
-
-        mStartNode = startNode;
-        mOpenTagOnly = openTagOnly;
-        mEndNode = endNode;
-        mOut = out;
-        mInRange = false;
-        mIndentString = mPrefs.getOneIndentUnit();
-
-        visitNode(rootDepth, root);
-    }
-
-    /** Visit the given node at the given depth */
-    private void visitNode(int depth, Node node) {
-        if (node == mStartNode) {
-            mInRange = true;
-        }
-
-        if (mInRange) {
-            visitBeforeChildren(depth, node);
-            if (mOpenTagOnly && mStartNode == node) {
-                mInRange = false;
-                return;
-            }
-        }
-
-        NodeList children = node.getChildNodes();
-        for (int i = 0, n = children.getLength(); i < n; i++) {
-            Node child = children.item(i);
-            visitNode(depth + 1, child);
-        }
-
-        if (mInRange) {
-            visitAfterChildren(depth, node);
-        }
-
-        if (node == mEndNode) {
-            mInRange = false;
-        }
-    }
-
-    private void visitBeforeChildren(int depth, Node node) {
-        short type = node.getNodeType();
-        switch (type) {
-            case Node.DOCUMENT_NODE:
-            case Node.DOCUMENT_FRAGMENT_NODE:
-                // Nothing to do
-                break;
-
-            case Node.ATTRIBUTE_NODE:
-                // Handled as part of processing elements
-                break;
-
-            case Node.ELEMENT_NODE: {
-                printOpenElementTag(depth, node);
-                break;
-            }
-
-            case Node.TEXT_NODE: {
-                printText(node);
-                break;
-            }
-
-            case Node.CDATA_SECTION_NODE:
-                printCharacterData(depth, node);
-                break;
-
-            case Node.PROCESSING_INSTRUCTION_NODE:
-                printProcessingInstruction(node);
-                break;
-
-            case Node.COMMENT_NODE: {
-                printComment(depth, node);
-                break;
-            }
-
-            case Node.DOCUMENT_TYPE_NODE:
-                printDocType(node);
-                break;
-
-            case Node.ENTITY_REFERENCE_NODE:
-            case Node.ENTITY_NODE:
-            case Node.NOTATION_NODE:
-                break;
-            default:
-                assert false : type;
-        }
-    }
-
-    private void visitAfterChildren(int depth, Node node) {
-        short type = node.getNodeType();
-        switch (type) {
-            case Node.ATTRIBUTE_NODE:
-                // Handled as part of processing elements
-                break;
-            case Node.ELEMENT_NODE: {
-                printCloseElementTag(depth, node);
-                break;
-            }
-        }
-    }
-
-    private void printProcessingInstruction(Node node) {
-        mOut.append("<?xml "); //$NON-NLS-1$
-        mOut.append(node.getNodeValue().trim());
-        mOut.append('?').append('>').append(mLineSeparator);
-    }
-
-    private void printDocType(Node node) {
-        // In Eclipse, org.w3c.dom.DocumentType.getTextContent() returns null
-        if (node instanceof DocumentTypeImpl) {
-            String content = ((DocumentTypeImpl) node).getSource();
-            mOut.append(content);
-            mOut.append(mLineSeparator);
-        }
-    }
-
-    private void printCharacterData(int depth, Node node) {
-        String nodeValue = node.getNodeValue();
-        boolean separateLine = nodeValue.indexOf('\n') != -1;
-        if (separateLine && !endsWithLineSeparator()) {
-            mOut.append(mLineSeparator);
-        }
-        mOut.append("<![CDATA["); //$NON-NLS-1$
-        mOut.append(nodeValue);
-        mOut.append("]]>");       //$NON-NLS-1$
-        if (separateLine) {
-            mOut.append(mLineSeparator);
-        }
-    }
-
-    private void printText(Node node) {
-        boolean escape = true;
-        String text = node.getNodeValue();
-
-        if (node instanceof IDOMNode) {
-            // Get the original source string. This will contain the actual entities
-            // such as "&gt;" instead of ">" which it gets turned into for the DOM nodes.
-            // By operating on source we can preserve the user's entities rather than
-            // having &gt; for example always turned into >.
-            IDOMNode textImpl = (IDOMNode) node;
-            text = textImpl.getSource();
-            escape = false;
-        }
-
-        // Most text nodes are just whitespace for formatting (which we're replacing)
-        // so look for actual text content and extract that part out
-        String trimmed = text.trim();
-        if (trimmed.length() > 0) {
-            // TODO: Reformat the contents if it is too wide?
-
-            // Note that we append the actual text content, NOT the trimmed content,
-            // since the whitespace may be significant, e.g.
-            // <string name="toast_sync_error">Sync error: <xliff:g id="error">%1$s</xliff:g>...
-
-            // However, we should remove all blank lines in the prefix and suffix of the
-            // text node, or we will end up inserting additional blank lines each time you're
-            // formatting a text node within an outer element (which also adds spacing lines)
-            int lastPrefixNewline = -1;
-            for (int i = 0, n = text.length(); i < n; i++) {
-                char c = text.charAt(i);
-                if (c == '\n') {
-                    lastPrefixNewline = i;
-                } else if (!Character.isWhitespace(c)) {
-                    break;
-                }
-            }
-            int firstSuffixNewline = -1;
-            for (int i = text.length() - 1; i >= 0; i--) {
-                char c = text.charAt(i);
-                if (c == '\n') {
-                    firstSuffixNewline = i;
-                } else if (!Character.isWhitespace(c)) {
-                    break;
-                }
-            }
-            if (lastPrefixNewline != -1 || firstSuffixNewline != -1) {
-                if (firstSuffixNewline == -1) {
-                    firstSuffixNewline = text.length();
-                }
-                text = text.substring(lastPrefixNewline + 1, firstSuffixNewline);
-            }
-
-            if (escape) {
-                XmlUtils.appendXmlTextValue(mOut, text);
-            } else {
-                // Text is already escaped
-                mOut.append(text);
-            }
-
-            if (mStyle != XmlFormatStyle.RESOURCE) {
-                mOut.append(mLineSeparator);
-            }
-        }
-    }
-
-    private void printComment(int depth, Node node) {
-        String comment = node.getNodeValue();
-        boolean multiLine = comment.indexOf('\n') != -1;
-        String trimmed = comment.trim();
-
-        // See if this is an "end-of-the-line" comment, e.g. it is not a multi-line
-        // comment and it appears on the same line as an opening or closing element tag;
-        // if so, continue to place it as a suffix comment
-        boolean isSuffixComment = false;
-        if (!multiLine) {
-            Node previous = node.getPreviousSibling();
-            isSuffixComment = true;
-            while (previous != null) {
-                short type = previous.getNodeType();
-                if (type == Node.TEXT_NODE || type == Node.COMMENT_NODE) {
-                    if (previous.getNodeValue().indexOf('\n') != -1) {
-                        isSuffixComment = false;
-                        break;
-                    }
-                } else {
-                    break;
-                }
-                previous = previous.getPreviousSibling();
-            }
-            if (isSuffixComment) {
-                // Remove newline added by element open tag or element close tag
-                if (endsWithLineSeparator()) {
-                    removeLastLineSeparator();
-                }
-                mOut.append(' ');
-            }
-        }
-
-        // Put the comment on a line on its own? Only if it was separated by a blank line
-        // in the previous version of the document. In other words, if the document
-        // adds blank lines between comments this formatter will preserve that fact, and vice
-        // versa for a tightly formatted document it will preserve that convention as well.
-        if (!mPrefs.removeEmptyLines && depth > 0 && !isSuffixComment) {
-            Node curr = node.getPreviousSibling();
-            if (curr == null) {
-                mOut.append(mLineSeparator);
-            } else if (curr.getNodeType() == Node.TEXT_NODE) {
-                String text = curr.getNodeValue();
-                // Count how many newlines we find in the trailing whitespace of the
-                // text node
-                int newLines = 0;
-                for (int i = text.length() - 1; i >= 0; i--) {
-                    char c = text.charAt(i);
-                    if (Character.isWhitespace(c)) {
-                        if (c == '\n') {
-                            newLines++;
-                            if (newLines == 2) {
-                                break;
-                            }
-                        }
-                    } else {
-                        break;
-                    }
-                }
-                if (newLines >= 2) {
-                    mOut.append(mLineSeparator);
-                } else if (text.trim().length() == 0 && curr.getPreviousSibling() == null) {
-                    // Comment before first child in node
-                    mOut.append(mLineSeparator);
-                }
-            }
-        }
-
-
-        // TODO: Reformat the comment text?
-        if (!multiLine) {
-            if (!isSuffixComment) {
-                indent(depth);
-            }
-            mOut.append(COMMENT_BEGIN).append(' ');
-            mOut.append(trimmed);
-            mOut.append(' ').append(COMMENT_END);
-            mOut.append(mLineSeparator);
-        } else {
-            // Strip off blank lines at the beginning and end of the comment text.
-            // Find last newline at the beginning of the text:
-            int index = 0;
-            int end = comment.length();
-            int recentNewline = -1;
-            while (index < end) {
-                char c = comment.charAt(index);
-                if (c == '\n') {
-                    recentNewline = index;
-                }
-                if (!Character.isWhitespace(c)) {
-                    break;
-                }
-                index++;
-            }
-
-            int start = recentNewline + 1;
-
-            // Find last newline at the end of the text
-            index = end - 1;
-            recentNewline = -1;
-            while (index > start) {
-                char c = comment.charAt(index);
-                if (c == '\n') {
-                    recentNewline = index;
-                }
-                if (!Character.isWhitespace(c)) {
-                    break;
-                }
-                index--;
-            }
-
-            end = recentNewline == -1 ? index + 1 : recentNewline;
-            if (start >= end) {
-                // It's a blank comment like <!-- \n\n--> - just clean it up
-                if (!isSuffixComment) {
-                    indent(depth);
-                }
-                mOut.append(COMMENT_BEGIN).append(' ').append(COMMENT_END);
-                mOut.append(mLineSeparator);
-                return;
-            }
-
-            trimmed = comment.substring(start, end);
-
-            // When stripping out prefix and suffix blank lines we might have ended up
-            // with a single line comment again so check and format single line comments
-            // without newlines inside the <!-- --> delimiters
-            multiLine = trimmed.indexOf('\n') != -1;
-            if (multiLine) {
-                indent(depth);
-                mOut.append(COMMENT_BEGIN);
-                mOut.append(mLineSeparator);
-
-                // See if we need to add extra spacing to keep alignment. Consider a comment
-                // like this:
-                // <!-- Deprecated strings - Move the identifiers to this section,
-                //      and remove the actual text. -->
-                // This String will be
-                // " Deprecated strings - Move the identifiers to this section,\n" +
-                // "     and remove the actual text. -->"
-                // where the left side column no longer lines up.
-                // To fix this, we need to insert some extra whitespace into the first line
-                // of the string; in particular, the exact number of characters that the
-                // first line of the comment was indented with!
-
-                // However, if the comment started like this:
-                // <!--
-                // /** Copyright
-                // -->
-                // then obviously the align-indent is 0, so we only want to compute an
-                // align indent when we don't find a newline before the content
-                boolean startsWithNewline = false;
-                for (int i = 0; i < start; i++) {
-                    if (comment.charAt(i) == '\n') {
-                        startsWithNewline = true;
-                        break;
-                    }
-                }
-                if (!startsWithNewline) {
-                    Node previous = node.getPreviousSibling();
-                    if (previous != null && previous.getNodeType() == Node.TEXT_NODE) {
-                        String prevText = previous.getNodeValue();
-                        int indentation = COMMENT_BEGIN.length();
-                        for (int i = prevText.length() - 1; i >= 0; i--) {
-                            char c = prevText.charAt(i);
-                            if (c == '\n') {
-                                break;
-                            } else {
-                                indentation += (c == '\t') ? mPrefs.getTabWidth() : 1;
-                            }
-                        }
-
-                        // See if the next line after the newline has indentation; if it doesn't,
-                        // leave things alone. This fixes a case like this:
-                        //     <!-- This is the
-                        //     comment block -->
-                        // such that it doesn't turn it into
-                        //     <!--
-                        //          This is the
-                        //     comment block
-                        //     -->
-                        // In this case we instead want
-                        //     <!--
-                        //     This is the
-                        //     comment block
-                        //     -->
-                        int minIndent = Integer.MAX_VALUE;
-                        String[] lines = trimmed.split("\n"); //$NON-NLS-1$
-                        // Skip line 0 since we know that it doesn't start with a newline
-                        for (int i = 1; i < lines.length; i++) {
-                            int indent = 0;
-                            String line = lines[i];
-                            for (int j = 0; j < line.length(); j++) {
-                                char c = line.charAt(j);
-                                if (!Character.isWhitespace(c)) {
-                                    // Only set minIndent if there's text content on the line;
-                                    // blank lines can exist in the comment without affecting
-                                    // the overall minimum indentation boundary.
-                                    if (indent < minIndent) {
-                                        minIndent = indent;
-                                    }
-                                    break;
-                                } else {
-                                    indent += (c == '\t') ? mPrefs.getTabWidth() : 1;
-                                }
-                            }
-                        }
-
-                        if (minIndent < indentation) {
-                            indentation = minIndent;
-
-                            // Subtract any indentation that is already present on the line
-                            String line = lines[0];
-                            for (int j = 0; j < line.length(); j++) {
-                                char c = line.charAt(j);
-                                if (!Character.isWhitespace(c)) {
-                                    break;
-                                } else {
-                                    indentation -= (c == '\t') ? mPrefs.getTabWidth() : 1;
-                                }
-                            }
-                        }
-
-                        for (int i = 0; i < indentation; i++) {
-                            mOut.append(' ');
-                        }
-
-                        if (indentation < 0) {
-                            boolean prefixIsSpace = true;
-                            for (int i = 0; i < -indentation && i < trimmed.length(); i++) {
-                                if (!Character.isWhitespace(trimmed.charAt(i))) {
-                                    prefixIsSpace = false;
-                                    break;
-                                }
-                            }
-                            if (prefixIsSpace) {
-                                trimmed = trimmed.substring(-indentation);
-                            }
-                        }
-                    }
-                }
-
-                mOut.append(trimmed);
-                mOut.append(mLineSeparator);
-                indent(depth);
-                mOut.append(COMMENT_END);
-                mOut.append(mLineSeparator);
-            } else {
-                mOut.append(COMMENT_BEGIN).append(' ');
-                mOut.append(trimmed);
-                mOut.append(' ').append(COMMENT_END);
-                mOut.append(mLineSeparator);
-            }
-        }
-
-        // Preserve whitespace after comment: See if the original document had two or
-        // more newlines after the comment, and if so have a blank line between this
-        // comment and the next
-        Node next = node.getNextSibling();
-        if (!mPrefs.removeEmptyLines && next != null && next.getNodeType() == Node.TEXT_NODE) {
-            String text = next.getNodeValue();
-            int newLinesBeforeText = 0;
-            for (int i = 0, n = text.length(); i < n; i++) {
-                char c = text.charAt(i);
-                if (c == '\n') {
-                    newLinesBeforeText++;
-                    if (newLinesBeforeText == 2) {
-                        // Yes
-                        mOut.append(mLineSeparator);
-                        break;
-                    }
-                } else if (!Character.isWhitespace(c)) {
-                    break;
-                }
-            }
-        }
-    }
-
-    private boolean endsWithLineSeparator() {
-        int separatorLength = mLineSeparator.length();
-        if (mOut.length() >= separatorLength) {
-            for (int i = 0, j = mOut.length() - separatorLength; i < separatorLength; i++) {
-               if (mOut.charAt(j) != mLineSeparator.charAt(i)) {
-                   return false;
-               }
-            }
-        }
-
-        return true;
-    }
-
-    private void removeLastLineSeparator() {
-        mOut.setLength(mOut.length() - mLineSeparator.length());
-    }
-
-    private void printOpenElementTag(int depth, Node node) {
-        Element element = (Element) node;
-        if (newlineBeforeElementOpen(element, depth)) {
-            mOut.append(mLineSeparator);
-        }
-        if (indentBeforeElementOpen(element, depth)) {
-            indent(depth);
-        }
-        mOut.append('<').append(element.getTagName());
-
-        NamedNodeMap attributes = element.getAttributes();
-        int attributeCount = attributes.getLength();
-        if (attributeCount > 0) {
-            // Sort the attributes
-            List<Attr> attributeList = new ArrayList<Attr>();
-            for (int i = 0, n = attributeCount; i < n; i++) {
-                attributeList.add((Attr) attributes.item(i));
-            }
-            Comparator<Attr> comparator = mPrefs.sortAttributes.getAttributeComparator();
-            Collections.sort(attributeList, comparator);
-
-            // Put the single attribute on the same line as the element tag?
-            boolean singleLine = mPrefs.oneAttributeOnFirstLine && attributeCount == 1
-                    // In resource files we always put all the attributes (which is
-                    // usually just zero, one or two) on the same line
-                    || mStyle == XmlFormatStyle.RESOURCE;
-
-            // We also place the namespace declaration on the same line as the root element,
-            // but this doesn't also imply singleLine handling; subsequent attributes end up
-            // on their own lines
-            boolean indentNextAttribute;
-            if (singleLine || (depth == 0 && XMLNS.equals(attributeList.get(0).getPrefix()))) {
-                mOut.append(' ');
-                indentNextAttribute = false;
-            } else {
-                mOut.append(mLineSeparator);
-                indentNextAttribute = true;
-            }
-
-            Attr last = attributeList.get(attributeCount - 1);
-            for (Attr attribute : attributeList) {
-                if (indentNextAttribute) {
-                    indent(depth + 1);
-                }
-                mOut.append(attribute.getName());
-                mOut.append('=').append('"');
-                XmlUtils.appendXmlAttributeValue(mOut, attribute.getValue());
-                mOut.append('"');
-
-                // Don't add a newline at the last attribute line; the > should
-                // immediately follow the last attribute
-                if (attribute != last) {
-                    mOut.append(singleLine ? " " : mLineSeparator); //$NON-NLS-1$
-                    indentNextAttribute = !singleLine;
-                }
-            }
-        }
-
-        boolean isClosed = isEmptyTag(element);
-
-        // Add a space before the > or /> ? In resource files, only do this when closing the
-        // element
-        if (mPrefs.spaceBeforeClose && (mStyle != XmlFormatStyle.RESOURCE || isClosed)
-                // in <selector> files etc still treat the <item> entries as in resource files
-                && !TAG_ITEM.equals(element.getTagName())
-                && (isClosed || element.getAttributes().getLength() > 0)) {
-            mOut.append(' ');
-        }
-
-        if (isClosed) {
-            mOut.append('/');
-        }
-
-        mOut.append('>');
-
-        if (newlineAfterElementOpen(element, depth, isClosed)) {
-            mOut.append(mLineSeparator);
-        }
-    }
-
-    private void printCloseElementTag(int depth, Node node) {
-        Element element = (Element) node;
-        if (isEmptyTag(element)) {
-            // Empty tag: Already handled as part of opening tag
-            return;
-        }
-
-        // Put the closing declaration on its own line - unless it's a compact
-        // resource file format
-        // If the element had element children, separate the end tag from them
-        if (newlineBeforeElementClose(element, depth)) {
-            mOut.append(mLineSeparator);
-        }
-        if (indentBeforeElementClose(element, depth)) {
-            indent(depth);
-        }
-        mOut.append('<').append('/');
-        mOut.append(node.getNodeName());
-        mOut.append('>');
-
-        if (newlineAfterElementClose(element, depth)) {
-            mOut.append(mLineSeparator);
-        }
-    }
-
-    private boolean newlineBeforeElementOpen(Element element, int depth) {
-        if (hasBlankLineAbove()) {
-            return false;
-        }
-
-        if (mPrefs.removeEmptyLines || depth <= 0) {
-            return false;
-        }
-
-        if (isMarkupElement(element)) {
-            return false;
-        }
-
-        // See if this element should be separated from the previous element.
-        // This is the case if we are not compressing whitespace (checked above),
-        // or if we are not immediately following a comment (in which case the
-        // newline would have been added above it), or if we are not in a formatting
-        // style where
-        if (mStyle == XmlFormatStyle.LAYOUT) {
-            // In layouts we always separate elements
-            return true;
-        }
-
-        if (mStyle == XmlFormatStyle.MANIFEST || mStyle == XmlFormatStyle.RESOURCE
-                || mStyle == XmlFormatStyle.FILE) {
-            Node curr = element.getPreviousSibling();
-
-            // <style> elements are traditionally separated unless it follows a comment
-            if (TAG_STYLE.equals(element.getTagName())) {
-                if (curr == null
-                        || curr.getNodeType() == Node.ELEMENT_NODE
-                        || (curr.getNodeType() == Node.TEXT_NODE
-                                && curr.getNodeValue().trim().length() == 0
-                                && (curr.getPreviousSibling() == null
-                                || curr.getPreviousSibling().getNodeType()
-                                        == Node.ELEMENT_NODE))) {
-                    return true;
-                }
-            }
-
-            // In all other styles, we separate elements if they have a different tag than
-            // the previous one (but we don't insert a newline inside tags)
-            while (curr != null) {
-                short nodeType = curr.getNodeType();
-                if (nodeType == Node.ELEMENT_NODE) {
-                    Element sibling = (Element) curr;
-                    if (!element.getTagName().equals(sibling.getTagName())) {
-                        return true;
-                    }
-                    break;
-                } else if (nodeType == Node.TEXT_NODE) {
-                    String text = curr.getNodeValue();
-                    if (text.trim().length() > 0) {
-                        break;
-                    }
-                    // If there is just whitespace, continue looking for a previous sibling
-                } else {
-                    // Any other previous node type, such as a comment, means we don't
-                    // continue looking: this element should not be separated
-                    break;
-                }
-                curr = curr.getPreviousSibling();
-            }
-            if (curr == null && depth <= 1) {
-                // Insert new line inside tag if it's the first element inside the root tag
-                return true;
-            }
-
-            return false;
-        }
-
-        return false;
-    }
-
-    private boolean indentBeforeElementOpen(Element element, int depth) {
-        if (isMarkupElement(element)) {
-            return false;
-        }
-
-        if (element.getParentNode().getNodeType() == Node.ELEMENT_NODE
-                && keepElementAsSingleLine(depth - 1, (Element) element.getParentNode())) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private boolean indentBeforeElementClose(Element element, int depth) {
-        if (isMarkupElement(element)) {
-            return false;
-        }
-
-        char lastOutChar = mOut.charAt(mOut.length() - 1);
-        char lastDelimiterChar = mLineSeparator.charAt(mLineSeparator.length() - 1);
-        return lastOutChar == lastDelimiterChar;
-    }
-
-    private boolean newlineAfterElementOpen(Element element, int depth, boolean isClosed) {
-        if (hasBlankLineAbove()) {
-            return false;
-        }
-
-        if (isMarkupElement(element)) {
-            return false;
-        }
-
-        // In resource files we keep the child content directly on the same
-        // line as the element (unless it has children). in other files, separate them
-        return isClosed || !keepElementAsSingleLine(depth, element);
-    }
-
-    private boolean newlineBeforeElementClose(Element element, int depth) {
-        if (hasBlankLineAbove()) {
-            return false;
-        }
-
-        if (isMarkupElement(element)) {
-            return false;
-        }
-
-        return depth == 0 && !mPrefs.removeEmptyLines;
-    }
-
-    private boolean hasBlankLineAbove() {
-        if (mOut.length() < 2 * mLineSeparator.length()) {
-            return false;
-        }
-
-        return SdkUtils.endsWith(mOut, mLineSeparator) &&
-                SdkUtils.endsWith(mOut, mOut.length() - mLineSeparator.length(), mLineSeparator);
-    }
-
-    private boolean newlineAfterElementClose(Element element, int depth) {
-        if (hasBlankLineAbove()) {
-            return false;
-        }
-
-        if (isMarkupElement(element)) {
-            return false;
-        }
-
-        return element.getParentNode().getNodeType() == Node.ELEMENT_NODE
-                && !keepElementAsSingleLine(depth - 1, (Element) element.getParentNode());
-    }
-
-    private boolean isMarkupElement(Element element) {
-        // The documentation suggests that the allowed tags are <u>, <b> and <i>:
-        //   developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
-        // However, the full set of tags accepted by Html.fromHtml is much larger. Therefore,
-        // instead consider *any* element nested inside a <string> definition to be a markup
-        // element. See frameworks/base/core/java/android/text/Html.java and look for
-        // HtmlToSpannedConverter#handleStartTag.
-
-        if (mStyle != XmlFormatStyle.RESOURCE) {
-            return false;
-        }
-
-        Node curr = element.getParentNode();
-        while (curr != null) {
-            if (TAG_STRING.equals(curr.getNodeName())) {
-                return true;
-            }
-
-            curr = curr.getParentNode();
-        }
-
-        return false;
-    }
-
-    /**
-     * TODO: Explain why we need to do per-tag decisions on whether to keep them on the
-     * same line or not. Show that we can't just do it by depth, or by file type.
-     * (style versus plurals example)
-     * @param tag
-     * @return
-     */
-    private boolean isSingleLineTag(Element element) {
-        String tag = element.getTagName();
-
-        return (tag.equals(TAG_ITEM) && mStyle == XmlFormatStyle.RESOURCE)
-                || tag.equals(TAG_STRING)
-                || tag.equals(TAG_DIMEN)
-                || tag.equals(TAG_COLOR);
-    }
-
-    private boolean keepElementAsSingleLine(int depth, Element element) {
-        if (depth == 0) {
-            return false;
-        }
-
-        return isSingleLineTag(element)
-                || (mStyle == XmlFormatStyle.RESOURCE
-                    && !DomUtilities.hasElementChildren(element));
-    }
-
-    private void indent(int depth) {
-        int i = 0;
-
-        if (mIndentationLevels != null) {
-            for (int j = Math.min(depth, mIndentationLevels.length - 1); j >= 0; j--) {
-                String indent = mIndentationLevels[j];
-                if (indent != null) {
-                    mOut.append(indent);
-                    i = j;
-                    break;
-                }
-            }
-        }
-
-        for (; i < depth; i++) {
-            mOut.append(mIndentString);
-        }
-    }
-
-    private boolean isEmptyTag(Element element) {
-        boolean isClosed = false;
-        if (element instanceof ElementImpl) {
-            ElementImpl elementImpl = (ElementImpl) element;
-            if (elementImpl.isEmptyTag()) {
-                isClosed = true;
-            }
-        }
-        return isClosed;
-    }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderPreviewList.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderPreviewList.java
index 05f1005..d3c4fab 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderPreviewList.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/RenderPreviewList.java
@@ -18,7 +18,7 @@
 import com.android.annotations.NonNull;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter;
 import com.android.ide.eclipse.adt.internal.editors.layout.configuration.Configuration;
 import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationChooser;
 import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationDescription;
@@ -107,7 +107,7 @@
             for (ConfigurationDescription description : mList) {
                 description.toXml(document);
             }
-            String xml = XmlPrettyPrinter.prettyPrint(document);
+            String xml = EclipseXmlPrettyPrinter.prettyPrint(document);
             Files.write(xml, file, Charsets.UTF_8);
         }
     }
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ChangeLayoutRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ChangeLayoutRefactoring.java
index b01b4b1..d8c85aa 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ChangeLayoutRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ChangeLayoutRefactoring.java
@@ -41,9 +41,9 @@
 import com.android.SdkConstants;
 import com.android.annotations.NonNull;
 import com.android.annotations.VisibleForTesting;
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractIncludeRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractIncludeRefactoring.java
index 65edd54..f58ac55 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractIncludeRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractIncludeRefactoring.java
@@ -37,10 +37,10 @@
 
 import com.android.annotations.NonNull;
 import com.android.annotations.VisibleForTesting;
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter;
 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
@@ -330,8 +330,9 @@
 
         String newFile = sb.toString();
         if (AdtPrefs.getPrefs().getFormatGuiXml()) {
-            newFile = XmlPrettyPrinter.prettyPrint(newFile,
-                    XmlFormatPreferences.create(), XmlFormatStyle.LAYOUT, null /*lineSeparator*/);
+            newFile = EclipseXmlPrettyPrinter.prettyPrint(newFile,
+                    EclipseXmlFormatPreferences.create(), XmlFormatStyle.LAYOUT,
+                    null /*lineSeparator*/);
         }
         addFile.setEdit(new InsertEdit(0, newFile));
 
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractStyleRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractStyleRefactoring.java
index ffe6892..9b1770d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractStyleRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/ExtractStyleRefactoring.java
@@ -43,10 +43,10 @@
 import com.android.annotations.VisibleForTesting;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.resources.ResourceResolver;
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
 import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
 import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
 import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RelativeLayoutConversionHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RelativeLayoutConversionHelper.java
index 7f9cc71..e0d6313 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RelativeLayoutConversionHelper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RelativeLayoutConversionHelper.java
@@ -15,15 +15,7 @@
  */
 package com.android.ide.eclipse.adt.internal.editors.layout.refactoring;
 
-import static com.android.ide.common.layout.GravityHelper.GRAVITY_BOTTOM;
-import static com.android.ide.common.layout.GravityHelper.GRAVITY_CENTER_HORIZ;
-import static com.android.ide.common.layout.GravityHelper.GRAVITY_CENTER_VERT;
-import static com.android.ide.common.layout.GravityHelper.GRAVITY_FILL_HORIZ;
-import static com.android.ide.common.layout.GravityHelper.GRAVITY_FILL_VERT;
-import static com.android.ide.common.layout.GravityHelper.GRAVITY_LEFT;
-import static com.android.ide.common.layout.GravityHelper.GRAVITY_RIGHT;
-import static com.android.ide.common.layout.GravityHelper.GRAVITY_TOP;
-import static com.android.ide.common.layout.GravityHelper.GRAVITY_VERT_MASK;
+import static com.android.SdkConstants.ANDROID_URI;
 import static com.android.SdkConstants.ATTR_BACKGROUND;
 import static com.android.SdkConstants.ATTR_BASELINE_ALIGNED;
 import static com.android.SdkConstants.ATTR_LAYOUT_ABOVE;
@@ -58,10 +50,16 @@
 import static com.android.SdkConstants.VALUE_TRUE;
 import static com.android.SdkConstants.VALUE_VERTICAL;
 import static com.android.SdkConstants.VALUE_WRAP_CONTENT;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_BOTTOM;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_CENTER_HORIZ;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_CENTER_VERT;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_FILL_HORIZ;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_FILL_VERT;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_LEFT;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_RIGHT;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_TOP;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_VERT_MASK;
 
-
-import com.android.SdkConstants;
-import static com.android.SdkConstants.ANDROID_URI;
 import com.android.ide.common.layout.GravityHelper;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UnwrapRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UnwrapRefactoring.java
index 1dcc1b7..4eff2cd 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UnwrapRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UnwrapRefactoring.java
@@ -22,7 +22,7 @@
 
 import com.android.annotations.NonNull;
 import com.android.annotations.VisibleForTesting;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
 
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
index b96d31a..a775686 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
@@ -42,10 +42,10 @@
 import com.android.annotations.NonNull;
 import com.android.annotations.Nullable;
 import com.android.annotations.VisibleForTesting;
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter;
 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
@@ -353,8 +353,9 @@
             }
         }
 
-        String xml = XmlPrettyPrinter.prettyPrint(tempDocument.getDocumentElement(),
-                XmlFormatPreferences.create(),
+        String xml = EclipseXmlPrettyPrinter.prettyPrint(
+                tempDocument.getDocumentElement(),
+                EclipseXmlFormatPreferences.create(),
                 XmlFormatStyle.LAYOUT, null);
 
         TextEdit replace = new ReplaceEdit(mSelectionStart, mSelectionEnd - mSelectionStart, xml);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoring.java
index 5939a8a..904a3a0 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoring.java
@@ -29,11 +29,11 @@
 
 import com.android.annotations.NonNull;
 import com.android.annotations.VisibleForTesting;
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter;
 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
 import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationDescription;
 import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
@@ -1312,8 +1312,8 @@
         //int end = actual.length() - distanceFromEnd;
         //int length = end - start;
         //TextEdit format = AndroidXmlFormattingStrategy.format(model, start, length);
-        XmlFormatPreferences formatPrefs = XmlFormatPreferences.create();
-        String formatted = XmlPrettyPrinter.prettyPrint(actual, formatPrefs, style,
+        EclipseXmlFormatPreferences formatPrefs = EclipseXmlFormatPreferences.create();
+        String formatted = EclipseXmlPrettyPrinter.prettyPrint(actual, formatPrefs, style,
                 null /*lineSeparator*/);
 
 
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/WrapInRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/WrapInRefactoring.java
index ff2e9bd..07b00b8 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/WrapInRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/WrapInRefactoring.java
@@ -28,8 +28,8 @@
 
 import com.android.annotations.NonNull;
 import com.android.annotations.VisibleForTesting;
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
 import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo;
 import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAttributeNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAttributeNode.java
index 71cb35d..ffe637c 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAttributeNode.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAttributeNode.java
@@ -16,17 +16,7 @@
 
 package com.android.ide.eclipse.adt.internal.editors.uimodel;
 
-import static com.android.SdkConstants.ATTR_ID;
-import static com.android.SdkConstants.ATTR_LAYOUT_HEIGHT;
-import static com.android.SdkConstants.ATTR_LAYOUT_RESOURCE_PREFIX;
-import static com.android.SdkConstants.ATTR_LAYOUT_WIDTH;
-import static com.android.SdkConstants.ATTR_NAME;
-import static com.android.SdkConstants.ATTR_STYLE;
-import static com.android.ide.eclipse.adt.internal.editors.color.ColorDescriptors.ATTR_COLOR;
-import static com.google.common.base.Strings.nullToEmpty;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
+import com.android.ide.common.xml.XmlAttributeSortOrder;
 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
 
@@ -34,8 +24,6 @@
 import org.eclipse.ui.forms.IManagedForm;
 import org.w3c.dom.Node;
 
-import java.util.Comparator;
-
 /**
  * Represents an XML attribute that can be modified by the XML editor's user interface.
  * <p/>
@@ -177,107 +165,10 @@
     public abstract void commit();
 
     // ---- Implements Comparable ----
+
     @Override
     public int compareTo(UiAttributeNode o) {
-        return compareAttributes(mDescriptor.getXmlLocalName(), o.mDescriptor.getXmlLocalName());
-    }
-
-    /**
-     * Returns {@link Comparator} values for ordering attributes in the following
-     * order:
-     * <ul>
-     *   <li> id
-     *   <li> style
-     *   <li> layout_width
-     *   <li> layout_height
-     *   <li> other layout params, sorted alphabetically
-     *   <li> other attributes, sorted alphabetically
-     * </ul>
-     *
-     * @param name1 the first attribute name to compare
-     * @param name2 the second attribute name to compare
-     * @return a negative number if name1 should be ordered before name2
-     */
-    public static int compareAttributes(String name1, String name2) {
-        int priority1 = getAttributePriority(name1);
-        int priority2 = getAttributePriority(name2);
-        if (priority1 != priority2) {
-            return priority1 - priority2;
-        }
-
-        // Sort remaining attributes alphabetically
-        return name1.compareTo(name2);
-    }
-
-    /**
-     * Returns {@link Comparator} values for ordering attributes in the following
-     * order:
-     * <ul>
-     *   <li> id
-     *   <li> style
-     *   <li> layout_width
-     *   <li> layout_height
-     *   <li> other layout params, sorted alphabetically
-     *   <li> other attributes, sorted alphabetically, first by namespace, then by name
-     * </ul>
-     * @param prefix1 the namespace prefix, if any, of {@code name1}
-     * @param name1 the first attribute name to compare
-     * @param prefix2  the namespace prefix, if any, of {@code name2}
-     * @param name2 the second attribute name to compare
-     * @return a negative number if name1 should be ordered before name2
-     */
-    public static int compareAttributes(
-            @Nullable String prefix1, @NonNull String name1,
-            @Nullable String prefix2, @NonNull String name2) {
-        int priority1 = getAttributePriority(name1);
-        int priority2 = getAttributePriority(name2);
-        if (priority1 != priority2) {
-            return priority1 - priority2;
-        }
-
-        int namespaceDelta = nullToEmpty(prefix1).compareTo(nullToEmpty(prefix2));
-        if (namespaceDelta != 0) {
-            return namespaceDelta;
-        }
-
-        // Sort remaining attributes alphabetically
-        return name1.compareTo(name2);
-    }
-
-
-    /** Returns a sorting priority for the given attribute name */
-    private static int getAttributePriority(String name) {
-        if (ATTR_ID.equals(name)) {
-            return 10;
-        }
-
-        if (ATTR_NAME.equals(name)) {
-            return 15;
-        }
-
-        if (ATTR_STYLE.equals(name)) {
-            return 20;
-        }
-
-        if (name.startsWith(ATTR_LAYOUT_RESOURCE_PREFIX)) {
-            // Width and height are special cased because we (a) want width and height
-            // before the other layout attributes, and (b) we want width to sort before height
-            // even though it comes after it alphabetically.
-            if (name.equals(ATTR_LAYOUT_WIDTH)) {
-                return 30;
-            }
-            if (name.equals(ATTR_LAYOUT_HEIGHT)) {
-                return 40;
-            }
-
-            return 50;
-        }
-
-        // "color" sorts to the end
-        if (ATTR_COLOR.equals(name)) {
-            return 100;
-        }
-
-        return 60;
+        return XmlAttributeSortOrder.compareAttributes(mDescriptor.getXmlLocalName(),
+                o.mDescriptor.getXmlLocalName());
     }
 }
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java
index f905c73..ed447c6 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java
@@ -26,6 +26,7 @@
 import com.android.annotations.VisibleForTesting;
 import com.android.ide.common.api.IAttributeInfo.Format;
 import com.android.ide.common.resources.platform.AttributeInfo;
+import com.android.ide.common.xml.XmlAttributeSortOrder;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
@@ -1663,7 +1664,7 @@
             List<Attr> move = new ArrayList<Attr>();
             for (int i = 0, n = attributes.getLength(); i < n; i++) {
                 Attr attribute = (Attr) attributes.item(i);
-                if (UiAttributeNode.compareAttributes(
+                if (XmlAttributeSortOrder.compareAttributes(
                         attribute.getPrefix(), attribute.getLocalName(),
                         firstNamePrefix, firstName) > 0) {
                     move.add(attribute);
@@ -1699,7 +1700,7 @@
 
                         String domAttributeName = domAttribute.getLocalName();
                         String uiAttributeName = uiAttribute.getDescriptor().getXmlLocalName();
-                        compare = UiAttributeNode.compareAttributes(domAttributeName,
+                        compare = XmlAttributeSortOrder.compareAttributes(domAttributeName,
                                 uiAttributeName);
                     } else {
                         compare = 1;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AdtPrefs.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AdtPrefs.java
index 800828c..aed4bd4 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AdtPrefs.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AdtPrefs.java
@@ -18,9 +18,9 @@
 
 
 import com.android.annotations.NonNull;
+import com.android.ide.common.xml.XmlAttributeSortOrder;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderPreviewMode;
 import com.android.prefs.AndroidLocation.AndroidLocationException;
 import com.android.sdklib.internal.build.DebugKeyProvider;
@@ -104,7 +104,7 @@
     private boolean mFormatOnSave;
     private boolean mLintOnSave;
     private boolean mLintOnExport;
-    private AttributeSortOrder mAttributeSort;
+    private XmlAttributeSortOrder mAttributeSort;
     private boolean mSharedLayoutEditor;
     private boolean mAutoPickTarget;
     private RenderPreviewMode mPreviewMode = RenderPreviewMode.NONE;
@@ -236,11 +236,11 @@
 
         if (property == null || PREFS_ATTRIBUTE_SORT.equals(property)) {
             String order = mStore.getString(PREFS_ATTRIBUTE_SORT);
-            mAttributeSort = AttributeSortOrder.LOGICAL;
-            if (AttributeSortOrder.ALPHABETICAL.key.equals(order)) {
-                mAttributeSort = AttributeSortOrder.ALPHABETICAL;
-            } else if (AttributeSortOrder.NO_SORTING.key.equals(order)) {
-                mAttributeSort = AttributeSortOrder.NO_SORTING;
+            mAttributeSort = XmlAttributeSortOrder.LOGICAL;
+            if (XmlAttributeSortOrder.ALPHABETICAL.key.equals(order)) {
+                mAttributeSort = XmlAttributeSortOrder.ALPHABETICAL;
+            } else if (XmlAttributeSortOrder.NO_SORTING.key.equals(order)) {
+                mAttributeSort = XmlAttributeSortOrder.NO_SORTING;
             }
         }
 
@@ -359,13 +359,13 @@
 
     /**
      * Returns the sort order to be applied to the attributes (one of which can
-     * be {@link AttributeSortOrder#NO_SORTING}).
+     * be {@link com.android.ide.common.xml.XmlAttributeSortOrder#NO_SORTING}).
      *
      * @return the sort order to apply to the attributes
      */
-    public AttributeSortOrder getAttributeSort() {
+    public XmlAttributeSortOrder getAttributeSort() {
         if (mAttributeSort == null) {
-            return AttributeSortOrder.LOGICAL;
+            return XmlAttributeSortOrder.LOGICAL;
         }
         return mAttributeSort;
     }
@@ -373,7 +373,7 @@
     /**
      * Returns whether a space should be inserted before the closing {@code >}
      * character in open tags and before the closing {@code />} characters in
-     * empty tag. Note that the {@link XmlFormatStyle#RESOURCE} style overrides
+     * empty tag. Note that the {@link com.android.ide.common.xml.XmlFormatStyle#RESOURCE} style overrides
      * this setting to make it more compact for the {@code <item>} elements.
      *
      * @return true if an empty space should be inserted before {@code >} or
@@ -517,7 +517,7 @@
         store.setDefault(PREFS_AUTO_PICK_TARGET, true);
 
         // Defaults already handled; no need to write into map:
-        //store.setDefault(PREFS_ATTRIBUTE_SORT, AttributeSortOrder.LOGICAL.key);
+        //store.setDefault(PREFS_ATTRIBUTE_SORT, XmlAttributeSortOrder.LOGICAL.key);
         //store.setDefault(PREFS_USE_ECLIPSE_INDENT, false);
         //store.setDefault(PREVS_REMOVE_EMPTY_LINES, false);
         //store.setDefault(PREFS_FORMAT_ON_SAVE, false);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AttributeSortOrder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AttributeSortOrder.java
deleted file mode 100644
index b743014..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AttributeSortOrder.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.ide.eclipse.adt.internal.preferences;
-
-import static com.android.SdkConstants.XMLNS;
-
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
-
-import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
-import org.w3c.dom.Attr;
-
-import java.util.Comparator;
-
-/** Order to use when sorting attributes */
-@SuppressWarnings("restriction") // IndexedRegion
-public enum AttributeSortOrder {
-    NO_SORTING("none"),     //$NON-NLS-1$
-    ALPHABETICAL("alpha"),  //$NON-NLS-1$
-    LOGICAL("logical");     //$NON-NLS-1$
-
-    AttributeSortOrder(String key) {
-        this.key = key;
-    }
-
-    public final String key;
-
-    /**
-     * @return a comparator for use by this attribute sort order
-     */
-    public Comparator<Attr> getAttributeComparator() {
-        switch (this) {
-            case ALPHABETICAL:
-                return ALPHABETICAL_COMPARATOR;
-            case NO_SORTING:
-                return EXISTING_ORDER_COMPARATOR;
-            case LOGICAL:
-            default:
-                return SORTED_ORDER_COMPARATOR;
-        }
-    }
-
-    /** Comparator which can be used to sort attributes in the coding style priority order */
-    private static final Comparator<Attr> SORTED_ORDER_COMPARATOR = new Comparator<Attr>() {
-        @Override
-        public int compare(Attr attr1, Attr attr2) {
-            // Namespace declarations should always go first
-            if (XMLNS.equals(attr1.getPrefix())) {
-                if (XMLNS.equals(attr2.getPrefix())) {
-                    return 0;
-                }
-                return -1;
-            } else if (XMLNS.equals(attr2.getPrefix())) {
-                return 1;
-            }
-
-            // Sort by preferred attribute order
-            return UiAttributeNode.compareAttributes(
-                    attr1.getPrefix(), attr1.getLocalName(),
-                    attr2.getPrefix(), attr2.getLocalName());
-        }
-    };
-
-    /**
-     * Comparator which can be used to "sort" attributes into their existing source order
-     * (which is not the same as the node map iteration order in the DOM model)
-     */
-    private static final Comparator<Attr> EXISTING_ORDER_COMPARATOR = new Comparator<Attr>() {
-        @Override
-        public int compare(Attr attr1, Attr attr2) {
-            IndexedRegion region1 = (IndexedRegion) attr1;
-            IndexedRegion region2 = (IndexedRegion) attr2;
-
-            return region1.getStartOffset() - region2.getStartOffset();
-        }
-    };
-
-    /**
-     * Comparator which can be used to sort attributes into alphabetical order (but xmlns
-     * is always first)
-     */
-    private static final Comparator<Attr> ALPHABETICAL_COMPARATOR = new Comparator<Attr>() {
-        @Override
-        public int compare(Attr attr1, Attr attr2) {
-            // Namespace declarations should always go first
-            if (XMLNS.equals(attr1.getPrefix())) {
-                if (XMLNS.equals(attr2.getPrefix())) {
-                    return 0;
-                }
-                return -1;
-            } else if (XMLNS.equals(attr2.getPrefix())) {
-                return 1;
-            }
-
-            // Sort by name rather than localname to ensure we sort by namespaces first,
-            // then by names.
-            return attr1.getName().compareTo(attr2.getName());
-        }
-    };
-}
\ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/EditorsPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/EditorsPage.java
index 0fcbaa0..d33b49f 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/EditorsPage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/EditorsPage.java
@@ -16,9 +16,9 @@
 
 package com.android.ide.eclipse.adt.internal.preferences;
 
-import static com.android.ide.eclipse.adt.internal.preferences.AttributeSortOrder.ALPHABETICAL;
-import static com.android.ide.eclipse.adt.internal.preferences.AttributeSortOrder.LOGICAL;
-import static com.android.ide.eclipse.adt.internal.preferences.AttributeSortOrder.NO_SORTING;
+import static com.android.ide.common.xml.XmlAttributeSortOrder.ALPHABETICAL;
+import static com.android.ide.common.xml.XmlAttributeSortOrder.LOGICAL;
+import static com.android.ide.common.xml.XmlAttributeSortOrder.NO_SORTING;
 
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.sdkuilib.internal.widgets.ResolutionChooserDialog;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java
index 19a7101..eea9d36 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java
@@ -25,12 +25,12 @@
 import com.android.annotations.Nullable;
 import com.android.ide.common.resources.ValueResourceParser;
 import com.android.ide.common.xml.ManifestData;
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.AdtConstants;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter;
 import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
 import com.android.ide.eclipse.adt.internal.project.AndroidNature;
 import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
@@ -1088,8 +1088,8 @@
     /** Reformats the given contents with the current formatting settings */
     private String reformat(XmlFormatStyle style, String contents) {
         if (AdtPrefs.getPrefs().getUseCustomXmlFormatter()) {
-            XmlFormatPreferences formatPrefs = XmlFormatPreferences.create();
-            return XmlPrettyPrinter.prettyPrint(contents, formatPrefs, style,
+            EclipseXmlFormatPreferences formatPrefs = EclipseXmlFormatPreferences.create();
+            return EclipseXmlPrettyPrinter.prettyPrint(contents, formatPrefs, style,
                     null /*lineSeparator*/);
         } else {
             return contents;
@@ -1404,7 +1404,8 @@
 
         if (reformat) {
             // Guess the formatting style based on the file location
-            XmlFormatStyle style = XmlFormatStyle.getForFile(destFile.getProjectRelativePath());
+            XmlFormatStyle style = EclipseXmlPrettyPrinter
+                    .getForFile(destFile.getProjectRelativePath());
             if (style != null) {
                 template = reformat(style, template);
             }
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java
index 33b22b4..16cd7b3 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java
@@ -21,13 +21,13 @@
 
 import com.android.SdkConstants;
 import com.android.ide.common.resources.configuration.FolderConfiguration;
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.AdtUtils;
 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
 import com.android.ide.eclipse.adt.internal.editors.IconFactory;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderPreviewManager;
 import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo;
 import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
@@ -250,14 +250,14 @@
 
         sb.append("</").append(root).append(">\n");  //$NON-NLS-1$ //$NON-NLS-2$
 
-        XmlFormatPreferences formatPrefs = XmlFormatPreferences.create();
+        EclipseXmlFormatPreferences formatPrefs = EclipseXmlFormatPreferences.create();
         String fileContents;
         if (!autoFormat) {
             fileContents = sb.toString();
         } else {
-            XmlFormatStyle style = XmlFormatStyle.getForFolderType(folderType);
-            fileContents = XmlPrettyPrinter.prettyPrint(sb.toString(), formatPrefs,
-                                style, null /*lineSeparator*/);
+            XmlFormatStyle style = EclipseXmlPrettyPrinter.getForFolderType(folderType);
+            fileContents = EclipseXmlPrettyPrinter.prettyPrint(sb.toString(), formatPrefs,
+                    style, null /*lineSeparator*/);
         }
 
         // Remove marker tokens and replace them with whitespace
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
index 8c310ec..eb3d94a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
@@ -33,12 +33,12 @@
 import com.android.annotations.NonNull;
 import com.android.annotations.Nullable;
 import com.android.annotations.VisibleForTesting;
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.AdtPlugin;
 import com.android.ide.eclipse.adt.AdtUtils;
 import com.android.ide.eclipse.adt.internal.actions.AddSupportJarAction;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
 import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
 import com.android.ide.eclipse.adt.internal.sdk.AdtManifestMergeCallback;
@@ -692,7 +692,7 @@
             String parentFolderName = to.getParent().getName();
             ResourceFolderType folderType = ResourceFolderType.getFolderType(parentFolderName);
             if (folderType != null) {
-                formatStyle = XmlFormatStyle.getForFile(toPath);
+                formatStyle = EclipseXmlPrettyPrinter.getForFile(toPath);
             } else {
                 formatStyle = XmlFormatStyle.FILE;
             }
@@ -705,8 +705,8 @@
         String contents = null;
         if (ok) {
             if (modified) {
-                contents = XmlPrettyPrinter.prettyPrint(currentDocument,
-                        XmlFormatPreferences.create(), formatStyle, null);
+                contents = EclipseXmlPrettyPrinter.prettyPrint(currentDocument,
+                        EclipseXmlFormatPreferences.create(), formatStyle, null);
             }
         } else {
             // Just insert into file along with comment, using the "standard" conflict
@@ -914,9 +914,9 @@
     private static String format(IProject project, String contents, IPath to) {
         String name = to.lastSegment();
         if (name.endsWith(DOT_XML)) {
-            XmlFormatStyle formatStyle = XmlFormatStyle.getForFile(to);
-            XmlFormatPreferences prefs = XmlFormatPreferences.create();
-            return XmlPrettyPrinter.prettyPrint(contents, prefs, formatStyle, null);
+            XmlFormatStyle formatStyle = EclipseXmlPrettyPrinter.getForFile(to);
+            EclipseXmlFormatPreferences prefs = EclipseXmlFormatPreferences.create();
+            return EclipseXmlPrettyPrinter.prettyPrint(contents, prefs, formatStyle, null);
         } else if (name.endsWith(DOT_JAVA)) {
             Map<?, ?> options = null;
             if (project != null && project.isAccessible()) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlPrettyPrinterTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinterTest.java
similarity index 93%
rename from eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlPrettyPrinterTest.java
rename to eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinterTest.java
index 731621c..8fc8dd1 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/formatting/XmlPrettyPrinterTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/formatting/EclipseXmlPrettyPrinterTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.ide.eclipse.adt.internal.editors.formatting;
 
+import com.android.ide.common.xml.XmlFormatStyle;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
 import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
 
@@ -28,9 +29,9 @@
 import junit.framework.TestCase;
 
 @SuppressWarnings({
-    "javadoc", "restriction"
+        "javadoc", "restriction"
 })
-public class XmlPrettyPrinterTest extends TestCase {
+public class EclipseXmlPrettyPrinterTest extends TestCase {
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -39,11 +40,11 @@
         AdtPrefs prefs = AdtPrefs.getPrefs();
         prefs.initializeStoreWithDefaults(store);
         prefs.loadValues(null);
-        XmlFormatPreferences formatPrefs = XmlFormatPreferences.create();
+        EclipseXmlFormatPreferences formatPrefs = EclipseXmlFormatPreferences.create();
         assertTrue(formatPrefs.oneAttributeOnFirstLine);
     }
 
-    private void checkFormat(XmlFormatPreferences prefs, String baseLocation,
+    private void checkFormat(EclipseXmlFormatPreferences prefs, String baseLocation,
             String xml,
             String expected, String delimiter, String startNodeName,
             boolean openTagOnly, String endNodeName) throws Exception {
@@ -61,7 +62,7 @@
         }
         XmlFormatStyle style = AndroidXmlFormattingStrategy.guessStyle(model, document);
 
-        XmlPrettyPrinter printer = new XmlPrettyPrinter(prefs, style, delimiter);
+        EclipseXmlPrettyPrinter printer = new EclipseXmlPrettyPrinter(prefs, style, delimiter);
 
         StringBuilder sb = new StringBuilder(1000);
         Node startNode = document;
@@ -110,18 +111,18 @@
         return caretContextIndex + caretDelta;
     }
 
-    private void checkFormat(XmlFormatPreferences prefs, String baseLocation, String xml,
+    private void checkFormat(EclipseXmlFormatPreferences prefs, String baseLocation, String xml,
             String expected, String delimiter) throws Exception {
         checkFormat(prefs, baseLocation, xml, expected, delimiter, null, false, null);
     }
 
-    private void checkFormat(XmlFormatPreferences prefs, String baseLocation, String xml,
+    private void checkFormat(EclipseXmlFormatPreferences prefs, String baseLocation, String xml,
             String expected) throws Exception {
         checkFormat(prefs, baseLocation, xml, expected, "\n"); //$NON-NLS-1$
     }
     private void checkFormat(String baseLocation, String xml, String expected)
             throws Exception {
-        XmlFormatPreferences prefs = XmlFormatPreferences.create();
+        EclipseXmlFormatPreferences prefs = EclipseXmlFormatPreferences.create();
         checkFormat(prefs, baseLocation, xml, expected);
     }
 
@@ -152,7 +153,7 @@
     }
 
     public void testLayout3() throws Exception {
-        XmlFormatPreferences prefs = XmlFormatPreferences.create();
+        EclipseXmlFormatPreferences prefs = EclipseXmlFormatPreferences.create();
         prefs.oneAttributeOnFirstLine = true;
         checkFormat(
                 prefs, "res/layout-land/layout3.xml",
@@ -252,7 +253,7 @@
 
     public void testWindowsDelimiters() throws Exception {
         checkFormat(
-                XmlFormatPreferences.create(), "res/layout-xlarge/layout.xml",
+                EclipseXmlFormatPreferences.create(), "res/layout-xlarge/layout.xml",
                 "<LinearLayout><Button foo=\"bar\"></Button></LinearLayout>",
 
                 "<LinearLayout>\r\n" +
@@ -265,7 +266,7 @@
     }
 
     public void testRemoveBlanklines() throws Exception {
-        XmlFormatPreferences prefs = XmlFormatPreferences.create();
+        EclipseXmlFormatPreferences prefs = EclipseXmlFormatPreferences.create();
         prefs.removeEmptyLines = true;
         checkFormat(
                 prefs, "res/layout-xlarge/layout.xml",
@@ -289,7 +290,7 @@
 
     public void testRange() throws Exception {
         checkFormat(
-                XmlFormatPreferences.create(), "res/layout-xlarge/layout.xml",
+                EclipseXmlFormatPreferences.create(), "res/layout-xlarge/layout.xml",
                 "<LinearLayout><Button foo=\"bar\"></Button><CheckBox/></LinearLayout>",
                 "\n" +
                 "    <Button foo=\"bar\" >\n" +
@@ -302,7 +303,7 @@
 
     public void testOpenTagOnly() throws Exception {
         checkFormat(
-                XmlFormatPreferences.create(), "res/layout-xlarge/layout.xml",
+                EclipseXmlFormatPreferences.create(), "res/layout-xlarge/layout.xml",
                 "<LinearLayout><Button foo=\"bar\"></Button><CheckBox/></LinearLayout>",
                 "\n" +
                 "    <Button foo=\"bar\" >\n" +
@@ -313,7 +314,7 @@
     }
 
     public void testRange2() throws Exception {
-        XmlFormatPreferences prefs = XmlFormatPreferences.create();
+        EclipseXmlFormatPreferences prefs = EclipseXmlFormatPreferences.create();
         prefs.removeEmptyLines = true;
         checkFormat(
                 prefs, "res/layout-xlarge/layout.xml",
@@ -329,7 +330,6 @@
                 "    <bar3>\n" +
                 "        <baz12>\n" +
                 "        </baz12>\n",
-
                 "\n",
                 "baz1", false, "baz12");
     }
@@ -480,6 +480,7 @@
                 "    <dimen name=\"text_size_large\">22sp</dimen>\n" +
                 "\n" +
                 "</resources>",
+
                 "<resources>\n" +
                 "\n" +
                 "    <dimen name=\"colorstrip_height\">6dip</dimen>\n" +
@@ -499,7 +500,7 @@
 
     public void testCommentHandling() throws Exception {
         checkFormat(
-                XmlFormatPreferences.create(), "res/layout/layout1.xml",
+                EclipseXmlFormatPreferences.create(), "res/layout/layout1.xml",
                 "<foo >\n" +
                 "\n" +
                 "    <!-- abc\n" +
@@ -543,7 +544,7 @@
 
     public void testCommentHandling2() throws Exception {
         checkFormat(
-                XmlFormatPreferences.create(), "res/layout-xlarge/layout.xml",
+                EclipseXmlFormatPreferences.create(), "res/layout-xlarge/layout.xml",
                 "<foo >\n" +
                 "    <!-- multi -->\n" +
                 "\n" +
@@ -561,7 +562,7 @@
 
     public void testMenus1() throws Exception {
         checkFormat(
-                XmlFormatPreferences.create(), "res/menu/menu1.xml",
+                EclipseXmlFormatPreferences.create(), "res/menu/menu1.xml",
                 // http://code.google.com/p/android/issues/detail?id=21383
                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                 "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n" +
@@ -614,7 +615,7 @@
     }
 
     public void testMenus2() throws Exception {
-        XmlFormatPreferences prefs = XmlFormatPreferences.create();
+        EclipseXmlFormatPreferences prefs = EclipseXmlFormatPreferences.create();
         prefs.removeEmptyLines = true;
         checkFormat(
                 prefs, "res/drawable-hdpi/layerlist.xml",
@@ -640,6 +641,7 @@
                 "    </shape>\n" +
                 "  </item>\n" +
                 "</layer-list>",
+
                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                 "<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n" +
                 "    <item>\n" +
@@ -665,7 +667,7 @@
 
     public void testMenus3() throws Exception {
         checkFormat(
-                XmlFormatPreferences.create(), "res/menu/menu1.xml",
+                EclipseXmlFormatPreferences.create(), "res/menu/menu1.xml",
                 // http://code.google.com/p/android/issues/detail?id=21227
                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                 "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n" +
@@ -703,7 +705,7 @@
 
     public void testColors1() throws Exception {
         checkFormat(
-                XmlFormatPreferences.create(), "res/values/colors.xml",
+                EclipseXmlFormatPreferences.create(), "res/values/colors.xml",
                 "<resources>\n" +
                 "  <color name=\"enrollment_error\">#99e21f14</color>\n" +
                 "\n" +
@@ -719,7 +721,7 @@
     }
 
     public void testEclipseFormatStyle1() throws Exception {
-        XmlFormatPreferences prefs = new XmlFormatPreferences() {
+        EclipseXmlFormatPreferences prefs = new EclipseXmlFormatPreferences() {
             @Override
             public String getOneIndentUnit() {
                 return "\t";
@@ -747,7 +749,7 @@
     }
 
     public void testEclipseFormatStyle2() throws Exception {
-        XmlFormatPreferences prefs = new XmlFormatPreferences() {
+        EclipseXmlFormatPreferences prefs = new EclipseXmlFormatPreferences() {
             @Override
             public String getOneIndentUnit() {
                 return "  ";
@@ -937,4 +939,19 @@
                 "</resources>");
     }
 
+    public void test52887() throws Exception {
+        // https://code.google.com/p/android/issues/detail?id=52887
+        checkFormat(
+                "res/layout/relative.xml",
+
+                "<!--Comment-->\n" +
+                "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
+                "  android:layout_width=\"match_parent\"\n" +
+                "  android:layout_height=\"match_parent\"/>\n",
+
+                "<!-- Comment -->\n" +
+                "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
+                "    android:layout_width=\"match_parent\"\n" +
+                "    android:layout_height=\"match_parent\" />\n");
+    }
 }
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestAttribute.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestAttribute.java
index 76840b1..752d61c 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestAttribute.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestAttribute.java
@@ -18,7 +18,7 @@
 import com.android.annotations.NonNull;
 import com.android.ide.common.api.IDragElement.IDragAttribute;
 import com.android.ide.common.api.INode.IAttribute;
-import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
+import com.android.ide.common.xml.XmlAttributeSortOrder;
 
 /** Test/mock implementation of {@link IAttribute} and {@link IDragAttribute} */
 public class TestAttribute implements IAttribute, IDragAttribute {
@@ -56,6 +56,6 @@
     }
 
     public int compareTo(IDragAttribute o) {
-        return UiAttributeNode.compareAttributes(mName, o.getName());
+        return XmlAttributeSortOrder.compareAttributes(mName, o.getName());
     }
 }
\ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestNode.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestNode.java
index f5c9d4d..30886e4 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestNode.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestNode.java
@@ -15,13 +15,13 @@
  */
 package com.android.ide.common.layout;
 
+import static com.android.SdkConstants.ANDROID_URI;
 import static com.android.SdkConstants.ANDROID_WIDGET_PREFIX;
 import static com.android.SdkConstants.ATTR_ID;
-import static com.android.SdkConstants.ANDROID_URI;
 import static junit.framework.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
 
 import com.android.annotations.NonNull;
 import com.android.annotations.Nullable;
@@ -30,9 +30,10 @@
 import com.android.ide.common.api.INodeHandler;
 import com.android.ide.common.api.Margins;
 import com.android.ide.common.api.Rect;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
-import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter;
+import com.android.ide.common.xml.XmlFormatStyle;
+import com.android.ide.common.xml.XmlPrettyPrinter;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences;
+import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter;
 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
 import com.google.common.base.Splitter;
 
@@ -52,8 +53,6 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import junit.framework.Assert;
-
 /** Test/mock implementation of {@link INode} */
 @SuppressWarnings("javadoc")
 public class TestNode implements INode {
@@ -257,7 +256,7 @@
         String xml = dumpDocument(document);
         document = DomUtilities.parseDocument(xml, false);
 
-        XmlPrettyPrinter printer = new XmlPrettyPrinter(XmlFormatPreferences.create(),
+        XmlPrettyPrinter printer = new EclipseXmlPrettyPrinter(EclipseXmlFormatPreferences.create(),
                 XmlFormatStyle.LAYOUT, "\n");
         StringBuilder sb = new StringBuilder(1000);
         sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
@@ -466,7 +465,7 @@
             int bottom = Integer.parseInt(bounds[3]);
             mBounds = new Rect(left, top, right - left, bottom - top);
         } catch (NumberFormatException nufe) {
-            Assert.fail(nufe.getLocalizedMessage());
+            fail(nufe.getLocalizedMessage());
         }
         String tag = matcher.group(3);
 
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategyTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategyTest.java
index 4fe2a7f..9c7e25d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategyTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/formatting/AndroidXmlFormattingStrategyTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.ide.eclipse.adt.internal.editors.formatting;
 
+import com.android.ide.common.xml.XmlFormatPreferences;
+
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.Document;
 import org.eclipse.text.edits.MalformedTreeException;
@@ -61,7 +63,9 @@
 
     // In the given before document, replace the range indicated by [ and ] with the given
     // formatted string, and assert that it's identical to the given after string
-    private void check(String before, String insert, String expected, XmlFormatPreferences prefs)
+    private void check(
+            String before, String insert, String expected,
+            XmlFormatPreferences prefs)
             throws MalformedTreeException, BadLocationException {
         int replaceStart = before.indexOf('[');
         assertTrue(replaceStart != -1);
diff --git a/eclipse/scripts/create_all_symlinks.sh b/eclipse/scripts/create_all_symlinks.sh
index 8f48fb7..ec738dc 100755
--- a/eclipse/scripts/create_all_symlinks.sh
+++ b/eclipse/scripts/create_all_symlinks.sh
@@ -225,7 +225,7 @@
 
 LIBS2=""
 for LIB in $LIBS; do
-  J="prebuilts/devtools/$LIB.jar"
+  J="prebuilts/devtools/tools/lib/$LIB.jar"
   if [[ -f $J ]]; then
     warn "## Using existing $J"
   else
@@ -271,7 +271,7 @@
   if [[ ! -f "$SRC" ]]; then
     ORIG_SRC="$SRC"
     # Take a prebuilts/devtools instead of a framework one if possible.
-    SRC="prebuilts/devtools/$SRC.jar"
+    SRC="prebuilts/devtools/tools/lib/$SRC.jar"
     if [[ ! -f "$SRC" ]]; then
       SRC="out/host/$PLATFORM/framework/$ORIG_SRC.jar"
     fi
diff --git a/emulator/gps/Android.mk b/emulator/gps/Android.mk
deleted file mode 100644
index 41bdc64..0000000
--- a/emulator/gps/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# We're moving the emulator-specific platform libs to
-# development.git/tools/emulator/. The following test is to ensure
-# smooth builds even if the tree contains both versions.
-#
-ifndef BUILD_EMULATOR_GPS_MODULE
-BUILD_EMULATOR_GPS_MODULE := true
-
-LOCAL_PATH := $(call my-dir)
-
-ifneq ($(TARGET_PRODUCT),sim)
-# HAL module implemenation, not prelinked and stored in
-# hw/<GPS_HARDWARE_MODULE_ID>.<ro.hardware>.so
-include $(CLEAR_VARS)
-LOCAL_PRELINK_MODULE := false
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-LOCAL_CFLAGS += -DQEMU_HARDWARE
-LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware
-LOCAL_SRC_FILES := gps_qemu.c
-LOCAL_MODULE := gps.goldfish
-LOCAL_MODULE_TAGS := debug
-include $(BUILD_SHARED_LIBRARY)
-endif
-
-endif # BUILD_EMULATOR_GPS_MODULE
diff --git a/emulator/gps/gps_qemu.c b/emulator/gps/gps_qemu.c
deleted file mode 100644
index eebe8d6..0000000
--- a/emulator/gps/gps_qemu.c
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* this implements a GPS hardware library for the Android emulator.
- * the following code should be built as a shared library that will be
- * placed into /system/lib/hw/gps.goldfish.so
- *
- * it will be loaded by the code in hardware/libhardware/hardware.c
- * which is itself called from android_location_GpsLocationProvider.cpp
- */
-
-
-#include <errno.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <sys/epoll.h>
-#include <math.h>
-#include <time.h>
-
-#define  LOG_TAG  "gps_qemu"
-#include <cutils/log.h>
-#include <cutils/sockets.h>
-#include <hardware/gps.h>
-#include <hardware/qemud.h>
-
-/* the name of the qemud-controlled socket */
-#define  QEMU_CHANNEL_NAME  "gps"
-
-#define  GPS_DEBUG  0
-
-#if GPS_DEBUG
-#  define  D(...)   ALOGD(__VA_ARGS__)
-#else
-#  define  D(...)   ((void)0)
-#endif
-
-/*****************************************************************/
-/*****************************************************************/
-/*****                                                       *****/
-/*****       N M E A   T O K E N I Z E R                     *****/
-/*****                                                       *****/
-/*****************************************************************/
-/*****************************************************************/
-
-typedef struct {
-    const char*  p;
-    const char*  end;
-} Token;
-
-#define  MAX_NMEA_TOKENS  16
-
-typedef struct {
-    int     count;
-    Token   tokens[ MAX_NMEA_TOKENS ];
-} NmeaTokenizer;
-
-static int
-nmea_tokenizer_init( NmeaTokenizer*  t, const char*  p, const char*  end )
-{
-    int    count = 0;
-    char*  q;
-
-    // the initial '$' is optional
-    if (p < end && p[0] == '$')
-        p += 1;
-
-    // remove trailing newline
-    if (end > p && end[-1] == '\n') {
-        end -= 1;
-        if (end > p && end[-1] == '\r')
-            end -= 1;
-    }
-
-    // get rid of checksum at the end of the sentecne
-    if (end >= p+3 && end[-3] == '*') {
-        end -= 3;
-    }
-
-    while (p < end) {
-        const char*  q = p;
-
-        q = memchr(p, ',', end-p);
-        if (q == NULL)
-            q = end;
-
-        if (q > p) {
-            if (count < MAX_NMEA_TOKENS) {
-                t->tokens[count].p   = p;
-                t->tokens[count].end = q;
-                count += 1;
-            }
-        }
-        if (q < end)
-            q += 1;
-
-        p = q;
-    }
-
-    t->count = count;
-    return count;
-}
-
-static Token
-nmea_tokenizer_get( NmeaTokenizer*  t, int  index )
-{
-    Token  tok;
-    static const char*  dummy = "";
-
-    if (index < 0 || index >= t->count) {
-        tok.p = tok.end = dummy;
-    } else
-        tok = t->tokens[index];
-
-    return tok;
-}
-
-
-static int
-str2int( const char*  p, const char*  end )
-{
-    int   result = 0;
-    int   len    = end - p;
-
-    for ( ; len > 0; len--, p++ )
-    {
-        int  c;
-
-        if (p >= end)
-            goto Fail;
-
-        c = *p - '0';
-        if ((unsigned)c >= 10)
-            goto Fail;
-
-        result = result*10 + c;
-    }
-    return  result;
-
-Fail:
-    return -1;
-}
-
-static double
-str2float( const char*  p, const char*  end )
-{
-    int   result = 0;
-    int   len    = end - p;
-    char  temp[16];
-
-    if (len >= (int)sizeof(temp))
-        return 0.;
-
-    memcpy( temp, p, len );
-    temp[len] = 0;
-    return strtod( temp, NULL );
-}
-
-/*****************************************************************/
-/*****************************************************************/
-/*****                                                       *****/
-/*****       N M E A   P A R S E R                           *****/
-/*****                                                       *****/
-/*****************************************************************/
-/*****************************************************************/
-
-#define  NMEA_MAX_SIZE  83
-
-typedef struct {
-    int     pos;
-    int     overflow;
-    int     utc_year;
-    int     utc_mon;
-    int     utc_day;
-    int     utc_diff;
-    GpsLocation  fix;
-    gps_location_callback  callback;
-    char    in[ NMEA_MAX_SIZE+1 ];
-} NmeaReader;
-
-
-static void
-nmea_reader_update_utc_diff( NmeaReader*  r )
-{
-    time_t         now = time(NULL);
-    struct tm      tm_local;
-    struct tm      tm_utc;
-    long           time_local, time_utc;
-
-    gmtime_r( &now, &tm_utc );
-    localtime_r( &now, &tm_local );
-
-    time_local = tm_local.tm_sec +
-                 60*(tm_local.tm_min +
-                 60*(tm_local.tm_hour +
-                 24*(tm_local.tm_yday +
-                 365*tm_local.tm_year)));
-
-    time_utc = tm_utc.tm_sec +
-               60*(tm_utc.tm_min +
-               60*(tm_utc.tm_hour +
-               24*(tm_utc.tm_yday +
-               365*tm_utc.tm_year)));
-
-    r->utc_diff = time_utc - time_local;
-}
-
-
-static void
-nmea_reader_init( NmeaReader*  r )
-{
-    memset( r, 0, sizeof(*r) );
-
-    r->pos      = 0;
-    r->overflow = 0;
-    r->utc_year = -1;
-    r->utc_mon  = -1;
-    r->utc_day  = -1;
-    r->callback = NULL;
-    r->fix.size = sizeof(r->fix);
-
-    nmea_reader_update_utc_diff( r );
-}
-
-
-static void
-nmea_reader_set_callback( NmeaReader*  r, gps_location_callback  cb )
-{
-    r->callback = cb;
-    if (cb != NULL && r->fix.flags != 0) {
-        D("%s: sending latest fix to new callback", __FUNCTION__);
-        r->callback( &r->fix );
-        r->fix.flags = 0;
-    }
-}
-
-
-static int
-nmea_reader_update_time( NmeaReader*  r, Token  tok )
-{
-    int        hour, minute;
-    double     seconds;
-    struct tm  tm;
-    time_t     fix_time;
-
-    if (tok.p + 6 > tok.end)
-        return -1;
-
-    if (r->utc_year < 0) {
-        // no date yet, get current one
-        time_t  now = time(NULL);
-        gmtime_r( &now, &tm );
-        r->utc_year = tm.tm_year + 1900;
-        r->utc_mon  = tm.tm_mon + 1;
-        r->utc_day  = tm.tm_mday;
-    }
-
-    hour    = str2int(tok.p,   tok.p+2);
-    minute  = str2int(tok.p+2, tok.p+4);
-    seconds = str2float(tok.p+4, tok.end);
-
-    tm.tm_hour  = hour;
-    tm.tm_min   = minute;
-    tm.tm_sec   = (int) seconds;
-    tm.tm_year  = r->utc_year - 1900;
-    tm.tm_mon   = r->utc_mon - 1;
-    tm.tm_mday  = r->utc_day;
-    tm.tm_isdst = -1;
-
-    fix_time = mktime( &tm ) + r->utc_diff;
-    r->fix.timestamp = (long long)fix_time * 1000;
-    return 0;
-}
-
-static int
-nmea_reader_update_date( NmeaReader*  r, Token  date, Token  time )
-{
-    Token  tok = date;
-    int    day, mon, year;
-
-    if (tok.p + 6 != tok.end) {
-        D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);
-        return -1;
-    }
-    day  = str2int(tok.p, tok.p+2);
-    mon  = str2int(tok.p+2, tok.p+4);
-    year = str2int(tok.p+4, tok.p+6) + 2000;
-
-    if ((day|mon|year) < 0) {
-        D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);
-        return -1;
-    }
-
-    r->utc_year  = year;
-    r->utc_mon   = mon;
-    r->utc_day   = day;
-
-    return nmea_reader_update_time( r, time );
-}
-
-
-static double
-convert_from_hhmm( Token  tok )
-{
-    double  val     = str2float(tok.p, tok.end);
-    int     degrees = (int)(floor(val) / 100);
-    double  minutes = val - degrees*100.;
-    double  dcoord  = degrees + minutes / 60.0;
-    return dcoord;
-}
-
-
-static int
-nmea_reader_update_latlong( NmeaReader*  r,
-                            Token        latitude,
-                            char         latitudeHemi,
-                            Token        longitude,
-                            char         longitudeHemi )
-{
-    double   lat, lon;
-    Token    tok;
-
-    tok = latitude;
-    if (tok.p + 6 > tok.end) {
-        D("latitude is too short: '%.*s'", tok.end-tok.p, tok.p);
-        return -1;
-    }
-    lat = convert_from_hhmm(tok);
-    if (latitudeHemi == 'S')
-        lat = -lat;
-
-    tok = longitude;
-    if (tok.p + 6 > tok.end) {
-        D("longitude is too short: '%.*s'", tok.end-tok.p, tok.p);
-        return -1;
-    }
-    lon = convert_from_hhmm(tok);
-    if (longitudeHemi == 'W')
-        lon = -lon;
-
-    r->fix.flags    |= GPS_LOCATION_HAS_LAT_LONG;
-    r->fix.latitude  = lat;
-    r->fix.longitude = lon;
-    return 0;
-}
-
-
-static int
-nmea_reader_update_altitude( NmeaReader*  r,
-                             Token        altitude,
-                             Token        units )
-{
-    double  alt;
-    Token   tok = altitude;
-
-    if (tok.p >= tok.end)
-        return -1;
-
-    r->fix.flags   |= GPS_LOCATION_HAS_ALTITUDE;
-    r->fix.altitude = str2float(tok.p, tok.end);
-    return 0;
-}
-
-
-static int
-nmea_reader_update_bearing( NmeaReader*  r,
-                            Token        bearing )
-{
-    double  alt;
-    Token   tok = bearing;
-
-    if (tok.p >= tok.end)
-        return -1;
-
-    r->fix.flags   |= GPS_LOCATION_HAS_BEARING;
-    r->fix.bearing  = str2float(tok.p, tok.end);
-    return 0;
-}
-
-
-static int
-nmea_reader_update_speed( NmeaReader*  r,
-                          Token        speed )
-{
-    double  alt;
-    Token   tok = speed;
-
-    if (tok.p >= tok.end)
-        return -1;
-
-    r->fix.flags   |= GPS_LOCATION_HAS_SPEED;
-    r->fix.speed    = str2float(tok.p, tok.end);
-    return 0;
-}
-
-
-static void
-nmea_reader_parse( NmeaReader*  r )
-{
-   /* we received a complete sentence, now parse it to generate
-    * a new GPS fix...
-    */
-    NmeaTokenizer  tzer[1];
-    Token          tok;
-
-    D("Received: '%.*s'", r->pos, r->in);
-    if (r->pos < 9) {
-        D("Too short. discarded.");
-        return;
-    }
-
-    nmea_tokenizer_init(tzer, r->in, r->in + r->pos);
-#if GPS_DEBUG
-    {
-        int  n;
-        D("Found %d tokens", tzer->count);
-        for (n = 0; n < tzer->count; n++) {
-            Token  tok = nmea_tokenizer_get(tzer,n);
-            D("%2d: '%.*s'", n, tok.end-tok.p, tok.p);
-        }
-    }
-#endif
-
-    tok = nmea_tokenizer_get(tzer, 0);
-    if (tok.p + 5 > tok.end) {
-        D("sentence id '%.*s' too short, ignored.", tok.end-tok.p, tok.p);
-        return;
-    }
-
-    // ignore first two characters.
-    tok.p += 2;
-    if ( !memcmp(tok.p, "GGA", 3) ) {
-        // GPS fix
-        Token  tok_time          = nmea_tokenizer_get(tzer,1);
-        Token  tok_latitude      = nmea_tokenizer_get(tzer,2);
-        Token  tok_latitudeHemi  = nmea_tokenizer_get(tzer,3);
-        Token  tok_longitude     = nmea_tokenizer_get(tzer,4);
-        Token  tok_longitudeHemi = nmea_tokenizer_get(tzer,5);
-        Token  tok_altitude      = nmea_tokenizer_get(tzer,9);
-        Token  tok_altitudeUnits = nmea_tokenizer_get(tzer,10);
-
-        nmea_reader_update_time(r, tok_time);
-        nmea_reader_update_latlong(r, tok_latitude,
-                                      tok_latitudeHemi.p[0],
-                                      tok_longitude,
-                                      tok_longitudeHemi.p[0]);
-        nmea_reader_update_altitude(r, tok_altitude, tok_altitudeUnits);
-
-    } else if ( !memcmp(tok.p, "GSA", 3) ) {
-        // do something ?
-    } else if ( !memcmp(tok.p, "RMC", 3) ) {
-        Token  tok_time          = nmea_tokenizer_get(tzer,1);
-        Token  tok_fixStatus     = nmea_tokenizer_get(tzer,2);
-        Token  tok_latitude      = nmea_tokenizer_get(tzer,3);
-        Token  tok_latitudeHemi  = nmea_tokenizer_get(tzer,4);
-        Token  tok_longitude     = nmea_tokenizer_get(tzer,5);
-        Token  tok_longitudeHemi = nmea_tokenizer_get(tzer,6);
-        Token  tok_speed         = nmea_tokenizer_get(tzer,7);
-        Token  tok_bearing       = nmea_tokenizer_get(tzer,8);
-        Token  tok_date          = nmea_tokenizer_get(tzer,9);
-
-        D("in RMC, fixStatus=%c", tok_fixStatus.p[0]);
-        if (tok_fixStatus.p[0] == 'A')
-        {
-            nmea_reader_update_date( r, tok_date, tok_time );
-
-            nmea_reader_update_latlong( r, tok_latitude,
-                                           tok_latitudeHemi.p[0],
-                                           tok_longitude,
-                                           tok_longitudeHemi.p[0] );
-
-            nmea_reader_update_bearing( r, tok_bearing );
-            nmea_reader_update_speed  ( r, tok_speed );
-        }
-    } else {
-        tok.p -= 2;
-        D("unknown sentence '%.*s", tok.end-tok.p, tok.p);
-    }
-    if (r->fix.flags != 0) {
-#if GPS_DEBUG
-        char   temp[256];
-        char*  p   = temp;
-        char*  end = p + sizeof(temp);
-        struct tm   utc;
-
-        p += snprintf( p, end-p, "sending fix" );
-        if (r->fix.flags & GPS_LOCATION_HAS_LAT_LONG) {
-            p += snprintf(p, end-p, " lat=%g lon=%g", r->fix.latitude, r->fix.longitude);
-        }
-        if (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE) {
-            p += snprintf(p, end-p, " altitude=%g", r->fix.altitude);
-        }
-        if (r->fix.flags & GPS_LOCATION_HAS_SPEED) {
-            p += snprintf(p, end-p, " speed=%g", r->fix.speed);
-        }
-        if (r->fix.flags & GPS_LOCATION_HAS_BEARING) {
-            p += snprintf(p, end-p, " bearing=%g", r->fix.bearing);
-        }
-        if (r->fix.flags & GPS_LOCATION_HAS_ACCURACY) {
-            p += snprintf(p,end-p, " accuracy=%g", r->fix.accuracy);
-        }
-        gmtime_r( (time_t*) &r->fix.timestamp, &utc );
-        p += snprintf(p, end-p, " time=%s", asctime( &utc ) );
-        D(temp);
-#endif
-        if (r->callback) {
-            r->callback( &r->fix );
-            r->fix.flags = 0;
-        }
-        else {
-            D("no callback, keeping data until needed !");
-        }
-    }
-}
-
-
-static void
-nmea_reader_addc( NmeaReader*  r, int  c )
-{
-    if (r->overflow) {
-        r->overflow = (c != '\n');
-        return;
-    }
-
-    if (r->pos >= (int) sizeof(r->in)-1 ) {
-        r->overflow = 1;
-        r->pos      = 0;
-        return;
-    }
-
-    r->in[r->pos] = (char)c;
-    r->pos       += 1;
-
-    if (c == '\n') {
-        nmea_reader_parse( r );
-        r->pos = 0;
-    }
-}
-
-
-/*****************************************************************/
-/*****************************************************************/
-/*****                                                       *****/
-/*****       C O N N E C T I O N   S T A T E                 *****/
-/*****                                                       *****/
-/*****************************************************************/
-/*****************************************************************/
-
-/* commands sent to the gps thread */
-enum {
-    CMD_QUIT  = 0,
-    CMD_START = 1,
-    CMD_STOP  = 2
-};
-
-
-/* this is the state of our connection to the qemu_gpsd daemon */
-typedef struct {
-    int                     init;
-    int                     fd;
-    GpsCallbacks            callbacks;
-    pthread_t               thread;
-    int                     control[2];
-} GpsState;
-
-static GpsState  _gps_state[1];
-
-
-static void
-gps_state_done( GpsState*  s )
-{
-    // tell the thread to quit, and wait for it
-    char   cmd = CMD_QUIT;
-    void*  dummy;
-    write( s->control[0], &cmd, 1 );
-    pthread_join(s->thread, &dummy);
-
-    // close the control socket pair
-    close( s->control[0] ); s->control[0] = -1;
-    close( s->control[1] ); s->control[1] = -1;
-
-    // close connection to the QEMU GPS daemon
-    close( s->fd ); s->fd = -1;
-    s->init = 0;
-}
-
-
-static void
-gps_state_start( GpsState*  s )
-{
-    char  cmd = CMD_START;
-    int   ret;
-
-    do { ret=write( s->control[0], &cmd, 1 ); }
-    while (ret < 0 && errno == EINTR);
-
-    if (ret != 1)
-        D("%s: could not send CMD_START command: ret=%d: %s",
-          __FUNCTION__, ret, strerror(errno));
-}
-
-
-static void
-gps_state_stop( GpsState*  s )
-{
-    char  cmd = CMD_STOP;
-    int   ret;
-
-    do { ret=write( s->control[0], &cmd, 1 ); }
-    while (ret < 0 && errno == EINTR);
-
-    if (ret != 1)
-        D("%s: could not send CMD_STOP command: ret=%d: %s",
-          __FUNCTION__, ret, strerror(errno));
-}
-
-
-static int
-epoll_register( int  epoll_fd, int  fd )
-{
-    struct epoll_event  ev;
-    int                 ret, flags;
-
-    /* important: make the fd non-blocking */
-    flags = fcntl(fd, F_GETFL);
-    fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-
-    ev.events  = EPOLLIN;
-    ev.data.fd = fd;
-    do {
-        ret = epoll_ctl( epoll_fd, EPOLL_CTL_ADD, fd, &ev );
-    } while (ret < 0 && errno == EINTR);
-    return ret;
-}
-
-
-static int
-epoll_deregister( int  epoll_fd, int  fd )
-{
-    int  ret;
-    do {
-        ret = epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL );
-    } while (ret < 0 && errno == EINTR);
-    return ret;
-}
-
-/* this is the main thread, it waits for commands from gps_state_start/stop and,
- * when started, messages from the QEMU GPS daemon. these are simple NMEA sentences
- * that must be parsed to be converted into GPS fixes sent to the framework
- */
-static void
-gps_state_thread( void*  arg )
-{
-    GpsState*   state = (GpsState*) arg;
-    NmeaReader  reader[1];
-    int         epoll_fd   = epoll_create(2);
-    int         started    = 0;
-    int         gps_fd     = state->fd;
-    int         control_fd = state->control[1];
-
-    nmea_reader_init( reader );
-
-    // register control file descriptors for polling
-    epoll_register( epoll_fd, control_fd );
-    epoll_register( epoll_fd, gps_fd );
-
-    D("gps thread running");
-
-    // now loop
-    for (;;) {
-        struct epoll_event   events[2];
-        int                  ne, nevents;
-
-        nevents = epoll_wait( epoll_fd, events, 2, -1 );
-        if (nevents < 0) {
-            if (errno != EINTR)
-                ALOGE("epoll_wait() unexpected error: %s", strerror(errno));
-            continue;
-        }
-        D("gps thread received %d events", nevents);
-        for (ne = 0; ne < nevents; ne++) {
-            if ((events[ne].events & (EPOLLERR|EPOLLHUP)) != 0) {
-                ALOGE("EPOLLERR or EPOLLHUP after epoll_wait() !?");
-                return;
-            }
-            if ((events[ne].events & EPOLLIN) != 0) {
-                int  fd = events[ne].data.fd;
-
-                if (fd == control_fd)
-                {
-                    char  cmd = 255;
-                    int   ret;
-                    D("gps control fd event");
-                    do {
-                        ret = read( fd, &cmd, 1 );
-                    } while (ret < 0 && errno == EINTR);
-
-                    if (cmd == CMD_QUIT) {
-                        D("gps thread quitting on demand");
-                        return;
-                    }
-                    else if (cmd == CMD_START) {
-                        if (!started) {
-                            D("gps thread starting  location_cb=%p", state->callbacks.location_cb);
-                            started = 1;
-                            nmea_reader_set_callback( reader, state->callbacks.location_cb );
-                        }
-                    }
-                    else if (cmd == CMD_STOP) {
-                        if (started) {
-                            D("gps thread stopping");
-                            started = 0;
-                            nmea_reader_set_callback( reader, NULL );
-                        }
-                    }
-                }
-                else if (fd == gps_fd)
-                {
-                    char  buff[32];
-                    D("gps fd event");
-                    for (;;) {
-                        int  nn, ret;
-
-                        ret = read( fd, buff, sizeof(buff) );
-                        if (ret < 0) {
-                            if (errno == EINTR)
-                                continue;
-                            if (errno != EWOULDBLOCK)
-                                ALOGE("error while reading from gps daemon socket: %s:", strerror(errno));
-                            break;
-                        }
-                        D("received %d bytes: %.*s", ret, ret, buff);
-                        for (nn = 0; nn < ret; nn++)
-                            nmea_reader_addc( reader, buff[nn] );
-                    }
-                    D("gps fd event end");
-                }
-                else
-                {
-                    ALOGE("epoll_wait() returned unkown fd %d ?", fd);
-                }
-            }
-        }
-    }
-}
-
-
-static void
-gps_state_init( GpsState*  state, GpsCallbacks* callbacks )
-{
-    state->init       = 1;
-    state->control[0] = -1;
-    state->control[1] = -1;
-    state->fd         = -1;
-
-    state->fd = qemud_channel_open(QEMU_CHANNEL_NAME);
-
-    if (state->fd < 0) {
-        D("no gps emulation detected");
-        return;
-    }
-
-    D("gps emulation will read from '%s' qemud channel", QEMU_CHANNEL_NAME );
-
-    if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->control ) < 0 ) {
-        ALOGE("could not create thread control socket pair: %s", strerror(errno));
-        goto Fail;
-    }
-
-    state->thread = callbacks->create_thread_cb( "gps_state_thread", gps_state_thread, state );
-
-    if ( !state->thread ) {
-        ALOGE("could not create gps thread: %s", strerror(errno));
-        goto Fail;
-    }
-
-    state->callbacks = *callbacks;
-
-    D("gps state initialized");
-    return;
-
-Fail:
-    gps_state_done( state );
-}
-
-
-/*****************************************************************/
-/*****************************************************************/
-/*****                                                       *****/
-/*****       I N T E R F A C E                               *****/
-/*****                                                       *****/
-/*****************************************************************/
-/*****************************************************************/
-
-
-static int
-qemu_gps_init(GpsCallbacks* callbacks)
-{
-    GpsState*  s = _gps_state;
-
-    if (!s->init)
-        gps_state_init(s, callbacks);
-
-    if (s->fd < 0)
-        return -1;
-
-    return 0;
-}
-
-static void
-qemu_gps_cleanup(void)
-{
-    GpsState*  s = _gps_state;
-
-    if (s->init)
-        gps_state_done(s);
-}
-
-
-static int
-qemu_gps_start()
-{
-    GpsState*  s = _gps_state;
-
-    if (!s->init) {
-        D("%s: called with uninitialized state !!", __FUNCTION__);
-        return -1;
-    }
-
-    D("%s: called", __FUNCTION__);
-    gps_state_start(s);
-    return 0;
-}
-
-
-static int
-qemu_gps_stop()
-{
-    GpsState*  s = _gps_state;
-
-    if (!s->init) {
-        D("%s: called with uninitialized state !!", __FUNCTION__);
-        return -1;
-    }
-
-    D("%s: called", __FUNCTION__);
-    gps_state_stop(s);
-    return 0;
-}
-
-
-static int
-qemu_gps_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty)
-{
-    return 0;
-}
-
-static int
-qemu_gps_inject_location(double latitude, double longitude, float accuracy)
-{
-    return 0;
-}
-
-static void
-qemu_gps_delete_aiding_data(GpsAidingData flags)
-{
-}
-
-static int qemu_gps_set_position_mode(GpsPositionMode mode, int fix_frequency)
-{
-    // FIXME - support fix_frequency
-    return 0;
-}
-
-static const void*
-qemu_gps_get_extension(const char* name)
-{
-    // no extensions supported
-    return NULL;
-}
-
-static const GpsInterface  qemuGpsInterface = {
-    sizeof(GpsInterface),
-    qemu_gps_init,
-    qemu_gps_start,
-    qemu_gps_stop,
-    qemu_gps_cleanup,
-    qemu_gps_inject_time,
-    qemu_gps_inject_location,
-    qemu_gps_delete_aiding_data,
-    qemu_gps_set_position_mode,
-    qemu_gps_get_extension,
-};
-
-const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)
-{
-    return &qemuGpsInterface;
-}
-
-static int open_gps(const struct hw_module_t* module, char const* name,
-        struct hw_device_t** device)
-{
-    struct gps_device_t *dev = malloc(sizeof(struct gps_device_t));
-    memset(dev, 0, sizeof(*dev));
-
-    dev->common.tag = HARDWARE_DEVICE_TAG;
-    dev->common.version = 0;
-    dev->common.module = (struct hw_module_t*)module;
-//    dev->common.close = (int (*)(struct hw_device_t*))close_lights;
-    dev->get_gps_interface = gps__get_gps_interface;
-
-    *device = (struct hw_device_t*)dev;
-    return 0;
-}
-
-
-static struct hw_module_methods_t gps_module_methods = {
-    .open = open_gps
-};
-
-struct hw_module_t HAL_MODULE_INFO_SYM = {
-    .tag = HARDWARE_MODULE_TAG,
-    .version_major = 1,
-    .version_minor = 0,
-    .id = GPS_HARDWARE_MODULE_ID,
-    .name = "Goldfish GPS Module",
-    .author = "The Android Open Source Project",
-    .methods = &gps_module_methods,
-};
diff --git a/emulator/qemud/Android.mk b/emulator/qemud/Android.mk
deleted file mode 100644
index 5666a74..0000000
--- a/emulator/qemud/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-
-# We're moving the emulator-specific platform libs to
-# development.git/tools/emulator/. The following test is to ensure
-# smooth builds even if the tree contains both versions.
-#
-ifndef BUILD_EMULATOR_QEMUD
-BUILD_EMULATOR_QEMUD := true
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	qemud.c
-
-
-LOCAL_SHARED_LIBRARIES := \
-	libcutils \
-
-LOCAL_MODULE:= qemud
-LOCAL_MODULE_TAGS := debug
-
-include $(BUILD_EXECUTABLE)
-
-endif # BUILD_EMULATOR_QEMUD
\ No newline at end of file
diff --git a/emulator/qemud/qemud.c b/emulator/qemud/qemud.c
deleted file mode 100644
index e836376..0000000
--- a/emulator/qemud/qemud.c
+++ /dev/null
@@ -1,1719 +0,0 @@
-#include <stdint.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <termios.h>
-#include <cutils/sockets.h>
-
-/*
- *  the qemud daemon program is only used within Android as a bridge
- *  between the emulator program and the emulated system. it really works as
- *  a simple stream multiplexer that works as follows:
- *
- *    - qemud is started by init following instructions in
- *      /system/etc/init.goldfish.rc (i.e. it is never started on real devices)
- *
- *    - qemud communicates with the emulator program through a single serial
- *      port, whose name is passed through a kernel boot parameter
- *      (e.g. android.qemud=ttyS1)
- *
- *    - qemud binds one unix local stream socket (/dev/socket/qemud, created
- *      by init through /system/etc/init.goldfish.rc).
- *
- *
- *      emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1
- *                                                            |
- *                                                            +--> client2
- *
- *   - the special channel index 0 is used by the emulator and qemud only.
- *     other channel numbers correspond to clients. More specifically,
- *     connection are created like this:
- *
- *     * the client connects to /dev/socket/qemud
- *
- *     * the client sends the service name through the socket, as
- *            <service-name>
- *
- *     * qemud creates a "Client" object internally, assigns it an
- *       internal unique channel number > 0, then sends a connection
- *       initiation request to the emulator (i.e. through channel 0):
- *
- *           connect:<id>:<name>
- *
- *       where <name> is the service name, and <id> is a 2-hexchar
- *       number corresponding to the channel number.
- *
- *     * in case of success, the emulator responds through channel 0
- *       with:
- *
- *           ok:connect:<id>
- *
- *       after this, all messages between the client and the emulator
- *       are passed in pass-through mode.
- *
- *     * if the emulator refuses the service connection, it will
- *       send the following through channel 0:
- *
- *           ko:connect:<id>:reason-for-failure
- *
- *     * If the client closes the connection, qemud sends the following
- *       to the emulator:
- *
- *           disconnect:<id>
- *
- *       The same message is the opposite direction if the emulator
- *       chooses to close the connection.
- *
- *     * any command sent through channel 0 to the emulator that is
- *       not properly recognized will be answered by:
- *
- *           ko:unknown command
- *
- *
- *  Internally, the daemon maintains a "Client" object for each client
- *  connection (i.e. accepting socket connection).
- */
-
-/* name of the single control socket used by the daemon */
-#define CONTROL_SOCKET_NAME  "qemud"
-
-#define  DEBUG     0
-#define  T_ACTIVE  0  /* set to 1 to dump traffic */
-
-#if DEBUG
-#  define LOG_TAG  "qemud"
-#  include <cutils/log.h>
-#  define  D(...)   ALOGD(__VA_ARGS__)
-#else
-#  define  D(...)  ((void)0)
-#  define  T(...)  ((void)0)
-#endif
-
-#if T_ACTIVE
-#  define  T(...)   D(__VA_ARGS__)
-#else
-#  define  T(...)   ((void)0)
-#endif
-
-/** UTILITIES
- **/
-
-static void
-fatal( const char*  fmt, ... )
-{
-    va_list  args;
-    va_start(args, fmt);
-    fprintf(stderr, "PANIC: ");
-    vfprintf(stderr, fmt, args);
-    fprintf(stderr, "\n" );
-    va_end(args);
-    exit(1);
-}
-
-static void*
-xalloc( size_t   sz )
-{
-    void*  p;
-
-    if (sz == 0)
-        return NULL;
-
-    p = malloc(sz);
-    if (p == NULL)
-        fatal( "not enough memory" );
-
-    return p;
-}
-
-#define  xnew(p)   (p) = xalloc(sizeof(*(p)))
-
-static void*
-xalloc0( size_t  sz )
-{
-    void*  p = xalloc(sz);
-    memset( p, 0, sz );
-    return p;
-}
-
-#define  xnew0(p)   (p) = xalloc0(sizeof(*(p)))
-
-#define  xfree(p)    (free((p)), (p) = NULL)
-
-static void*
-xrealloc( void*  block, size_t  size )
-{
-    void*  p = realloc( block, size );
-
-    if (p == NULL && size > 0)
-        fatal( "not enough memory" );
-
-    return p;
-}
-
-#define  xrenew(p,count)  (p) = xrealloc((p),sizeof(*(p))*(count))
-
-static int
-hex2int( const uint8_t*  data, int  len )
-{
-    int  result = 0;
-    while (len > 0) {
-        int       c = *data++;
-        unsigned  d;
-
-        result <<= 4;
-        do {
-            d = (unsigned)(c - '0');
-            if (d < 10)
-                break;
-
-            d = (unsigned)(c - 'a');
-            if (d < 6) {
-                d += 10;
-                break;
-            }
-
-            d = (unsigned)(c - 'A');
-            if (d < 6) {
-                d += 10;
-                break;
-            }
-
-            return -1;
-        }
-        while (0);
-
-        result |= d;
-        len    -= 1;
-    }
-    return  result;
-}
-
-
-static void
-int2hex( int  value, uint8_t*  to, int  width )
-{
-    int  nn = 0;
-    static const char hexchars[16] = "0123456789abcdef";
-
-    for ( --width; width >= 0; width--, nn++ ) {
-        to[nn] = hexchars[(value >> (width*4)) & 15];
-    }
-}
-
-static int
-fd_read(int  fd, void*  to, int  len)
-{
-    int  ret;
-
-    do {
-        ret = read(fd, to, len);
-    } while (ret < 0 && errno == EINTR);
-
-    return ret;
-}
-
-static int
-fd_write(int  fd, const void*  from, int  len)
-{
-    int  ret;
-
-    do {
-        ret = write(fd, from, len);
-    } while (ret < 0 && errno == EINTR);
-
-    return ret;
-}
-
-static void
-fd_setnonblock(int  fd)
-{
-    int  ret, flags;
-
-    do {
-        flags = fcntl(fd, F_GETFD);
-    } while (flags < 0 && errno == EINTR);
-
-    if (flags < 0) {
-        fatal( "%s: could not get flags for fd %d: %s",
-               __FUNCTION__, fd, strerror(errno) );
-    }
-
-    do {
-        ret = fcntl(fd, F_SETFD, flags | O_NONBLOCK);
-    } while (ret < 0 && errno == EINTR);
-
-    if (ret < 0) {
-        fatal( "%s: could not set fd %d to non-blocking: %s",
-               __FUNCTION__, fd, strerror(errno) );
-    }
-}
-
-
-static int
-fd_accept(int  fd)
-{
-    struct sockaddr  from;
-    socklen_t        fromlen = sizeof(from);
-    int              ret;
-
-    do {
-        ret = accept(fd, &from, &fromlen);
-    } while (ret < 0 && errno == EINTR);
-
-    return ret;
-}
-
-/** FD EVENT LOOP
- **/
-
-/* A Looper object is used to monitor activity on one or more
- * file descriptors (e.g sockets).
- *
- * - call looper_add() to register a function that will be
- *   called when events happen on the file descriptor.
- *
- * - call looper_enable() or looper_disable() to enable/disable
- *   the set of monitored events for a given file descriptor.
- *
- * - call looper_del() to unregister a file descriptor.
- *   this does *not* close the file descriptor.
- *
- * Note that you can only provide a single function to handle
- * all events related to a given file descriptor.
-
- * You can call looper_enable/_disable/_del within a function
- * callback.
- */
-
-/* the current implementation uses Linux's epoll facility
- * the event mask we use are simply combinations of EPOLLIN
- * EPOLLOUT, EPOLLHUP and EPOLLERR
- */
-#include <sys/epoll.h>
-
-#define  MAX_CHANNELS  16
-#define  MAX_EVENTS    (MAX_CHANNELS+1)  /* each channel + the serial fd */
-
-/* the event handler function type, 'user' is a user-specific
- * opaque pointer passed to looper_add().
- */
-typedef void (*EventFunc)( void*  user, int  events );
-
-/* bit flags for the LoopHook structure.
- *
- * HOOK_PENDING means that an event happened on the
- * corresponding file descriptor.
- *
- * HOOK_CLOSING is used to delay-close monitored
- * file descriptors.
- */
-enum {
-    HOOK_PENDING = (1 << 0),
-    HOOK_CLOSING = (1 << 1),
-};
-
-/* A LoopHook structure is used to monitor a given
- * file descriptor and record its event handler.
- */
-typedef struct {
-    int        fd;
-    int        wanted;  /* events we are monitoring */
-    int        events;  /* events that occured */
-    int        state;   /* see HOOK_XXX constants */
-    void*      ev_user; /* user-provided handler parameter */
-    EventFunc  ev_func; /* event handler callback */
-} LoopHook;
-
-/* Looper is the main object modeling a looper object
- */
-typedef struct {
-    int                  epoll_fd;
-    int                  num_fds;
-    int                  max_fds;
-    struct epoll_event*  events;
-    LoopHook*            hooks;
-} Looper;
-
-/* initialize a looper object */
-static void
-looper_init( Looper*  l )
-{
-    l->epoll_fd = epoll_create(4);
-    l->num_fds  = 0;
-    l->max_fds  = 0;
-    l->events   = NULL;
-    l->hooks    = NULL;
-}
-
-/* finalize a looper object */
-static void
-looper_done( Looper*  l )
-{
-    xfree(l->events);
-    xfree(l->hooks);
-    l->max_fds = 0;
-    l->num_fds = 0;
-
-    close(l->epoll_fd);
-    l->epoll_fd  = -1;
-}
-
-/* return the LoopHook corresponding to a given
- * monitored file descriptor, or NULL if not found
- */
-static LoopHook*
-looper_find( Looper*  l, int  fd )
-{
-    LoopHook*  hook = l->hooks;
-    LoopHook*  end  = hook + l->num_fds;
-
-    for ( ; hook < end; hook++ ) {
-        if (hook->fd == fd)
-            return hook;
-    }
-    return NULL;
-}
-
-/* grow the arrays in the looper object */
-static void
-looper_grow( Looper*  l )
-{
-    int  old_max = l->max_fds;
-    int  new_max = old_max + (old_max >> 1) + 4;
-    int  n;
-
-    xrenew( l->events, new_max );
-    xrenew( l->hooks,  new_max );
-    l->max_fds = new_max;
-
-    /* now change the handles to all events */
-    for (n = 0; n < l->num_fds; n++) {
-        struct epoll_event ev;
-        LoopHook*          hook = l->hooks + n;
-
-        ev.events   = hook->wanted;
-        ev.data.ptr = hook;
-        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
-    }
-}
-
-/* register a file descriptor and its event handler.
- * no event mask will be enabled
- */
-static void
-looper_add( Looper*  l, int  fd, EventFunc  func, void*  user )
-{
-    struct epoll_event  ev;
-    LoopHook*           hook;
-
-    if (l->num_fds >= l->max_fds)
-        looper_grow(l);
-
-    hook = l->hooks + l->num_fds;
-
-    hook->fd      = fd;
-    hook->ev_user = user;
-    hook->ev_func = func;
-    hook->state   = 0;
-    hook->wanted  = 0;
-    hook->events  = 0;
-
-    fd_setnonblock(fd);
-
-    ev.events   = 0;
-    ev.data.ptr = hook;
-    epoll_ctl( l->epoll_fd, EPOLL_CTL_ADD, fd, &ev );
-
-    l->num_fds += 1;
-}
-
-/* unregister a file descriptor and its event handler
- */
-static void
-looper_del( Looper*  l, int  fd )
-{
-    LoopHook*  hook = looper_find( l, fd );
-
-    if (!hook) {
-        D( "%s: invalid fd: %d", __FUNCTION__, fd );
-        return;
-    }
-    /* don't remove the hook yet */
-    hook->state |= HOOK_CLOSING;
-
-    epoll_ctl( l->epoll_fd, EPOLL_CTL_DEL, fd, NULL );
-}
-
-/* enable monitoring of certain events for a file
- * descriptor. This adds 'events' to the current
- * event mask
- */
-static void
-looper_enable( Looper*  l, int  fd, int  events )
-{
-    LoopHook*  hook = looper_find( l, fd );
-
-    if (!hook) {
-        D("%s: invalid fd: %d", __FUNCTION__, fd );
-        return;
-    }
-
-    if (events & ~hook->wanted) {
-        struct epoll_event  ev;
-
-        hook->wanted |= events;
-        ev.events   = hook->wanted;
-        ev.data.ptr = hook;
-
-        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
-    }
-}
-
-/* disable monitoring of certain events for a file
- * descriptor. This ignores events that are not
- * currently enabled.
- */
-static void
-looper_disable( Looper*  l, int  fd, int  events )
-{
-    LoopHook*  hook = looper_find( l, fd );
-
-    if (!hook) {
-        D("%s: invalid fd: %d", __FUNCTION__, fd );
-        return;
-    }
-
-    if (events & hook->wanted) {
-        struct epoll_event  ev;
-
-        hook->wanted &= ~events;
-        ev.events   = hook->wanted;
-        ev.data.ptr = hook;
-
-        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
-    }
-}
-
-/* wait until an event occurs on one of the registered file
- * descriptors. Only returns in case of error !!
- */
-static void
-looper_loop( Looper*  l )
-{
-    for (;;) {
-        int  n, count;
-
-        do {
-            count = epoll_wait( l->epoll_fd, l->events, l->num_fds, -1 );
-        } while (count < 0 && errno == EINTR);
-
-        if (count < 0) {
-            D("%s: error: %s", __FUNCTION__, strerror(errno) );
-            return;
-        }
-
-        if (count == 0) {
-            D("%s: huh ? epoll returned count=0", __FUNCTION__);
-            continue;
-        }
-
-        /* mark all pending hooks */
-        for (n = 0; n < count; n++) {
-            LoopHook*  hook = l->events[n].data.ptr;
-            hook->state  = HOOK_PENDING;
-            hook->events = l->events[n].events;
-        }
-
-        /* execute hook callbacks. this may change the 'hooks'
-         * and 'events' array, as well as l->num_fds, so be careful */
-        for (n = 0; n < l->num_fds; n++) {
-            LoopHook*  hook = l->hooks + n;
-            if (hook->state & HOOK_PENDING) {
-                hook->state &= ~HOOK_PENDING;
-                hook->ev_func( hook->ev_user, hook->events );
-            }
-        }
-
-        /* now remove all the hooks that were closed by
-         * the callbacks */
-        for (n = 0; n < l->num_fds;) {
-            struct epoll_event ev;
-            LoopHook*  hook = l->hooks + n;
-
-            if (!(hook->state & HOOK_CLOSING)) {
-                n++;
-                continue;
-            }
-
-            hook[0]     = l->hooks[l->num_fds-1];
-            l->num_fds -= 1;
-            ev.events   = hook->wanted;
-            ev.data.ptr = hook;
-            epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
-        }
-    }
-}
-
-#if T_ACTIVE
-char*
-quote( const void*  data, int  len )
-{
-    const char*  p   = data;
-    const char*  end = p + len;
-    int          count = 0;
-    int          phase = 0;
-    static char*  buff = NULL;
-
-    for (phase = 0; phase < 2; phase++) {
-        if (phase != 0) {
-            xfree(buff);
-            buff = xalloc(count+1);
-        }
-        count = 0;
-        for (p = data; p < end; p++) {
-            int  c = *p;
-
-            if (c == '\\') {
-                if (phase != 0) {
-                    buff[count] = buff[count+1] = '\\';
-                }
-                count += 2;
-                continue;
-            }
-
-            if (c >= 32 && c < 127) {
-                if (phase != 0)
-                    buff[count] = c;
-                count += 1;
-                continue;
-            }
-
-
-            if (c == '\t') {
-                if (phase != 0) {
-                    memcpy(buff+count, "<TAB>", 5);
-                }
-                count += 5;
-                continue;
-            }
-            if (c == '\n') {
-                if (phase != 0) {
-                    memcpy(buff+count, "<LN>", 4);
-                }
-                count += 4;
-                continue;
-            }
-            if (c == '\r') {
-                if (phase != 0) {
-                    memcpy(buff+count, "<CR>", 4);
-                }
-                count += 4;
-                continue;
-            }
-
-            if (phase != 0) {
-                buff[count+0] = '\\';
-                buff[count+1] = 'x';
-                buff[count+2] = "0123456789abcdef"[(c >> 4) & 15];
-                buff[count+3] = "0123456789abcdef"[     (c) & 15];
-            }
-            count += 4;
-        }
-    }
-    buff[count] = 0;
-    return buff;
-}
-#endif /* T_ACTIVE */
-
-/** PACKETS
- **
- ** We need a way to buffer data before it can be sent to the
- ** corresponding file descriptor. We use linked list of Packet
- ** objects to do this.
- **/
-
-typedef struct Packet   Packet;
-
-#define  MAX_PAYLOAD  4000
-
-struct Packet {
-    Packet*   next;
-    int       len;
-    int       channel;
-    uint8_t   data[ MAX_PAYLOAD ];
-};
-
-/* we expect to alloc/free a lot of packets during
- * operations so use a single linked list of free packets
- * to keep things speedy and simple.
- */
-static Packet*   _free_packets;
-
-/* Allocate a packet */
-static Packet*
-packet_alloc(void)
-{
-    Packet*  p = _free_packets;
-    if (p != NULL) {
-        _free_packets = p->next;
-    } else {
-        xnew(p);
-    }
-    p->next    = NULL;
-    p->len     = 0;
-    p->channel = -1;
-    return p;
-}
-
-/* Release a packet. This takes the address of a packet
- * pointer that will be set to NULL on exit (avoids
- * referencing dangling pointers in case of bugs)
- */
-static void
-packet_free( Packet*  *ppacket )
-{
-    Packet*  p = *ppacket;
-    if (p) {
-        p->next       = _free_packets;
-        _free_packets = p;
-        *ppacket = NULL;
-    }
-}
-
-/** PACKET RECEIVER
- **
- ** Simple abstraction for something that can receive a packet
- ** from a FDHandler (see below) or something else.
- **
- ** Send a packet to it with 'receiver_post'
- **
- ** Call 'receiver_close' to indicate that the corresponding
- ** packet source was closed.
- **/
-
-typedef void (*PostFunc) ( void*  user, Packet*  p );
-typedef void (*CloseFunc)( void*  user );
-
-typedef struct {
-    PostFunc   post;
-    CloseFunc  close;
-    void*      user;
-} Receiver;
-
-/* post a packet to a receiver. Note that this transfers
- * ownership of the packet to the receiver.
- */
-static __inline__ void
-receiver_post( Receiver*  r, Packet*  p )
-{
-    if (r->post)
-        r->post( r->user, p );
-    else
-        packet_free(&p);
-}
-
-/* tell a receiver the packet source was closed.
- * this will also prevent further posting to the
- * receiver.
- */
-static __inline__ void
-receiver_close( Receiver*  r )
-{
-    if (r->close) {
-        r->close( r->user );
-        r->close = NULL;
-    }
-    r->post  = NULL;
-}
-
-
-/** FD HANDLERS
- **
- ** these are smart listeners that send incoming packets to a receiver
- ** and can queue one or more outgoing packets and send them when
- ** possible to the FD.
- **
- ** note that we support clean shutdown of file descriptors,
- ** i.e. we try to send all outgoing packets before destroying
- ** the FDHandler.
- **/
-
-typedef struct FDHandler      FDHandler;
-typedef struct FDHandlerList  FDHandlerList;
-
-struct FDHandler {
-    int             fd;
-    FDHandlerList*  list;
-    char            closing;
-    Receiver        receiver[1];
-
-    /* queue of outgoing packets */
-    int             out_pos;
-    Packet*         out_first;
-    Packet**        out_ptail;
-
-    FDHandler*      next;
-    FDHandler**     pref;
-
-};
-
-struct FDHandlerList {
-    /* the looper that manages the fds */
-    Looper*      looper;
-
-    /* list of active FDHandler objects */
-    FDHandler*   active;
-
-    /* list of closing FDHandler objects.
-     * these are waiting to push their
-     * queued packets to the fd before
-     * freeing themselves.
-     */
-    FDHandler*   closing;
-
-};
-
-/* remove a FDHandler from its current list */
-static void
-fdhandler_remove( FDHandler*  f )
-{
-    f->pref[0] = f->next;
-    if (f->next)
-        f->next->pref = f->pref;
-}
-
-/* add a FDHandler to a given list */
-static void
-fdhandler_prepend( FDHandler*  f, FDHandler**  list )
-{
-    f->next = list[0];
-    f->pref = list;
-    list[0] = f;
-    if (f->next)
-        f->next->pref = &f->next;
-}
-
-/* initialize a FDHandler list */
-static void
-fdhandler_list_init( FDHandlerList*  list, Looper*  looper )
-{
-    list->looper  = looper;
-    list->active  = NULL;
-    list->closing = NULL;
-}
-
-
-/* close a FDHandler (and free it). Note that this will not
- * perform a graceful shutdown, i.e. all packets in the
- * outgoing queue will be immediately free.
- *
- * this *will* notify the receiver that the file descriptor
- * was closed.
- *
- * you should call fdhandler_shutdown() if you want to
- * notify the FDHandler that its packet source is closed.
- */
-static void
-fdhandler_close( FDHandler*  f )
-{
-    /* notify receiver */
-    receiver_close(f->receiver);
-
-    /* remove the handler from its list */
-    fdhandler_remove(f);
-
-    /* get rid of outgoing packet queue */
-    if (f->out_first != NULL) {
-        Packet*  p;
-        while ((p = f->out_first) != NULL) {
-            f->out_first = p->next;
-            packet_free(&p);
-        }
-    }
-
-    /* get rid of file descriptor */
-    if (f->fd >= 0) {
-        looper_del( f->list->looper, f->fd );
-        close(f->fd);
-        f->fd = -1;
-    }
-
-    f->list = NULL;
-    xfree(f);
-}
-
-/* Ask the FDHandler to cleanly shutdown the connection,
- * i.e. send any pending outgoing packets then auto-free
- * itself.
- */
-static void
-fdhandler_shutdown( FDHandler*  f )
-{
-    /* prevent later fdhandler_close() to
-     * call the receiver's close.
-     */
-    f->receiver->close = NULL;
-
-    if (f->out_first != NULL && !f->closing)
-    {
-        /* move the handler to the 'closing' list */
-        f->closing = 1;
-        fdhandler_remove(f);
-        fdhandler_prepend(f, &f->list->closing);
-        return;
-    }
-
-    fdhandler_close(f);
-}
-
-/* Enqueue a new packet that the FDHandler will
- * send through its file descriptor.
- */
-static void
-fdhandler_enqueue( FDHandler*  f, Packet*  p )
-{
-    Packet*  first = f->out_first;
-
-    p->next         = NULL;
-    f->out_ptail[0] = p;
-    f->out_ptail    = &p->next;
-
-    if (first == NULL) {
-        f->out_pos = 0;
-        looper_enable( f->list->looper, f->fd, EPOLLOUT );
-    }
-}
-
-
-/* FDHandler file descriptor event callback for read/write ops */
-static void
-fdhandler_event( FDHandler*  f, int  events )
-{
-   int  len;
-
-    /* in certain cases, it's possible to have both EPOLLIN and
-     * EPOLLHUP at the same time. This indicates that there is incoming
-     * data to read, but that the connection was nonetheless closed
-     * by the sender. Be sure to read the data before closing
-     * the receiver to avoid packet loss.
-     */
-
-    if (events & EPOLLIN) {
-        Packet*  p = packet_alloc();
-        int      len;
-
-        if ((len = fd_read(f->fd, p->data, MAX_PAYLOAD)) < 0) {
-            D("%s: can't recv: %s", __FUNCTION__, strerror(errno));
-            packet_free(&p);
-        } else if (len > 0) {
-            p->len     = len;
-            p->channel = -101;  /* special debug value, not used */
-            receiver_post( f->receiver, p );
-        }
-    }
-
-    if (events & (EPOLLHUP|EPOLLERR)) {
-        /* disconnection */
-        D("%s: disconnect on fd %d", __FUNCTION__, f->fd);
-        fdhandler_close(f);
-        return;
-    }
-
-    if (events & EPOLLOUT && f->out_first) {
-        Packet*  p = f->out_first;
-        int      avail, len;
-
-        avail = p->len - f->out_pos;
-        if ((len = fd_write(f->fd, p->data + f->out_pos, avail)) < 0) {
-            D("%s: can't send: %s", __FUNCTION__, strerror(errno));
-        } else {
-            f->out_pos += len;
-            if (f->out_pos >= p->len) {
-                f->out_pos   = 0;
-                f->out_first = p->next;
-                packet_free(&p);
-                if (f->out_first == NULL) {
-                    f->out_ptail = &f->out_first;
-                    looper_disable( f->list->looper, f->fd, EPOLLOUT );
-                }
-            }
-        }
-    }
-}
-
-
-/* Create a new FDHandler that monitors read/writes */
-static FDHandler*
-fdhandler_new( int             fd,
-               FDHandlerList*  list,
-               Receiver*       receiver )
-{
-    FDHandler*  f = xalloc0(sizeof(*f));
-
-    f->fd          = fd;
-    f->list        = list;
-    f->receiver[0] = receiver[0];
-    f->out_first   = NULL;
-    f->out_ptail   = &f->out_first;
-    f->out_pos     = 0;
-
-    fdhandler_prepend(f, &list->active);
-
-    looper_add( list->looper, fd, (EventFunc) fdhandler_event, f );
-    looper_enable( list->looper, fd, EPOLLIN );
-
-    return f;
-}
-
-
-/* event callback function to monitor accepts() on server sockets.
- * the convention used here is that the receiver will receive a
- * dummy packet with the new client socket in p->channel
- */
-static void
-fdhandler_accept_event( FDHandler*  f, int  events )
-{
-    if (events & EPOLLIN) {
-        /* this is an accept - send a dummy packet to the receiver */
-        Packet*  p = packet_alloc();
-
-        D("%s: accepting on fd %d", __FUNCTION__, f->fd);
-        p->data[0] = 1;
-        p->len     = 1;
-        p->channel = fd_accept(f->fd);
-        if (p->channel < 0) {
-            D("%s: accept failed ?: %s", __FUNCTION__, strerror(errno));
-            packet_free(&p);
-            return;
-        }
-        receiver_post( f->receiver, p );
-    }
-
-    if (events & (EPOLLHUP|EPOLLERR)) {
-        /* disconnecting !! */
-        D("%s: closing accept fd %d", __FUNCTION__, f->fd);
-        fdhandler_close(f);
-        return;
-    }
-}
-
-
-/* Create a new FDHandler used to monitor new connections on a
- * server socket. The receiver must expect the new connection
- * fd in the 'channel' field of a dummy packet.
- */
-static FDHandler*
-fdhandler_new_accept( int             fd,
-                      FDHandlerList*  list,
-                      Receiver*       receiver )
-{
-    FDHandler*  f = xalloc0(sizeof(*f));
-
-    f->fd          = fd;
-    f->list        = list;
-    f->receiver[0] = receiver[0];
-
-    fdhandler_prepend(f, &list->active);
-
-    looper_add( list->looper, fd, (EventFunc) fdhandler_accept_event, f );
-    looper_enable( list->looper, fd, EPOLLIN );
-    listen( fd, 5 );
-
-    return f;
-}
-
-/** SERIAL CONNECTION STATE
- **
- ** The following is used to handle the framing protocol
- ** used on the serial port connection.
- **/
-
-/* each packet is made of a 6 byte header followed by a payload
- * the header looks like:
- *
- *   offset   size    description
- *       0       2    a 2-byte hex string for the channel number
- *       4       4    a 4-char hex string for the size of the payload
- *       6       n    the payload itself
- */
-#define  HEADER_SIZE    6
-#define  CHANNEL_OFFSET 0
-#define  LENGTH_OFFSET  2
-#define  CHANNEL_SIZE   2
-#define  LENGTH_SIZE    4
-
-#define  CHANNEL_CONTROL  0
-
-/* The Serial object receives data from the serial port,
- * extracts the payload size and channel index, then sends
- * the resulting messages as a packet to a generic receiver.
- *
- * You can also use serial_send to send a packet through
- * the serial port.
- */
-typedef struct Serial {
-    FDHandler*  fdhandler;   /* used to monitor serial port fd */
-    Receiver    receiver[1]; /* send payload there */
-    int         in_len;      /* current bytes in input packet */
-    int         in_datalen;  /* payload size, or 0 when reading header */
-    int         in_channel;  /* extracted channel number */
-    Packet*     in_packet;   /* used to read incoming packets */
-} Serial;
-
-
-/* a callback called when the serial port's fd is closed */
-static void
-serial_fd_close( Serial*  s )
-{
-    fatal("unexpected serial port close !!");
-}
-
-static void
-serial_dump( Packet*  p, const char*  funcname )
-{
-    T("%s: %03d bytes: '%s'",
-      funcname, p->len, quote(p->data, p->len));
-}
-
-/* a callback called when a packet arrives from the serial port's FDHandler.
- *
- * This will essentially parse the header, extract the channel number and
- * the payload size and store them in 'in_datalen' and 'in_channel'.
- *
- * After that, the payload is sent to the receiver once completed.
- */
-static void
-serial_fd_receive( Serial*  s, Packet*  p )
-{
-    int      rpos  = 0, rcount = p->len;
-    Packet*  inp   = s->in_packet;
-    int      inpos = s->in_len;
-
-    serial_dump( p, __FUNCTION__ );
-
-    while (rpos < rcount)
-    {
-        int  avail = rcount - rpos;
-
-        /* first, try to read the header */
-        if (s->in_datalen == 0) {
-            int  wanted = HEADER_SIZE - inpos;
-            if (avail > wanted)
-                avail = wanted;
-
-            memcpy( inp->data + inpos, p->data + rpos, avail );
-            inpos += avail;
-            rpos  += avail;
-
-            if (inpos == HEADER_SIZE) {
-                s->in_datalen = hex2int( inp->data + LENGTH_OFFSET,  LENGTH_SIZE );
-                s->in_channel = hex2int( inp->data + CHANNEL_OFFSET, CHANNEL_SIZE );
-
-                if (s->in_datalen <= 0) {
-                    D("ignoring %s packet from serial port",
-                      s->in_datalen ? "empty" : "malformed");
-                    s->in_datalen = 0;
-                }
-
-                //D("received %d bytes packet for channel %d", s->in_datalen, s->in_channel);
-                inpos = 0;
-            }
-        }
-        else /* then, populate the packet itself */
-        {
-            int   wanted = s->in_datalen - inpos;
-
-            if (avail > wanted)
-                avail = wanted;
-
-            memcpy( inp->data + inpos, p->data + rpos, avail );
-            inpos += avail;
-            rpos  += avail;
-
-            if (inpos == s->in_datalen) {
-                if (s->in_channel < 0) {
-                    D("ignoring %d bytes addressed to channel %d",
-                       inpos, s->in_channel);
-                } else {
-                    inp->len     = inpos;
-                    inp->channel = s->in_channel;
-                    receiver_post( s->receiver, inp );
-                    s->in_packet  = inp = packet_alloc();
-                }
-                s->in_datalen = 0;
-                inpos         = 0;
-            }
-        }
-    }
-    s->in_len = inpos;
-    packet_free(&p);
-}
-
-
-/* send a packet to the serial port.
- * this assumes that p->len and p->channel contain the payload's
- * size and channel and will add the appropriate header.
- */
-static void
-serial_send( Serial*  s, Packet*  p )
-{
-    Packet*  h = packet_alloc();
-
-    //D("sending to serial %d bytes from channel %d: '%.*s'", p->len, p->channel, p->len, p->data);
-
-    /* insert a small header before this packet */
-    h->len = HEADER_SIZE;
-    int2hex( p->len,     h->data + LENGTH_OFFSET,  LENGTH_SIZE );
-    int2hex( p->channel, h->data + CHANNEL_OFFSET, CHANNEL_SIZE );
-
-    serial_dump( h, __FUNCTION__ );
-    serial_dump( p, __FUNCTION__ );
-
-    fdhandler_enqueue( s->fdhandler, h );
-    fdhandler_enqueue( s->fdhandler, p );
-}
-
-
-/* initialize serial reader */
-static void
-serial_init( Serial*         s,
-             int             fd,
-             FDHandlerList*  list,
-             Receiver*       receiver )
-{
-    Receiver  recv;
-
-    recv.user  = s;
-    recv.post  = (PostFunc)  serial_fd_receive;
-    recv.close = (CloseFunc) serial_fd_close;
-
-    s->receiver[0] = receiver[0];
-
-    s->fdhandler = fdhandler_new( fd, list, &recv );
-    s->in_len     = 0;
-    s->in_datalen = 0;
-    s->in_channel = 0;
-    s->in_packet  = packet_alloc();
-}
-
-
-/** CLIENTS
- **/
-
-typedef struct Client       Client;
-typedef struct Multiplexer  Multiplexer;
-
-/* A Client object models a single qemud client socket
- * connection in the emulated system.
- *
- * the client first sends the name of the system service
- * it wants to contact (no framing), then waits for a 2
- * byte answer from qemud.
- *
- * the answer is either "OK" or "KO" to indicate
- * success or failure.
- *
- * In case of success, the client can send messages
- * to the service.
- *
- * In case of failure, it can disconnect or try sending
- * the name of another service.
- */
-struct Client {
-    Client*       next;
-    Client**      pref;
-    int           channel;
-    char          registered;
-    FDHandler*    fdhandler;
-    Multiplexer*  multiplexer;
-};
-
-struct Multiplexer {
-    Client*        clients;
-    int            last_channel;
-    Serial         serial[1];
-    Looper         looper[1];
-    FDHandlerList  fdhandlers[1];
-};
-
-
-static int   multiplexer_open_channel( Multiplexer*  mult, Packet*  p );
-static void  multiplexer_close_channel( Multiplexer*  mult, int  channel );
-static void  multiplexer_serial_send( Multiplexer* mult, int  channel, Packet*  p );
-
-static void
-client_dump( Client*  c, Packet*  p, const char*  funcname )
-{
-    T("%s: client %p (%d): %3d bytes: '%s'",
-      funcname, c, c->fdhandler->fd,
-      p->len, quote(p->data, p->len));
-}
-
-/* destroy a client */
-static void
-client_free( Client*  c )
-{
-    /* remove from list */
-    c->pref[0] = c->next;
-    if (c->next)
-        c->next->pref = c->pref;
-
-    c->channel    = -1;
-    c->registered = 0;
-
-    /* gently ask the FDHandler to shutdown to
-     * avoid losing queued outgoing packets */
-    if (c->fdhandler != NULL) {
-        fdhandler_shutdown(c->fdhandler);
-        c->fdhandler = NULL;
-    }
-
-    xfree(c);
-}
-
-
-/* a function called when a client socket receives data */
-static void
-client_fd_receive( Client*  c, Packet*  p )
-{
-    client_dump(c, p, __FUNCTION__);
-
-    if (c->registered) {
-        /* the client is registered, just send the
-         * data through the serial port
-         */
-        multiplexer_serial_send(c->multiplexer, c->channel, p);
-        return;
-    }
-
-    if (c->channel > 0) {
-        /* the client is waiting registration results.
-         * this should not happen because the client
-         * should wait for our 'ok' or 'ko'.
-         * close the connection.
-         */
-         D("%s: bad client sending data before end of registration",
-           __FUNCTION__);
-     BAD_CLIENT:
-         packet_free(&p);
-         client_free(c);
-         return;
-    }
-
-    /* the client hasn't registered a service yet,
-     * so this must be the name of a service, call
-     * the multiplexer to start registration for
-     * it.
-     */
-    D("%s: attempting registration for service '%.*s'",
-      __FUNCTION__, p->len, p->data);
-    c->channel = multiplexer_open_channel(c->multiplexer, p);
-    if (c->channel < 0) {
-        D("%s: service name too long", __FUNCTION__);
-        goto BAD_CLIENT;
-    }
-    D("%s:    -> received channel id %d", __FUNCTION__, c->channel);
-    packet_free(&p);
-}
-
-
-/* a function called when the client socket is closed. */
-static void
-client_fd_close( Client*  c )
-{
-    T("%s: client %p (%d)", __FUNCTION__, c, c->fdhandler->fd);
-
-    /* no need to shutdown the FDHandler */
-    c->fdhandler = NULL;
-
-    /* tell the emulator we're out */
-    if (c->channel > 0)
-        multiplexer_close_channel(c->multiplexer, c->channel);
-
-    /* free the client */
-    client_free(c);
-}
-
-/* a function called when the multiplexer received a registration
- * response from the emulator for a given client.
- */
-static void
-client_registration( Client*  c, int  registered )
-{
-    Packet*  p = packet_alloc();
-
-    /* sends registration status to client */
-    if (!registered) {
-        D("%s: registration failed for client %d", __FUNCTION__, c->channel);
-        memcpy( p->data, "KO", 2 );
-        p->len = 2;
-    } else {
-        D("%s: registration succeeded for client %d", __FUNCTION__, c->channel);
-        memcpy( p->data, "OK", 2 );
-        p->len = 2;
-    }
-    client_dump(c, p, __FUNCTION__);
-    fdhandler_enqueue(c->fdhandler, p);
-
-    /* now save registration state
-     */
-    c->registered = registered;
-    if (!registered) {
-        /* allow the client to try registering another service */
-        c->channel = -1;
-    }
-}
-
-/* send data to a client */
-static void
-client_send( Client*  c, Packet*  p )
-{
-    client_dump(c, p, __FUNCTION__);
-    fdhandler_enqueue(c->fdhandler, p);
-}
-
-
-/* Create new client socket handler */
-static Client*
-client_new( Multiplexer*    mult,
-            int             fd,
-            FDHandlerList*  pfdhandlers,
-            Client**        pclients )
-{
-    Client*   c;
-    Receiver  recv;
-
-    xnew(c);
-
-    c->multiplexer = mult;
-    c->next        = NULL;
-    c->pref        = &c->next;
-    c->channel     = -1;
-    c->registered  = 0;
-
-    recv.user  = c;
-    recv.post  = (PostFunc)  client_fd_receive;
-    recv.close = (CloseFunc) client_fd_close;
-
-    c->fdhandler = fdhandler_new( fd, pfdhandlers, &recv );
-
-    /* add to client list */
-    c->next   = *pclients;
-    c->pref   = pclients;
-    *pclients = c;
-    if (c->next)
-        c->next->pref = &c->next;
-
-    return c;
-}
-
-/**  GLOBAL MULTIPLEXER
- **/
-
-/* find a client by its channel */
-static Client*
-multiplexer_find_client( Multiplexer*  mult, int  channel )
-{
-    Client* c = mult->clients;
-
-    for ( ; c != NULL; c = c->next ) {
-        if (c->channel == channel)
-            return c;
-    }
-    return NULL;
-}
-
-/* handle control messages coming from the serial port
- * on CONTROL_CHANNEL.
- */
-static void
-multiplexer_handle_control( Multiplexer*  mult, Packet*  p )
-{
-    /* connection registration success */
-    if (p->len == 13 && !memcmp(p->data, "ok:connect:", 11)) {
-        int      channel = hex2int(p->data+11, 2);
-        Client*  client  = multiplexer_find_client(mult, channel);
-
-        /* note that 'client' can be NULL if the corresponding
-         * socket was closed before the emulator response arrived.
-         */
-        if (client != NULL) {
-            client_registration(client, 1);
-        } else {
-            D("%s: NULL client: '%.*s'", __FUNCTION__, p->len, p->data+11);
-        }
-        goto EXIT;
-    }
-
-    /* connection registration failure */
-    if (p->len == 13 && !memcmp(p->data, "ko:connect:",11)) {
-        int     channel = hex2int(p->data+11, 2);
-        Client* client  = multiplexer_find_client(mult, channel);
-
-        if (client != NULL)
-            client_registration(client, 0);
-
-        goto EXIT;
-    }
-
-    /* emulator-induced client disconnection */
-    if (p->len == 13 && !memcmp(p->data, "disconnect:",11)) {
-        int      channel = hex2int(p->data+11, 2);
-        Client*  client  = multiplexer_find_client(mult, channel);
-
-        if (client != NULL)
-            client_free(client);
-
-        goto EXIT;
-    }
-
-    /* A message that begins with "X00" is a probe sent by
-     * the emulator used to detect which version of qemud it runs
-     * against (in order to detect 1.0/1.1 system images. Just
-     * silently ignore it there instead of printing an error
-     * message.
-     */
-    if (p->len >= 3 && !memcmp(p->data,"X00",3)) {
-        goto EXIT;
-    }
-
-    D("%s: unknown control message (%d bytes): '%.*s'",
-      __FUNCTION__, p->len, p->len, p->data);
-
-EXIT:
-    packet_free(&p);
-}
-
-/* a function called when an incoming packet comes from the serial port */
-static void
-multiplexer_serial_receive( Multiplexer*  mult, Packet*  p )
-{
-    Client*  client;
-
-    T("%s: channel=%d '%.*s'", __FUNCTION__, p->channel, p->len, p->data);
-
-    if (p->channel == CHANNEL_CONTROL) {
-        multiplexer_handle_control(mult, p);
-        return;
-    }
-
-    client = multiplexer_find_client(mult, p->channel);
-    if (client != NULL) {
-        client_send(client, p);
-        return;
-    }
-
-    D("%s: discarding packet for unknown channel %d", __FUNCTION__, p->channel);
-    packet_free(&p);
-}
-
-/* a function called when the serial reader closes */
-static void
-multiplexer_serial_close( Multiplexer*  mult )
-{
-    fatal("unexpected close of serial reader");
-}
-
-/* a function called to send a packet to the serial port */
-static void
-multiplexer_serial_send( Multiplexer*  mult, int  channel, Packet*  p )
-{
-    p->channel = channel;
-    serial_send( mult->serial, p );
-}
-
-
-
-/* a function used by a client to allocate a new channel id and
- * ask the emulator to open it. 'service' must be a packet containing
- * the name of the service in its payload.
- *
- * returns -1 if the service name is too long.
- *
- * notice that client_registration() will be called later when
- * the answer arrives.
- */
-static int
-multiplexer_open_channel( Multiplexer*  mult, Packet*  service )
-{
-    Packet*   p = packet_alloc();
-    int       len, channel;
-
-    /* find a free channel number, assume we don't have many
-     * clients here. */
-    {
-        Client*  c;
-    TRY_AGAIN:
-        channel = (++mult->last_channel) & 0xff;
-
-        for (c = mult->clients; c != NULL; c = c->next)
-            if (c->channel == channel)
-                goto TRY_AGAIN;
-    }
-
-    len = snprintf((char*)p->data, sizeof p->data, "connect:%.*s:%02x", service->len, service->data, channel);
-    if (len >= (int)sizeof(p->data)) {
-        D("%s: weird, service name too long (%d > %d)", __FUNCTION__, len, sizeof(p->data));
-        packet_free(&p);
-        return -1;
-    }
-    p->channel = CHANNEL_CONTROL;
-    p->len     = len;
-
-    serial_send(mult->serial, p);
-    return channel;
-}
-
-/* used to tell the emulator a channel was closed by a client */
-static void
-multiplexer_close_channel( Multiplexer*  mult, int  channel )
-{
-    Packet*  p   = packet_alloc();
-    int      len = snprintf((char*)p->data, sizeof(p->data), "disconnect:%02x", channel);
-
-    if (len > (int)sizeof(p->data)) {
-        /* should not happen */
-        return;
-    }
-
-    p->channel = CHANNEL_CONTROL;
-    p->len     = len;
-
-    serial_send(mult->serial, p);
-}
-
-/* this function is used when a new connection happens on the control
- * socket.
- */
-static void
-multiplexer_control_accept( Multiplexer*  m, Packet*  p )
-{
-    /* the file descriptor for the new socket connection is
-     * in p->channel. See fdhandler_accept_event() */
-    int      fd     = p->channel;
-    Client*  client = client_new( m, fd, m->fdhandlers, &m->clients );
-
-    D("created client %p listening on fd %d", client, fd);
-
-    /* free dummy packet */
-    packet_free(&p);
-}
-
-static void
-multiplexer_control_close( Multiplexer*  m )
-{
-    fatal("unexpected multiplexer control close");
-}
-
-static void
-multiplexer_init( Multiplexer*  m, const char*  serial_dev )
-{
-    int       fd, control_fd;
-    Receiver  recv;
-
-    /* initialize looper and fdhandlers list */
-    looper_init( m->looper );
-    fdhandler_list_init( m->fdhandlers, m->looper );
-
-    /* open the serial port */
-    do {
-        fd = open(serial_dev, O_RDWR);
-    } while (fd < 0 && errno == EINTR);
-
-    if (fd < 0) {
-        fatal( "%s: could not open '%s': %s", __FUNCTION__, serial_dev,
-               strerror(errno) );
-    }
-    // disable echo on serial lines
-    if ( !memcmp( serial_dev, "/dev/ttyS", 9 ) ) {
-        struct termios  ios;
-        tcgetattr( fd, &ios );
-        ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
-        tcsetattr( fd, TCSANOW, &ios );
-    }
-
-    /* initialize the serial reader/writer */
-    recv.user  = m;
-    recv.post  = (PostFunc)  multiplexer_serial_receive;
-    recv.close = (CloseFunc) multiplexer_serial_close;
-
-    serial_init( m->serial, fd, m->fdhandlers, &recv );
-
-    /* open the qemud control socket */
-    recv.user  = m;
-    recv.post  = (PostFunc)  multiplexer_control_accept;
-    recv.close = (CloseFunc) multiplexer_control_close;
-
-    fd = android_get_control_socket(CONTROL_SOCKET_NAME);
-    if (fd < 0) {
-        fatal("couldn't get fd for control socket '%s'", CONTROL_SOCKET_NAME);
-    }
-
-    fdhandler_new_accept( fd, m->fdhandlers, &recv );
-
-    /* initialize clients list */
-    m->clients = NULL;
-}
-
-/** MAIN LOOP
- **/
-
-static Multiplexer  _multiplexer[1];
-
-int  main( void )
-{
-    Multiplexer*  m = _multiplexer;
-
-   /* extract the name of our serial device from the kernel
-    * boot options that are stored in /proc/cmdline
-    */
-#define  KERNEL_OPTION  "android.qemud="
-
-    {
-        char          buff[1024];
-        int           fd, len;
-        char*         p;
-        char*         q;
-
-        fd = open( "/proc/cmdline", O_RDONLY );
-        if (fd < 0) {
-            D("%s: can't open /proc/cmdline !!: %s", __FUNCTION__,
-            strerror(errno));
-            exit(1);
-        }
-
-        len = fd_read( fd, buff, sizeof(buff)-1 );
-        close(fd);
-        if (len < 0) {
-            D("%s: can't read /proc/cmdline: %s", __FUNCTION__,
-            strerror(errno));
-            exit(1);
-        }
-        buff[len] = 0;
-
-        p = strstr( buff, KERNEL_OPTION );
-        if (p == NULL) {
-            D("%s: can't find '%s' in /proc/cmdline",
-            __FUNCTION__, KERNEL_OPTION );
-            exit(1);
-        }
-
-        p += sizeof(KERNEL_OPTION)-1;  /* skip option */
-        q  = p;
-        while ( *q && *q != ' ' && *q != '\t' )
-            q += 1;
-
-        snprintf( buff, sizeof(buff), "/dev/%.*s", q-p, p );
-
-        multiplexer_init( m, buff );
-    }
-
-    D( "entering main loop");
-    looper_loop( m->looper );
-    D( "unexpected termination !!" );
-    return 0;
-}
diff --git a/emulator/sensors/Android.mk b/emulator/sensors/Android.mk
deleted file mode 100644
index 9b0e83d..0000000
--- a/emulator/sensors/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# We're moving the emulator-specific platform libs to
-# development.git/tools/emulator/. The following test is to ensure
-# smooth builds even if the tree contains both versions.
-#
-ifndef BUILD_EMULATOR_SENSORS_MODULE
-BUILD_EMULATOR_SENSORS_MODULE := true
-
-LOCAL_PATH := $(call my-dir)
-
-ifneq ($(TARGET_PRODUCT),sim)
-# HAL module implemenation, not prelinked and stored in
-# hw/<SENSORS_HARDWARE_MODULE_ID>.<ro.hardware>.so
-include $(CLEAR_VARS)
-LOCAL_PRELINK_MODULE := false
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_SRC_FILES := sensors_qemu.c
-LOCAL_MODULE := sensors.goldfish
-LOCAL_MODULE_TAGS := debug
-include $(BUILD_SHARED_LIBRARY)
-endif
-
-endif # BUILD_EMULATOR_SENSORS_MODULE
diff --git a/emulator/sensors/sensors_qemu.c b/emulator/sensors/sensors_qemu.c
deleted file mode 100644
index 978eaeb..0000000
--- a/emulator/sensors/sensors_qemu.c
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* this implements a sensors hardware library for the Android emulator.
- * the following code should be built as a shared library that will be
- * placed into /system/lib/hw/sensors.goldfish.so
- *
- * it will be loaded by the code in hardware/libhardware/hardware.c
- * which is itself called from com_android_server_SensorService.cpp
- */
-
-
-/* we connect with the emulator through the "sensors" qemud service
- */
-#define  SENSORS_SERVICE_NAME "sensors"
-
-#define LOG_TAG "QemuSensors"
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <cutils/log.h>
-#include <cutils/native_handle.h>
-#include <cutils/sockets.h>
-#include <hardware/sensors.h>
-
-#if 0
-#define  D(...)  ALOGD(__VA_ARGS__)
-#else
-#define  D(...)  ((void)0)
-#endif
-
-#define  E(...)  ALOGE(__VA_ARGS__)
-
-#include <hardware/qemud.h>
-
-/** SENSOR IDS AND NAMES
- **/
-
-#define MAX_NUM_SENSORS 5
-
-#define SUPPORTED_SENSORS  ((1<<MAX_NUM_SENSORS)-1)
-
-#define  ID_BASE           SENSORS_HANDLE_BASE
-#define  ID_ACCELERATION   (ID_BASE+0)
-#define  ID_MAGNETIC_FIELD (ID_BASE+1)
-#define  ID_ORIENTATION    (ID_BASE+2)
-#define  ID_TEMPERATURE    (ID_BASE+3)
-#define  ID_PROXIMITY      (ID_BASE+4)
-
-#define  SENSORS_ACCELERATION   (1 << ID_ACCELERATION)
-#define  SENSORS_MAGNETIC_FIELD  (1 << ID_MAGNETIC_FIELD)
-#define  SENSORS_ORIENTATION     (1 << ID_ORIENTATION)
-#define  SENSORS_TEMPERATURE     (1 << ID_TEMPERATURE)
-#define  SENSORS_PROXIMITY       (1 << ID_PROXIMITY)
-
-#define  ID_CHECK(x)  ((unsigned)((x)-ID_BASE) < MAX_NUM_SENSORS)
-
-#define  SENSORS_LIST  \
-    SENSOR_(ACCELERATION,"acceleration") \
-    SENSOR_(MAGNETIC_FIELD,"magnetic-field") \
-    SENSOR_(ORIENTATION,"orientation") \
-    SENSOR_(TEMPERATURE,"temperature") \
-    SENSOR_(PROXIMITY,"proximity") \
-
-static const struct {
-    const char*  name;
-    int          id; } _sensorIds[MAX_NUM_SENSORS] =
-{
-#define SENSOR_(x,y)  { y, ID_##x },
-    SENSORS_LIST
-#undef  SENSOR_
-};
-
-static const char*
-_sensorIdToName( int  id )
-{
-    int  nn;
-    for (nn = 0; nn < MAX_NUM_SENSORS; nn++)
-        if (id == _sensorIds[nn].id)
-            return _sensorIds[nn].name;
-    return "<UNKNOWN>";
-}
-
-static int
-_sensorIdFromName( const char*  name )
-{
-    int  nn;
-
-    if (name == NULL)
-        return -1;
-
-    for (nn = 0; nn < MAX_NUM_SENSORS; nn++)
-        if (!strcmp(name, _sensorIds[nn].name))
-            return _sensorIds[nn].id;
-
-    return -1;
-}
-
-/** SENSORS POLL DEVICE
- **
- ** This one is used to read sensor data from the hardware.
- ** We implement this by simply reading the data from the
- ** emulator through the QEMUD channel.
- **/
-
-typedef struct SensorPoll {
-    struct sensors_poll_device_t  device;
-    sensors_event_t               sensors[MAX_NUM_SENSORS];
-    int                           events_fd;
-    uint32_t                      pendingSensors;
-    int64_t                       timeStart;
-    int64_t                       timeOffset;
-    int                           fd;
-    uint32_t                      active_sensors;
-} SensorPoll;
-
-/* this must return a file descriptor that will be used to read
- * the sensors data (it is passed to data__data_open() below
- */
-static native_handle_t*
-control__open_data_source(struct sensors_poll_device_t *dev)
-{
-    SensorPoll*  ctl = (void*)dev;
-    native_handle_t* handle;
-
-    if (ctl->fd < 0) {
-        ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
-    }
-    D("%s: fd=%d", __FUNCTION__, ctl->fd);
-    handle = native_handle_create(1, 0);
-    handle->data[0] = dup(ctl->fd);
-    return handle;
-}
-
-static int
-control__activate(struct sensors_poll_device_t *dev,
-                  int handle,
-                  int enabled)
-{
-    SensorPoll*     ctl = (void*)dev;
-    uint32_t        mask, sensors, active, new_sensors, changed;
-    char            command[128];
-    int             ret;
-
-    D("%s: handle=%s (%d) fd=%d enabled=%d", __FUNCTION__,
-        _sensorIdToName(handle), handle, ctl->fd, enabled);
-
-    if (!ID_CHECK(handle)) {
-        E("%s: bad handle ID", __FUNCTION__);
-        return -1;
-    }
-
-    mask    = (1<<handle);
-    sensors = enabled ? mask : 0;
-
-    active      = ctl->active_sensors;
-    new_sensors = (active & ~mask) | (sensors & mask);
-    changed     = active ^ new_sensors;
-
-    if (!changed)
-        return 0;
-
-    snprintf(command, sizeof command, "set:%s:%d",
-                _sensorIdToName(handle), enabled != 0);
-
-    if (ctl->fd < 0) {
-        ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
-    }
-
-    ret = qemud_channel_send(ctl->fd, command, -1);
-    if (ret < 0) {
-        E("%s: when sending command errno=%d: %s", __FUNCTION__, errno, strerror(errno));
-        return -1;
-    }
-    ctl->active_sensors = new_sensors;
-
-    return 0;
-}
-
-static int
-control__set_delay(struct sensors_poll_device_t *dev, int32_t ms)
-{
-    SensorPoll*     ctl = (void*)dev;
-    char            command[128];
-
-    D("%s: dev=%p delay-ms=%d", __FUNCTION__, dev, ms);
-
-    snprintf(command, sizeof command, "set-delay:%d", ms);
-
-    return qemud_channel_send(ctl->fd, command, -1);
-}
-
-static int
-control__close(struct hw_device_t *dev) 
-{
-    SensorPoll*  ctl = (void*)dev;
-    close(ctl->fd);
-    free(ctl);
-    return 0;
-}
-
-/* return the current time in nanoseconds */
-static int64_t
-data__now_ns(void)
-{
-    struct timespec  ts;
-
-    clock_gettime(CLOCK_MONOTONIC, &ts);
-
-    return (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec;
-}
-
-static int
-data__data_open(struct sensors_poll_device_t *dev, native_handle_t* handle)
-{
-    SensorPoll*  data = (void*)dev;
-    int i;
-    D("%s: dev=%p fd=%d", __FUNCTION__, dev, handle->data[0]);
-    memset(&data->sensors, 0, sizeof(data->sensors));
-
-    for (i=0 ; i<MAX_NUM_SENSORS ; i++) {
-        data->sensors[i].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
-    }
-    data->pendingSensors = 0;
-    data->timeStart      = 0;
-    data->timeOffset     = 0;
-
-    data->events_fd = dup(handle->data[0]);
-    D("%s: dev=%p fd=%d (was %d)", __FUNCTION__, dev, data->events_fd, handle->data[0]);
-    native_handle_close(handle);
-    native_handle_delete(handle);
-    return 0;
-}
-
-static int
-data__data_close(struct sensors_poll_device_t *dev)
-{
-    SensorPoll*  data = (void*)dev;
-    D("%s: dev=%p", __FUNCTION__, dev);
-    if (data->events_fd >= 0) {
-        close(data->events_fd);
-        data->events_fd = -1;
-    }
-    return 0;
-}
-
-static int
-pick_sensor(SensorPoll*       data,
-            sensors_event_t*  values)
-{
-    uint32_t mask = SUPPORTED_SENSORS;
-    while (mask) {
-        uint32_t i = 31 - __builtin_clz(mask);
-        mask &= ~(1<<i);
-        if (data->pendingSensors & (1<<i)) {
-            data->pendingSensors &= ~(1<<i);
-            *values = data->sensors[i];
-            values->sensor = i;
-            values->version = sizeof(*values);
-
-            D("%s: %d [%f, %f, %f]", __FUNCTION__,
-                    i,
-                    values->data[0],
-                    values->data[1],
-                    values->data[2]);
-            return i;
-        }
-    }
-    ALOGE("No sensor to return!!! pendingSensors=%08x", data->pendingSensors);
-    // we may end-up in a busy loop, slow things down, just in case.
-    usleep(100000);
-    return -EINVAL;
-}
-
-static int
-data__poll(struct sensors_poll_device_t *dev, sensors_event_t* values)
-{
-    SensorPoll*  data = (void*)dev;
-    int fd = data->events_fd;
-
-    D("%s: data=%p", __FUNCTION__, dev);
-
-    // there are pending sensors, returns them now...
-    if (data->pendingSensors) {
-        return pick_sensor(data, values);
-    }
-
-    // wait until we get a complete event for an enabled sensor
-    uint32_t new_sensors = 0;
-
-    while (1) {
-        /* read the next event */
-        char     buff[256];
-        int      len = qemud_channel_recv(data->events_fd, buff, sizeof buff-1);
-        float    params[3];
-        int64_t  event_time;
-
-        if (len < 0) {
-            E("%s: len=%d, errno=%d: %s", __FUNCTION__, len, errno, strerror(errno));
-            return -errno;
-        }
-
-        buff[len] = 0;
-
-        /* "wake" is sent from the emulator to exit this loop. */
-        if (!strcmp((const char*)data, "wake")) {
-            return 0x7FFFFFFF;
-        }
-
-        /* "acceleration:<x>:<y>:<z>" corresponds to an acceleration event */
-        if (sscanf(buff, "acceleration:%g:%g:%g", params+0, params+1, params+2) == 3) {
-            new_sensors |= SENSORS_ACCELERATION;
-            data->sensors[ID_ACCELERATION].acceleration.x = params[0];
-            data->sensors[ID_ACCELERATION].acceleration.y = params[1];
-            data->sensors[ID_ACCELERATION].acceleration.z = params[2];
-            continue;
-        }
-
-        /* "orientation:<azimuth>:<pitch>:<roll>" is sent when orientation changes */
-        if (sscanf(buff, "orientation:%g:%g:%g", params+0, params+1, params+2) == 3) {
-            new_sensors |= SENSORS_ORIENTATION;
-            data->sensors[ID_ORIENTATION].orientation.azimuth = params[0];
-            data->sensors[ID_ORIENTATION].orientation.pitch   = params[1];
-            data->sensors[ID_ORIENTATION].orientation.roll    = params[2];
-            continue;
-        }
-
-        /* "magnetic-field:<x>:<y>:<z>" is sent for the params of the magnetic field */
-        if (sscanf(buff, "magnetic-field:%g:%g:%g", params+0, params+1, params+2) == 3) {
-            new_sensors |= SENSORS_MAGNETIC_FIELD;
-            data->sensors[ID_MAGNETIC_FIELD].magnetic.x = params[0];
-            data->sensors[ID_MAGNETIC_FIELD].magnetic.y = params[1];
-            data->sensors[ID_MAGNETIC_FIELD].magnetic.z = params[2];
-            continue;
-        }
-
-        /* "temperature:<celsius>" */
-        if (sscanf(buff, "temperature:%g", params+0) == 2) {
-            new_sensors |= SENSORS_TEMPERATURE;
-            data->sensors[ID_TEMPERATURE].temperature = params[0];
-            continue;
-        }
-
-        /* "proximity:<value>" */
-        if (sscanf(buff, "proximity:%g", params+0) == 1) {
-            new_sensors |= SENSORS_PROXIMITY;
-            data->sensors[ID_PROXIMITY].distance = params[0];
-            continue;
-        }
-
-        /* "sync:<time>" is sent after a series of sensor events.
-         * where 'time' is expressed in micro-seconds and corresponds
-         * to the VM time when the real poll occured.
-         */
-        if (sscanf(buff, "sync:%lld", &event_time) == 1) {
-            if (new_sensors) {
-                data->pendingSensors = new_sensors;
-                int64_t t = event_time * 1000LL;  /* convert to nano-seconds */
-
-                /* use the time at the first sync: as the base for later
-                 * time values */
-                if (data->timeStart == 0) {
-                    data->timeStart  = data__now_ns();
-                    data->timeOffset = data->timeStart - t;
-                }
-                t += data->timeOffset;
-
-                while (new_sensors) {
-                    uint32_t i = 31 - __builtin_clz(new_sensors);
-                    new_sensors &= ~(1<<i);
-                    data->sensors[i].timestamp = t;
-                }
-                return pick_sensor(data, values);
-            } else {
-                D("huh ? sync without any sensor data ?");
-            }
-            continue;
-        }
-        D("huh ? unsupported command");
-    }
-    return -1;
-}
-
-static int
-data__close(struct hw_device_t *dev) 
-{
-    SensorPoll* data = (SensorPoll*)dev;
-    if (data) {
-        if (data->events_fd >= 0) {
-            //ALOGD("(device close) about to close fd=%d", data->events_fd);
-            close(data->events_fd);
-        }
-        free(data);
-    }
-    return 0;
-}
-
-/** SENSORS POLL DEVICE FUNCTIONS **/
-
-static int poll__close(struct hw_device_t* dev)
-{
-    SensorPoll*  ctl = (void*)dev;
-    close(ctl->fd);
-    if (ctl->fd >= 0) {
-        close(ctl->fd);
-    }
-    if (ctl->events_fd >= 0) {
-        close(ctl->events_fd);
-    }
-    free(ctl);
-    return 0;
-}
-
-static int poll__poll(struct sensors_poll_device_t *dev,
-            sensors_event_t* data, int count)
-{
-    SensorPoll*  datadev = (void*)dev;
-    int ret;
-    int i;
-    D("%s: dev=%p data=%p count=%d ", __FUNCTION__, dev, data, count);
-
-    for (i = 0; i < count; i++)  {
-        ret = data__poll(dev, data);
-        data++;
-        if (ret > MAX_NUM_SENSORS || ret < 0) {
-           return i;
-        }
-        if (!datadev->pendingSensors) {
-           return i + 1;
-        }
-    }
-    return count;
-}
-
-static int poll__activate(struct sensors_poll_device_t *dev,
-            int handle, int enabled)
-{
-    int ret;
-    native_handle_t* hdl;
-    SensorPoll*  ctl = (void*)dev;
-    D("%s: dev=%p handle=%x enable=%d ", __FUNCTION__, dev, handle, enabled);
-    if (ctl->fd < 0) {
-        D("%s: OPEN CTRL and DATA ", __FUNCTION__);
-        hdl = control__open_data_source(dev);
-        ret = data__data_open(dev,hdl);
-    }
-    ret = control__activate(dev, handle, enabled);
-    return ret;
-}
-
-static int poll__setDelay(struct sensors_poll_device_t *dev,
-            int handle, int64_t ns)
-{
-    // TODO
-    return 0;
-}
-
-/** MODULE REGISTRATION SUPPORT
- **
- ** This is required so that hardware/libhardware/hardware.c
- ** will dlopen() this library appropriately.
- **/
-
-/*
- * the following is the list of all supported sensors.
- * this table is used to build sSensorList declared below
- * according to which hardware sensors are reported as
- * available from the emulator (see get_sensors_list below)
- *
- * note: numerical values for maxRange/resolution/power were
- *       taken from the reference AK8976A implementation
- */
-static const struct sensor_t sSensorListInit[] = {
-        { .name       = "Goldfish 3-axis Accelerometer",
-          .vendor     = "The Android Open Source Project",
-          .version    = 1,
-          .handle     = ID_ACCELERATION,
-          .type       = SENSOR_TYPE_ACCELEROMETER,
-          .maxRange   = 2.8f,
-          .resolution = 1.0f/4032.0f,
-          .power      = 3.0f,
-          .reserved   = {}
-        },
-
-        { .name       = "Goldfish 3-axis Magnetic field sensor",
-          .vendor     = "The Android Open Source Project",
-          .version    = 1,
-          .handle     = ID_MAGNETIC_FIELD,
-          .type       = SENSOR_TYPE_MAGNETIC_FIELD,
-          .maxRange   = 2000.0f,
-          .resolution = 1.0f,
-          .power      = 6.7f,
-          .reserved   = {}
-        },
-
-        { .name       = "Goldfish Orientation sensor",
-          .vendor     = "The Android Open Source Project",
-          .version    = 1,
-          .handle     = ID_ORIENTATION,
-          .type       = SENSOR_TYPE_ORIENTATION,
-          .maxRange   = 360.0f,
-          .resolution = 1.0f,
-          .power      = 9.7f,
-          .reserved   = {}
-        },
-
-        { .name       = "Goldfish Temperature sensor",
-          .vendor     = "The Android Open Source Project",
-          .version    = 1,
-          .handle     = ID_TEMPERATURE,
-          .type       = SENSOR_TYPE_TEMPERATURE,
-          .maxRange   = 80.0f,
-          .resolution = 1.0f,
-          .power      = 0.0f,
-          .reserved   = {}
-        },
-
-        { .name       = "Goldfish Proximity sensor",
-          .vendor     = "The Android Open Source Project",
-          .version    = 1,
-          .handle     = ID_PROXIMITY,
-          .type       = SENSOR_TYPE_PROXIMITY,
-          .maxRange   = 1.0f,
-          .resolution = 1.0f,
-          .power      = 20.0f,
-          .reserved   = {}
-        },
-};
-
-static struct sensor_t  sSensorList[MAX_NUM_SENSORS];
-
-static int sensors__get_sensors_list(struct sensors_module_t* module,
-        struct sensor_t const** list) 
-{
-    int  fd = qemud_channel_open(SENSORS_SERVICE_NAME);
-    char buffer[12];
-    int  mask, nn, count;
-
-    int  ret;
-    if (fd < 0) {
-        E("%s: no qemud connection", __FUNCTION__);
-        return 0;
-    }
-    ret = qemud_channel_send(fd, "list-sensors", -1);
-    if (ret < 0) {
-        E("%s: could not query sensor list: %s", __FUNCTION__,
-          strerror(errno));
-        close(fd);
-        return 0;
-    }
-    ret = qemud_channel_recv(fd, buffer, sizeof buffer-1);
-    if (ret < 0) {
-        E("%s: could not receive sensor list: %s", __FUNCTION__,
-          strerror(errno));
-        close(fd);
-        return 0;
-    }
-    buffer[ret] = 0;
-    close(fd);
-
-    /* the result is a integer used as a mask for available sensors */
-    mask  = atoi(buffer);
-    count = 0;
-    for (nn = 0; nn < MAX_NUM_SENSORS; nn++) {
-        if (((1 << nn) & mask) == 0)
-            continue;
-
-        sSensorList[count++] = sSensorListInit[nn];
-    }
-    D("%s: returned %d sensors (mask=%d)", __FUNCTION__, count, mask);
-    *list = sSensorList;
-    return count;
-}
-
-
-static int
-open_sensors(const struct hw_module_t* module,
-             const char*               name,
-             struct hw_device_t*      *device)
-{
-    int  status = -EINVAL;
-
-    D("%s: name=%s", __FUNCTION__, name);
-
-    if (!strcmp(name, SENSORS_HARDWARE_POLL)) {
-        SensorPoll *dev = malloc(sizeof(*dev));
-
-        memset(dev, 0, sizeof(*dev));
-
-        dev->device.common.tag     = HARDWARE_DEVICE_TAG;
-        dev->device.common.version = 0;
-        dev->device.common.module  = (struct hw_module_t*) module;
-        dev->device.common.close   = poll__close;
-        dev->device.poll           = poll__poll;
-        dev->device.activate       = poll__activate;
-        dev->device.setDelay       = poll__setDelay;
-        dev->events_fd             = -1;
-        dev->fd                    = -1;
-
-        *device = &dev->device.common;
-        status  = 0;
-    }
-    return status;
-}
-
-
-static struct hw_module_methods_t sensors_module_methods = {
-    .open = open_sensors
-};
-
-struct sensors_module_t HAL_MODULE_INFO_SYM = {
-    .common = {
-        .tag = HARDWARE_MODULE_TAG,
-        .version_major = 1,
-        .version_minor = 0,
-        .id = SENSORS_HARDWARE_MODULE_ID,
-        .name = "Goldfish SENSORS Module",
-        .author = "The Android Open Source Project",
-        .methods = &sensors_module_methods,
-    },
-    .get_sensors_list = sensors__get_sensors_list
-};
diff --git a/emulator/tests/Android.mk b/emulator/tests/Android.mk
deleted file mode 100644
index 04917f4..0000000
--- a/emulator/tests/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# This directory contains various host tests to be used with the emulator
-# NOTE: Most of these are only built and run on Linux.
-
-LOCAL_PATH := $(call my-dir)
-
-# The test-qemud-pipes program is used to check the execution of QEMUD Pipes
-# See external/qemu/docs/ANDROID-QEMUD-PIPES.TXT for details.
-#
-ifeq ($(HOST_OS),XXXXlinux)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE     := test-qemud-pipes
-LOCAL_SRC_FILES  := test-qemud-pipes.c
-LOCAL_MODULE_TAGS := debug
-include $(BUILD_HOST_EXECUTABLE)
-
-endif # HOST_OS == linux
\ No newline at end of file
diff --git a/emulator/tests/test-qemud-pipes.c b/emulator/tests/test-qemud-pipes.c
deleted file mode 100644
index f5db531..0000000
--- a/emulator/tests/test-qemud-pipes.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* This program is used to test the QEMUD fast pipes.
- * See external/qemu/docs/ANDROID-QEMUD-PIPES.TXT for details.
- *
- * The program acts as a simple TCP server that accepts data and sends
- * them back to the client.
- */
-
-#include <sys/socket.h>
-#include <net/inet.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
-#define  DEFAULT_PORT  8012
-
-static void
-socket_close(int  sock)
-{
-    int  old_errno = errno;
-    close(sock);
-    errno = old_errno;
-}
-
-static int
-socket_loopback_server( int port, int type )
-{
-    struct sockaddr_in  addr;
-
-    int  sock = socket(AF_INET, type, 0);
-    if (sock < 0) {
-        return -1;
-    }
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sin_family      = AF_INET;
-    addr.sin_port        = htons(port);
-    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-    int n = 1;
-    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
-
-    if (TEMP_FAILURE_RETRY(bind(sock, &addr, sizeof(addr))) < 0) {
-        socket_close(sock);
-        return -1;
-    }
-
-    if (type == SOCK_STREAM) {
-        if (TEMP_FAILURE_RETRY(listen(sock, 4)) < 0) {
-            socket_close(sock);
-            return -1;
-        }
-    }
-
-    return sock;
-}
-
-int main(void)
-{
-    int sock, client;
-    int port = DEFAULT_PORT;
-
-    printf("Starting pipe test server on local port %d\n", port);
-    sock = socket_loopback_server( port, SOCK_STREAM );
-    if (sock < 0) {
-        fprintf(stderr, "Could not start server: %s\n", strerror(errno));
-        return 1;
-    }
-
-    client = accept(sock, NULL, NULL);
-    if (client < 0) {
-        fprintf(stderr, "Server error: %s\n", strerror(errno));
-        return 2;
-    }
-    printf("Client connected!\n");
-
-    /* Now, accept any incoming data, and send it back */
-    for (;;) {
-        char  buff[1024], *p;
-        int   ret, count;
-
-        do {
-            ret = read(client, buff, sizeof(buff));
-        } while (ret < 0 && errno == EINTR);
-
-        if (ret < 0) {
-            fprintf(stderr, "Client read error: %s\n", strerror(errno));
-            close(client);
-            return 3;
-        }
-        count = ret;
-        p     = buff;
-        printf("   received: %d bytes\n", count);
-
-        while (count > 0) {
-            do {
-                ret = write(client, p, count);
-            } while (ret < 0 && errno == EINTR);
-
-            if (ret < 0) {
-                fprintf(stderr, "Client write error: %s\n", strerror(errno));
-                close(client);
-                return 4;
-            }
-            printf("   sent: %d bytes\n", ret);
-
-            p     += ret;
-            count -= ret;
-        }
-    }
-
-    return 0;
-}
diff --git a/emulator/tools/Android.mk b/emulator/tools/Android.mk
deleted file mode 100644
index 1bdbf68..0000000
--- a/emulator/tools/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# this file is used to build emulator-specific program tools
-# that should only run in the emulator.
-#
-
-# We're moving the emulator-specific platform libs to
-# development.git/tools/emulator/. The following test is to ensure
-# smooth builds even if the tree contains both versions.
-#
-ifndef BUILD_EMULATOR_QEMU_PROPS
-BUILD_EMULATOR_QEMU_PROPS := true
-
-LOCAL_PATH := $(call my-dir)
-
-ifneq ($(TARGET_PRODUCT),sim)
-
-# The 'qemu-props' program is run from /system/etc/init.goldfish.rc
-# to setup various system properties sent by the emulator program.
-#
-include $(CLEAR_VARS)
-LOCAL_MODULE    := qemu-props
-LOCAL_SRC_FILES := qemu-props.c
-LOCAL_SHARED_LIBRARIES := libcutils
-# we don't want this in 'user' builds which don't have
-# emulator-specific binaries.
-LOCAL_MODULE_TAGS := debug
-include $(BUILD_EXECUTABLE)
-
-endif # TARGET_PRODUCT != sim
-
-endif # BUILD_EMULATOR_QEMU_PROPS
diff --git a/emulator/tools/qemu-props.c b/emulator/tools/qemu-props.c
deleted file mode 100644
index 56d510f..0000000
--- a/emulator/tools/qemu-props.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* this program is used to read a set of system properties and their values
- * from the emulator program and set them in the currently-running emulated
- * system. It does so by connecting to the 'boot-properties' qemud service.
- *
- * This program should be run as root and called from
- * /system/etc/init.goldfish.rc exclusively.
- */
-
-#define LOG_TAG  "qemu-props"
-
-#define DEBUG  1
-
-#if DEBUG
-#  include <cutils/log.h>
-#  define  DD(...)    ALOGI(__VA_ARGS__)
-#else
-#  define  DD(...)    ((void)0)
-#endif
-
-#include <cutils/properties.h>
-#include <unistd.h>
-#include <hardware/qemud.h>
-
-/* Name of the qemud service we want to connect to.
- */
-#define  QEMUD_SERVICE  "boot-properties"
-
-#define  MAX_TRIES      5
-
-int  main(void)
-{
-    int  qemud_fd, count = 0;
-
-    /* try to connect to the qemud service */
-    {
-        int  tries = MAX_TRIES;
-
-        while (1) {
-            qemud_fd = qemud_channel_open( "boot-properties" );
-            if (qemud_fd >= 0)
-                break;
-
-            if (--tries <= 0) {
-                DD("Could not connect after too many tries. Aborting");
-                return 1;
-            }
-
-            DD("waiting 1s to wait for qemud.");
-            sleep(1);
-        }
-    }
-
-    DD("connected to '%s' qemud service.", QEMUD_SERVICE);
-
-    /* send the 'list' command to the service */
-    if (qemud_channel_send(qemud_fd, "list", -1) < 0) {
-        DD("could not send command to '%s' service", QEMUD_SERVICE);
-        return 1;
-    }
-
-    /* read each system property as a single line from the service,
-     * until exhaustion.
-     */
-    for (;;)
-    {
-#define  BUFF_SIZE   (PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 2)
-        DD("receiving..");
-        char* q;
-        char  temp[BUFF_SIZE];
-        int   len = qemud_channel_recv(qemud_fd, temp, sizeof temp - 1);
-
-        /* lone NUL-byte signals end of properties */
-        if (len < 0 || len > BUFF_SIZE-1 || temp[0] == '\0')
-            break;
-
-        temp[len] = '\0';  /* zero-terminate string */
-
-        DD("received: %.*s", len, temp);
-
-        /* separate propery name from value */
-        q = strchr(temp, '=');
-        if (q == NULL) {
-            DD("invalid format, ignored.");
-            continue;
-        }
-        *q++ = '\0';
-
-        if (property_set(temp, q) < 0) {
-            DD("could not set property '%s' to '%s'", temp, q);
-        } else {
-            count += 1;
-        }
-    }
-
-
-    /* finally, close the channel and exit */
-    close(qemud_fd);
-    DD("exiting (%d properties set).", count);
-    return 0;
-}
diff --git a/jobb/Android.mk b/jobb/Android.mk
index 1a58732..2750830 100644
--- a/jobb/Android.mk
+++ b/jobb/Android.mk
@@ -23,7 +23,7 @@
 LOCAL_JAVA_LIBRARIES := fat32lib
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/layoutlib_api/Android.mk b/layoutlib_api/Android.mk
index 169cf37..e03b7dc 100644
--- a/layoutlib_api/Android.mk
+++ b/layoutlib_api/Android.mk
@@ -29,7 +29,7 @@
 LOCAL_MODULE := layoutlib_api
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/lint/cli/Android.mk b/lint/cli/Android.mk
index 00c736b..0f29dae 100644
--- a/lint/cli/Android.mk
+++ b/lint/cli/Android.mk
@@ -36,7 +36,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/lint/libs/lint_api/Android.mk b/lint/libs/lint_api/Android.mk
index 3510559..e30db14 100644
--- a/lint/libs/lint_api/Android.mk
+++ b/lint/libs/lint_api/Android.mk
@@ -34,7 +34,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/lint/libs/lint_checks/Android.mk b/lint/libs/lint_checks/Android.mk
index 1382715..4229820 100644
--- a/lint/libs/lint_checks/Android.mk
+++ b/lint/libs/lint_checks/Android.mk
@@ -37,7 +37,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/manifmerger/Android.mk b/manifmerger/Android.mk
index b07af36..a9b4915 100644
--- a/manifmerger/Android.mk
+++ b/manifmerger/Android.mk
@@ -26,7 +26,7 @@
 LOCAL_JAVA_LIBRARIES := common sdklib
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/sdk_common/Android.mk b/sdk_common/Android.mk
index 17c78cb..1550052 100644
--- a/sdk_common/Android.mk
+++ b/sdk_common/Android.mk
@@ -33,7 +33,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/sdkmanager/app/Android.mk b/sdkmanager/app/Android.mk
index f72c401..428b8a0 100644
--- a/sdkmanager/app/Android.mk
+++ b/sdkmanager/app/Android.mk
@@ -12,7 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-LOCAL_PATH := $(call my-dir)
+ORIG_LOCAL_PATH := $(call my-dir)
+LOCAL_PATH := $(ORIG_LOCAL_PATH)
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)
@@ -49,6 +50,7 @@
 # ----- TESTS ------
 # Copyright (C) 2011 The Android Open Source Project
 
+LOCAL_PATH := $(ORIG_LOCAL_PATH)
 include $(CLEAR_VARS)
 
 # Only compile source java files in this lib.
diff --git a/sdkmanager/libs/sdklib/Android.mk b/sdkmanager/libs/sdklib/Android.mk
index ef0362d..c24fc5a 100644
--- a/sdkmanager/libs/sdklib/Android.mk
+++ b/sdkmanager/libs/sdklib/Android.mk
@@ -39,7 +39,7 @@
         layoutlib_api
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/sdkmanager/libs/sdkuilib/Android.mk b/sdkmanager/libs/sdkuilib/Android.mk
index df35432..155da45 100644
--- a/sdkmanager/libs/sdkuilib/Android.mk
+++ b/sdkmanager/libs/sdkuilib/Android.mk
@@ -42,7 +42,7 @@
 	swtmenubar
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)
 
diff --git a/swtmenubar/Android.mk b/swtmenubar/Android.mk
index 01e8645..699eeb3 100644
--- a/swtmenubar/Android.mk
+++ b/swtmenubar/Android.mk
@@ -26,7 +26,7 @@
 	org.eclipse.jface_3.6.2.M20110210-1200
 
 LOCAL_PREBUILT_JAVA_LIBRARIES := \
-	../../prebuilts/devtools/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+	../../prebuilts/devtools/tools/lib/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
 
 include $(BUILD_HOST_PREBUILT)