Add missing delegates for M preview.

- Remove ICU dependency (use the version bundled with platform).
- Restructure intelliJ project to move dependencies to module.
- Minor fixes to layoutlib tests.

TODO:
- Load ICU data.
- Hyphenator doesn't work.
- High quality line breaker not present.

Change-Id: I965e096e17bfc97ee995a649c3f4f6f64bb4f70d
diff --git a/tools/layoutlib/.idea/libraries/asm_4_0.xml b/tools/layoutlib/.idea/libraries/asm_4_0.xml
deleted file mode 100644
index 7df287f..0000000
--- a/tools/layoutlib/.idea/libraries/asm_4_0.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="asm-4.0">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/asm/asm-4.0.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/asm/src.zip!/" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/framework_jar.xml b/tools/layoutlib/.idea/libraries/framework_jar.xml
deleted file mode 100644
index 6695a36..0000000
--- a/tools/layoutlib/.idea/libraries/framework_jar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<component name="libraryTable">
-  <library name="framework.jar">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="file://$PROJECT_DIR$/../../core/java" />
-      <root url="file://$PROJECT_DIR$/../../graphics/java" />
-      <root url="file://$PROJECT_DIR$/../../../../libcore/luni/src/main/java" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/guava.xml b/tools/layoutlib/.idea/libraries/guava.xml
deleted file mode 100644
index eb60719..0000000
--- a/tools/layoutlib/.idea/libraries/guava.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="guava">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0-sources.jar!/" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/icu4j.xml b/tools/layoutlib/.idea/libraries/icu4j.xml
deleted file mode 100644
index dbe0bd7..0000000
--- a/tools/layoutlib/.idea/libraries/icu4j.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="icu4j">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/icu4j/icu4j.jar!/" />
-    </CLASSES>
-    <JAVADOC>
-      <root url="http://icu-project.org/apiref/icu4j50rc/" />
-    </JAVADOC>
-    <SOURCES />
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/kxml2_2_3_0.xml b/tools/layoutlib/.idea/libraries/kxml2_2_3_0.xml
deleted file mode 100644
index 2a65050..0000000
--- a/tools/layoutlib/.idea/libraries/kxml2_2_3_0.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="kxml2-2.3.0">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="file://$PROJECT_DIR$/../../../../libcore/xml/src/main/java" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml b/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml
deleted file mode 100644
index a873600..0000000
--- a/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="layoutlib_api-prebuilt">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-sources.jar!/" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/ninepatch_prebuilt.xml b/tools/layoutlib/.idea/libraries/ninepatch_prebuilt.xml
deleted file mode 100644
index f34f7dd..0000000
--- a/tools/layoutlib/.idea/libraries/ninepatch_prebuilt.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="ninepatch-prebuilt">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="file://$ANDROID_SRC$/tools/base/ninepatch/src/main/java" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/tools_common_prebuilt.xml b/tools/layoutlib/.idea/libraries/tools_common_prebuilt.xml
deleted file mode 100644
index b325ad4..0000000
--- a/tools/layoutlib/.idea/libraries/tools_common_prebuilt.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<component name="libraryTable">
-  <library name="tools-common-prebuilt">
-    <ANNOTATIONS>
-      <root url="file://$PROJECT_DIR$" />
-    </ANNOTATIONS>
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="file://$ANDROID_SRC$/tools/base/common/src/main/java" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk
index 80b4d59..0dbdd56 100644
--- a/tools/layoutlib/bridge/Android.mk
+++ b/tools/layoutlib/bridge/Android.mk
@@ -22,7 +22,6 @@
 
 
 LOCAL_JAVA_LIBRARIES := \
-	icu4j \
 	layoutlib_api-prebuilt \
 	tools-common-prebuilt
 
diff --git a/tools/layoutlib/bridge/bridge.iml b/tools/layoutlib/bridge/bridge.iml
index 0baa5ab..d2b1259 100644
--- a/tools/layoutlib/bridge/bridge.iml
+++ b/tools/layoutlib/bridge/bridge.iml
@@ -24,15 +24,79 @@
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="icu4j" level="project" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-    <orderEntry type="library" name="ninepatch-prebuilt" level="project" />
-    <orderEntry type="library" name="tools-common-prebuilt" level="project" />
-    <orderEntry type="library" name="framework.jar" level="project" />
-    <orderEntry type="library" scope="TEST" name="kxml2-2.3.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="guava" level="project" />
+    <orderEntry type="module-library">
+      <library name="layoutlib_api-prebuilt">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library name="ninepatch-prebuilt">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="file://$ANDROID_SRC$/tools/base/ninepatch/src/main/java" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library name="tools-common-prebuilt">
+        <ANNOTATIONS>
+          <root url="file://$MODULE_DIR$/.." />
+        </ANNOTATIONS>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="file://$ANDROID_SRC$/tools/base/common/src/main/java" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library name="framework.jar">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="file://$MODULE_DIR$/../../../core/java" />
+          <root url="file://$MODULE_DIR$/../../../graphics/java" />
+          <root url="file://$MODULE_DIR$/../../../../../libcore/luni/src/main/java" />
+        </SOURCES>
+      </library>
+    </orderEntry>
     <orderEntry type="module-library" scope="TEST">
-      <library>
+      <library name="kxml2-2.3.0">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="file://$MODULE_DIR$/../../../../../libcore/xml/src/main/java" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library" scope="TEST">
+      <library name="guava">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library" scope="TEST">
+      <library name="sdk-common">
         <CLASSES>
           <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
         </CLASSES>
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index 7d4271b..572fdc9 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -758,6 +758,17 @@
         return s != null && ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false);
     }
 
+    @Override
+    public int getType(int index) {
+        if (!hasValue(index)) {
+            return TypedValue.TYPE_NULL;
+        }
+        ResourceValue value = mResourceData[index];
+        ResourceType resourceType = value.getResourceType();
+        return 0;
+        // TODO: fixme.
+    }
+
     /**
      * Determines whether there is an attribute at <var>index</var>.
      *
diff --git a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
index a4a3b7d..21f36ce 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
@@ -19,6 +19,12 @@
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 
+import android.graphics.Paint_Delegate.FontInfo;
+import android.icu.lang.UScript;
+import android.icu.lang.UScriptRun;
+import android.icu.text.Bidi;
+import android.icu.text.BidiRun;
+
 import java.awt.Font;
 import java.awt.Graphics2D;
 import java.awt.Toolkit;
@@ -29,13 +35,6 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import com.ibm.icu.lang.UScript;
-import com.ibm.icu.lang.UScriptRun;
-import com.ibm.icu.text.Bidi;
-import com.ibm.icu.text.BidiRun;
-
-import android.graphics.Paint_Delegate.FontInfo;
-
 /**
  * Render the text by breaking it into various scripts and using the right font for each script.
  * Can be used to measure the text without actually drawing it.
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
index e9b5d6e..af47aeb 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
@@ -23,7 +23,15 @@
 
 import android.graphics.Shader.TileMode;
 
+import java.awt.PaintContext;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
 import java.awt.image.ColorModel;
+import java.awt.image.Raster;
 
 /**
  * Delegate implementing the native methods of android.graphics.BitmapShader
@@ -67,9 +75,9 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long native_bitmap, int shaderTileModeX,
+    /*package*/ static long nativeCreate(Bitmap androidBitmap, int shaderTileModeX,
             int shaderTileModeY) {
-        Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(native_bitmap);
+        Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(androidBitmap);
         if (bitmap == null) {
             return 0;
         }
@@ -83,17 +91,17 @@
 
     // ---- Private delegate/helper methods ----
 
-    private BitmapShader_Delegate(java.awt.image.BufferedImage image,
+    private BitmapShader_Delegate(BufferedImage image,
             TileMode tileModeX, TileMode tileModeY) {
         mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY);
     }
 
     private class BitmapShaderPaint implements java.awt.Paint {
-        private final java.awt.image.BufferedImage mImage;
+        private final BufferedImage mImage;
         private final TileMode mTileModeX;
         private final TileMode mTileModeY;
 
-        BitmapShaderPaint(java.awt.image.BufferedImage image,
+        BitmapShaderPaint(BufferedImage image,
                 TileMode tileModeX, TileMode tileModeY) {
             mImage = image;
             mTileModeX = tileModeX;
@@ -101,29 +109,24 @@
         }
 
         @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel      colorModel,
-                java.awt.Rectangle             deviceBounds,
-                java.awt.geom.Rectangle2D      userBounds,
-                java.awt.geom.AffineTransform  xform,
-                java.awt.RenderingHints        hints) {
-
-            java.awt.geom.AffineTransform canvasMatrix;
+        public PaintContext createContext(ColorModel colorModel, Rectangle deviceBounds,
+                Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) {
+            AffineTransform canvasMatrix;
             try {
                 canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
+            } catch (NoninvertibleTransformException e) {
                 Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
                         "Unable to inverse matrix in BitmapShader", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
+                canvasMatrix = new AffineTransform();
             }
 
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
+            AffineTransform localMatrix = getLocalMatrix();
             try {
                 localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
+            } catch (NoninvertibleTransformException e) {
                 Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
                         "Unable to inverse matrix in BitmapShader", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
+                localMatrix = new AffineTransform();
             }
 
             if (!colorModel.isCompatibleRaster(mImage.getRaster())) {
@@ -134,16 +137,16 @@
             return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel);
         }
 
-        private class BitmapShaderContext implements java.awt.PaintContext {
+        private class BitmapShaderContext implements PaintContext {
 
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
+            private final AffineTransform mCanvasMatrix;
+            private final AffineTransform mLocalMatrix;
+            private final ColorModel mColorModel;
 
             public BitmapShaderContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
+                    AffineTransform canvasMatrix,
+                    AffineTransform localMatrix,
+                    ColorModel colorModel) {
                 mCanvasMatrix = canvasMatrix;
                 mLocalMatrix = localMatrix;
                 mColorModel = colorModel;
@@ -154,13 +157,13 @@
             }
 
             @Override
-            public java.awt.image.ColorModel getColorModel() {
+            public ColorModel getColorModel() {
                 return mColorModel;
             }
 
             @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
+            public Raster getRaster(int x, int y, int w, int h) {
+                BufferedImage image = new BufferedImage(
                     mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
                     mColorModel.isAlphaPremultiplied(), null);
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index 970b9d0..874bc9d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -16,6 +16,7 @@
 
 package android.graphics;
 
+import com.android.annotations.Nullable;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
@@ -82,6 +83,12 @@
         return sManager.getDelegate(native_bitmap);
     }
 
+    @Nullable
+    public static Bitmap_Delegate getDelegate(@Nullable Bitmap bitmap) {
+        // refSkPixelRef is a hack to get the native pointer: see #nativeRefPixelRef()
+        return bitmap == null ? null : getDelegate(bitmap.refSkPixelRef());
+    }
+
     /**
      * Creates and returns a {@link Bitmap} initialized with the given file content.
      *
@@ -180,18 +187,7 @@
         return createBitmap(delegate, createFlags, density.getDpiValue());
     }
 
-    public static int getBufferedImageType(int nativeBitmapConfig) {
-        switch (Config.nativeToConfig(nativeBitmapConfig)) {
-            case ALPHA_8:
-                return BufferedImage.TYPE_INT_ARGB;
-            case RGB_565:
-                return BufferedImage.TYPE_INT_ARGB;
-            case ARGB_4444:
-                return BufferedImage.TYPE_INT_ARGB;
-            case ARGB_8888:
-                return BufferedImage.TYPE_INT_ARGB;
-        }
-
+    private static int getBufferedImageType() {
         return BufferedImage.TYPE_INT_ARGB;
     }
 
@@ -218,10 +214,6 @@
         return mHasAlpha && mConfig != Config.RGB_565;
     }
 
-    public boolean hasMipMap() {
-        // TODO: check if more checks are required as in hasAlpha.
-        return mHasMipMap;
-    }
     /**
      * Update the generationId.
      *
@@ -236,7 +228,7 @@
     @LayoutlibDelegate
     /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
             int height, int nativeConfig, boolean isMutable) {
-        int imageType = getBufferedImageType(nativeConfig);
+        int imageType = getBufferedImageType();
 
         // create the image
         BufferedImage image = new BufferedImage(width, height, imageType);
@@ -264,7 +256,7 @@
         int width = srcImage.getWidth();
         int height = srcImage.getHeight();
 
-        int imageType = getBufferedImageType(nativeConfig);
+        int imageType = getBufferedImageType();
 
         // create the image
         BufferedImage image = new BufferedImage(width, height, imageType);
@@ -353,22 +345,16 @@
     /*package*/ static boolean nativeHasAlpha(long nativeBitmap) {
         // get the delegate from the native int.
         Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return true;
-        }
+        return delegate == null || delegate.mHasAlpha;
 
-        return delegate.mHasAlpha;
     }
 
     @LayoutlibDelegate
     /*package*/ static boolean nativeHasMipMap(long nativeBitmap) {
         // get the delegate from the native int.
         Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return true;
-        }
+        return delegate == null || delegate.mHasMipMap;
 
-        return delegate.mHasMipMap;
     }
 
     @LayoutlibDelegate
@@ -489,11 +475,6 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void nativePrepareToDraw(long nativeBitmap) {
-        // nothing to be done here.
-    }
-
-    @LayoutlibDelegate
     /*package*/ static boolean nativeIsPremultiplied(long nativeBitmap) {
         // get the delegate from the native int.
         Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
@@ -579,6 +560,14 @@
         return Arrays.equals(argb1, argb2);
     }
 
+    // Only used by AssetAtlasService, which we don't care about.
+    @LayoutlibDelegate
+    /*package*/ static long nativeRefPixelRef(long nativeBitmap) {
+        // Hack: This is called by Bitmap.refSkPixelRef() and LayoutLib uses that method to get
+        // the native pointer from a Bitmap. So, we return nativeBitmap here.
+        return nativeBitmap;
+    }
+
     // ---- Private delegate/helper methods ----
 
     private Bitmap_Delegate(BufferedImage image, Config config) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index e1091f0..47acc42 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -16,6 +16,7 @@
 
 package android.graphics;
 
+import com.android.annotations.Nullable;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
@@ -114,7 +115,11 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long initRaster(long nativeBitmapOrZero) {
+    /*package*/ static long initRaster(@Nullable Bitmap bitmap) {
+        long nativeBitmapOrZero = 0;
+        if (bitmap != null) {
+            nativeBitmapOrZero = bitmap.refSkPixelRef();
+        }
         if (nativeBitmapOrZero > 0) {
             // get the Bitmap from the int
             Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmapOrZero);
@@ -132,8 +137,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/
-    static void native_setBitmap(long canvas, long bitmap, boolean copyState) {
+    /*package*/ static void native_setBitmap(long canvas, Bitmap bitmap) {
         Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas);
         Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
         if (canvasDelegate == null || bitmapDelegate==null) {
@@ -427,8 +431,7 @@
 
         canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter);
 
-        if (canvasDelegate.mDrawFilter != null &&
-                canvasDelegate.mDrawFilter.isSupported() == false) {
+        if (canvasDelegate.mDrawFilter != null && !canvasDelegate.mDrawFilter.isSupported()) {
             Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER,
                     canvasDelegate.mDrawFilter.getSupportMessage(), null, null /*data*/);
         }
@@ -444,7 +447,7 @@
         }
 
         Rectangle rect = canvasDelegate.getSnapshot().getClip().getBounds();
-        if (rect != null && rect.isEmpty() == false) {
+        if (rect != null && !rect.isEmpty()) {
             bounds.left = rect.x;
             bounds.top = rect.y;
             bounds.right = rect.x + rect.width;
@@ -720,7 +723,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, long bitmap,
+    /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, Bitmap bitmap,
                                                  float left, float top,
                                                  long nativePaintOrZero,
                                                  int canvasDensity,
@@ -742,7 +745,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, long bitmap,
+    /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, Bitmap bitmap,
                                  float srcLeft, float srcTop, float srcRight, float srcBottom,
                                  float dstLeft, float dstTop, float dstRight, float dstBottom,
                                  long nativePaintOrZero, int screenDensity, int bitmapDensity) {
@@ -783,7 +786,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void nativeDrawBitmapMatrix(long nCanvas, long nBitmap,
+    /*package*/ static void nativeDrawBitmapMatrix(long nCanvas, Bitmap bitmap,
                                                       long nMatrix, long nPaint) {
         // get the delegate from the native int.
         Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
@@ -795,7 +798,7 @@
         Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
 
         // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nBitmap);
+        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
         if (bitmapDelegate == null) {
             return;
         }
@@ -824,7 +827,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void nativeDrawBitmapMesh(long nCanvas, long nBitmap,
+    /*package*/ static void nativeDrawBitmapMesh(long nCanvas, Bitmap bitmap,
             int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,
             int colorOffset, long nPaint) {
         // FIXME
@@ -1041,8 +1044,7 @@
     }
 
     /**
-     * Restores the {@link GcSnapshot} to <var>saveCount</var>
-     * @param saveCount the saveCount
+     * Restores the top {@link GcSnapshot}
      */
     private void restore() {
         mSnapshot = mSnapshot.restore();
@@ -1105,7 +1107,7 @@
         // before drawing it.
         if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) {
             fixAlpha8Bitmap(image);
-        } else if (bitmap.hasAlpha() == false) {
+        } else if (!bitmap.hasAlpha()) {
             // hasAlpha is merely a rendering hint. There can in fact be alpha values
             // in the bitmap but it should be ignored at drawing time.
             // There is two ways to do this:
@@ -1125,7 +1127,7 @@
             }
 
             // if we can't force SRC mode, then create a temp bitmap of TYPE_RGB
-            if (forceSrcMode[0] == false) {
+            if (!forceSrcMode[0]) {
                 image = Bitmap_Delegate.createCopy(image, BufferedImage.TYPE_INT_RGB, 0xFF);
             }
         }
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
index e16dbda..e8d34d0 100644
--- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
@@ -90,7 +90,7 @@
             if (oos != null) {
                 try {
                     oos.close();
-                } catch (IOException e) {
+                } catch (IOException ignored) {
                 }
             }
         }
@@ -136,7 +136,7 @@
                 if (ois != null) {
                     try {
                         ois.close();
-                    } catch (IOException e) {
+                    } catch (IOException ignored) {
                     }
                 }
             }
@@ -150,15 +150,12 @@
     @LayoutlibDelegate
     /*package*/ static boolean isNinePatchChunk(byte[] chunk) {
         NinePatchChunk chunkObject = getChunk(chunk);
-        if (chunkObject != null) {
-            return true;
-        }
+        return chunkObject != null;
 
-        return false;
     }
 
     @LayoutlibDelegate
-    /*package*/ static long validateNinePatchChunk(long bitmap, byte[] chunk) {
+    /*package*/ static long validateNinePatchChunk(byte[] chunk) {
         // the default JNI implementation only checks that the byte[] has the same
         // size as the C struct it represent. Since we cannot do the same check (serialization
         // will return different size depending on content), we do nothing.
@@ -173,7 +170,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void nativeDraw(long canvas_instance, RectF loc, long bitmap_instance,
+    /*package*/ static void nativeDraw(long canvas_instance, RectF loc, Bitmap bitmap_instance,
             long chunk, long paint_instance_or_null, int destDensity, int srcDensity) {
         draw(canvas_instance,
                 (int) loc.left, (int) loc.top, (int) loc.right, (int) loc.bottom,
@@ -182,7 +179,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void nativeDraw(long canvas_instance, Rect loc, long bitmap_instance,
+    /*package*/ static void nativeDraw(long canvas_instance, Rect loc, Bitmap bitmap_instance,
             long chunk, long paint_instance_or_null, int destDensity, int srcDensity) {
         draw(canvas_instance,
                 loc.left, loc.top, loc.right, loc.bottom,
@@ -191,7 +188,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long nativeGetTransparentRegion(long bitmap, long chunk, Rect location) {
+    /*package*/ static long nativeGetTransparentRegion(Bitmap bitmap, long chunk, Rect location) {
         return 0;
     }
 
@@ -199,7 +196,7 @@
 
     private static void draw(long canvas_instance,
             final int left, final int top, final int right, final int bottom,
-            long bitmap_instance, long chunk, long paint_instance_or_null,
+            Bitmap bitmap_instance, long chunk, long paint_instance_or_null,
             final int destDensity, final int srcDensity) {
         // get the delegate from the native int.
         final Bitmap_Delegate bitmap_delegate = Bitmap_Delegate.getDelegate(bitmap_instance);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 0c8c0d6..a2e9a85 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -16,6 +16,8 @@
 
 package android.graphics;
 
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
@@ -83,6 +85,8 @@
     private float mTextScaleX;
     private float mTextSkewX;
     private int mHintingMode = Paint.HINTING_ON;
+    private int mHyphenEdit;
+    private float mLetterSpacing;  // not used in actual text rendering.
     // Variant of the font. A paint's variant can only be compact or elegant.
     private FontVariant mFontVariant = FontVariant.COMPACT;
 
@@ -100,6 +104,7 @@
 
     // ---- Public Helper methods ----
 
+    @Nullable
     public static Paint_Delegate getDelegate(long native_paint) {
         return sManager.getDelegate(native_paint);
     }
@@ -1088,18 +1093,107 @@
 
     @LayoutlibDelegate
     /*package*/ static float native_getLetterSpacing(long nativePaint) {
-        // TODO: throw a fidelity warning.
-        return 0;
+        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+        return delegate.mLetterSpacing;
     }
 
     @LayoutlibDelegate
     /*package*/ static void native_setLetterSpacing(long nativePaint, float letterSpacing) {
-        // pass.
+        Bridge.getLog().fidelityWarning("textRendering", "Paint.setLetterSpacing() not supported.",
+                null, null);
+        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+        if (delegate == null) {
+            return;
+        }
+        delegate.mLetterSpacing = letterSpacing;
     }
 
     @LayoutlibDelegate
     /*package*/ static void native_setFontFeatureSettings(long nativePaint, String settings) {
-        // pass.
+        Bridge.getLog().fidelityWarning("textRendering",
+                "Paint.setFontFeatureSettings() not supported.", null, null);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_getHyphenEdit(long nativePaint) {
+        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+        return delegate.mHyphenEdit;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setHyphenEdit(long nativePaint, int hyphen) {
+        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+        if (delegate == null) {
+            return;
+        }
+        delegate.mHyphenEdit = hyphen;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_hasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
+            String string) {
+        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+        if (delegate == null) {
+            return false;
+        }
+        if (string.length() == 0) {
+            return false;
+        }
+        if (string.length() > 1) {
+            Bridge.getLog().fidelityWarning("textRendering",
+                    "Paint.hasGlyph() is not supported for ligatures.", null, null);
+            return false;
+        }
+        assert nativeTypeface == delegate.mNativeTypeface;
+        Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
+
+        char c = string.charAt(0);
+        for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
+            if (font.canDisplay(c)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    @LayoutlibDelegate
+    /*package*/ static float native_getRunAdvance(long nativePaint, long nativeTypeface,
+            @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
+            boolean isRtl, int offset) {
+        int count = end - start;
+        float[] advances = new float[count];
+        native_getTextRunAdvances(nativePaint, nativeTypeface, text, start, count,
+                contextStart, contextEnd - contextStart, isRtl, advances, 0);
+        float sum = 0;
+        for (int i = 0; i < offset; i++) {
+            sum += advances[i];
+        }
+        return sum;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_getOffsetForAdvance(long nativePaint, long nativeTypeface,
+            char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
+            float advance) {
+        int count = end - start;
+        float[] advances = new float[count];
+        native_getTextRunAdvances(nativePaint, nativeTypeface, text, start, count,
+                contextStart, contextEnd - contextStart, isRtl, advances, 0);
+        float sum = 0;
+        int i;
+        for (i = 0; i < count && sum < advance; i++) {
+            sum += advances[i];
+        }
+        float distanceToI = sum - advance;
+        float distanceToIMinus1 = advance - (sum - advances[i]);
+        return distanceToI > distanceToIMinus1 ? i : i - 1;
     }
 
     // ---- Private delegate/helper methods ----
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
index 14e9960..0d491a0 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -81,14 +81,15 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void nativeSetLocalMatrix(long native_shader, long matrix_instance) {
+    /*package*/ static long nativeSetLocalMatrix(long native_shader, long matrix_instance) {
         // get the delegate from the native int.
         Shader_Delegate shaderDelegate = sManager.getDelegate(native_shader);
         if (shaderDelegate == null) {
-            return;
+            return native_shader;
         }
 
         shaderDelegate.mLocalMatrix = Matrix_Delegate.getDelegate(matrix_instance);
+        return native_shader;
     }
 
     // ---- Private delegate/helper methods ----
diff --git a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java b/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
index 6247dae..38171dc 100644
--- a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
@@ -19,8 +19,8 @@
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.ibm.icu.text.Bidi;
 
+import android.icu.text.Bidi;
 
 /**
  * Delegate used to provide new implementation for the native methods of {@link AndroidBidi}
diff --git a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
index c72efc2..b95cda6 100644
--- a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
+++ b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
@@ -36,7 +36,7 @@
     }
 
     @Override
-    public void computeBreaks(LineBreaks lineBreaks) {
+    public void computeBreaks(@NonNull LineBreaks lineBreaks) {
         BreakInfo breakInfo = new BreakInfo();
         int lineNum = 0;
         float width = 0, printedWidth = 0;
diff --git a/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java b/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java
new file mode 100644
index 0000000..5a59597
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.io.File;
+
+/**
+ * Delegate that overrides implementation for certain methods in {@link android.text.StaticLayout}
+ * <p/>
+ * Through the layoutlib_create tool, selected methods of StaticLayout have been replaced
+ * by calls to methods of the same name in this delegate class.
+ */
+public class Hyphenator_Delegate {
+
+    private static final DelegateManager<Hyphenator_Delegate> sDelegateManager = new
+            DelegateManager<Hyphenator_Delegate>(Hyphenator_Delegate.class);
+
+    @LayoutlibDelegate
+    /*package*/ static File getSystemHyphenatorLocation() {
+        // FIXME
+        return null;
+    }
+
+    /*package*/ static long loadHyphenator(String patternData) {
+        return sDelegateManager.addNewDelegate(new Hyphenator_Delegate());
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/text/LineBreaker.java b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
index 54445a4..edeef78 100644
--- a/tools/layoutlib/bridge/src/android/text/LineBreaker.java
+++ b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
@@ -39,6 +39,5 @@
         mTabStops = tabStops;
     }
 
-    @NonNull
     public abstract void computeBreaks(@NonNull LineBreaks breakInfo);
 }
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
index 86d8da3..7971902 100644
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
@@ -8,15 +8,15 @@
 import android.graphics.Paint;
 import android.graphics.Paint_Delegate;
 import android.graphics.RectF;
-import android.text.StaticLayout.LineBreaks;
+import android.icu.text.BreakIterator;
+import android.icu.util.ULocale;
 import android.text.Primitive.PrimitiveType;
+import android.text.StaticLayout.LineBreaks;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-import com.ibm.icu.text.BreakIterator;
-import com.ibm.icu.util.ULocale;
 import javax.swing.text.Segment;
 
 /**
@@ -38,15 +38,55 @@
         new DelegateManager<Builder>(Builder.class);
 
     @LayoutlibDelegate
-    /*package*/ static int nComputeLineBreaks(long nativeBuilder,
-            int length, float firstWidth, int firstWidthLineCount, float restWidth,
-            int[] variableTabStops, int defaultTabStop, boolean optimize, LineBreaks recycle,
-            int[] recycleBreaks, float[] recycleWidths, boolean[] recycleFlags, int recycleLength) {
+    /*package*/ static long nNewBuilder() {
+        return sBuilderManager.addNewDelegate(new Builder());
+    }
 
+    @LayoutlibDelegate
+    /*package*/ static void nFreeBuilder(long nativeBuilder) {
+        sBuilderManager.removeJavaReferenceFor(nativeBuilder);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nFinishBuilder(long nativeBuilder) {
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static long nLoadHyphenator(String patternData) {
+        return Hyphenator_Delegate.loadHyphenator(patternData);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nSetLocale(long nativeBuilder, String locale, long nativeHyphenator) {
         Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+        if (builder != null) {
+            builder.mLocale = locale;
+            builder.mNativeHyphenator = nativeHyphenator;
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nSetIndents(long nativeBuilder, int[] indents) {
+        // TODO.
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nSetupParagraph(long nativeBuilder, char[] text, int length,
+            float firstWidth, int firstWidthLineCount, float restWidth,
+            int[] variableTabStops, int defaultTabStop, int breakStrategy,
+            int hyphenationFrequency) {
+        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+        if (builder == null) {
+            return;
+        }
+
+        builder.mText = text;
+        builder.mWidths = new float[length];
+
         // compute all possible breakpoints.
         BreakIterator it = BreakIterator.getLineInstance(new ULocale(builder.mLocale));
         it.setText(new Segment(builder.mText, 0, length));
+
         // average word length in english is 5. So, initialize the possible breaks with a guess.
         List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d));
         int loc;
@@ -54,17 +94,73 @@
         while ((loc = it.next()) != BreakIterator.DONE) {
             breaks.add(loc);
         }
-
         LineWidth lineWidth = new LineWidth(firstWidth, firstWidthLineCount, restWidth);
         TabStops tabStopCalculator = new TabStops(variableTabStops, defaultTabStop);
-        List<Primitive> primitives = computePrimitives(builder.mText, builder.mWidths, length, breaks);
-        LineBreaker lineBreaker;
-        if (optimize) {
-            lineBreaker = new OptimizingLineBreaker(primitives, lineWidth, tabStopCalculator);
-        } else {
-            lineBreaker = new GreedyLineBreaker(primitives, lineWidth, tabStopCalculator);
+        List<Primitive> primitives =
+                computePrimitives(builder.mText, builder.mWidths, length, breaks);
+        BreakStrategy strategy = BreakStrategy.getStrategy(breakStrategy);
+        switch (strategy) {
+            case GREEDY:
+                builder.mLineBreaker =
+                        new GreedyLineBreaker(primitives, lineWidth, tabStopCalculator);
+                break;
+            case HIGH_QUALITY:
+                // TODO
+                break;
+            case BALANCED:
+                builder.mLineBreaker = new OptimizingLineBreaker(primitives, lineWidth,
+                        tabStopCalculator);
+                break;
         }
-        lineBreaker.computeBreaks(recycle);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nAddStyleRun(long nativeBuilder, long nativePaint, long nativeTypeface,
+            int start, int end, boolean isRtl) {
+        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+
+        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
+        return builder == null ? 0 :
+                measureText(nativePaint, builder.mText, start, end - start, builder.mWidths,
+                        bidiFlags);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nAddMeasuredRun(long nativeBuilder, int start, int end, float[] widths) {
+        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+        if (builder != null) {
+            System.arraycopy(widths, start, builder.mWidths, start, end - start);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nAddReplacementRun(long nativeBuilder, int start, int end, float width) {
+        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+        if (builder == null) {
+            return;
+        }
+        builder.mWidths[start] = width;
+        Arrays.fill(builder.mWidths, start + 1, end, 0.0f);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nGetWidths(long nativeBuilder, float[] floatsArray) {
+        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+        if (builder != null) {
+            System.arraycopy(builder.mWidths, 0, floatsArray, 0, builder.mWidths.length);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nComputeLineBreaks(long nativeBuilder,
+            LineBreaks recycle, int[] recycleBreaks, float[] recycleWidths,
+            int[] recycleFlags, int recycleLength) {
+
+        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+        if (builder == null) {
+            return 0;
+        }
+        builder.mLineBreaker.computeBreaks(recycle);
         return recycle.breaks.length;
     }
 
@@ -109,63 +205,6 @@
         return primitives;
     }
 
-    @LayoutlibDelegate
-    /*package*/ static long nNewBuilder() {
-        return sBuilderManager.addNewDelegate(new Builder());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFinishBuilder(long nativeBuilder) {
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFreeBuilder(long nativeBuilder) {
-        sBuilderManager.removeJavaReferenceFor(nativeBuilder);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLocale(long nativeBuilder, String locale) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        builder.mLocale = locale;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetText(long nativeBuilder, char[] text, int length) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        builder.mText = text;
-        builder.mWidths = new float[length];
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static float nAddStyleRun(long nativeBuilder, long nativePaint, long nativeTypeface,
-            int start, int end, boolean isRtl) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-
-        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
-        return measureText(nativePaint, builder.mText, start, end - start, builder.mWidths, bidiFlags);
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddMeasuredRun(long nativeBuilder, int start, int end, float[] widths) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        System.arraycopy(widths, start, builder.mWidths, start, end - start);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddReplacementRun(long nativeBuilder, int start, int end, float width) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        builder.mWidths[start] = width;
-        Arrays.fill(builder.mWidths, start + 1, end, 0.0f);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetWidths(long nativeBuilder, float[] floatsArray) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        System.arraycopy(builder.mWidths, 0, floatsArray, 0, builder.mWidths.length);
-    }
-
     private static float measureText(long nativePaint, char []text, int index, int count,
             float[] widths, int bidiFlags) {
         Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
@@ -174,12 +213,32 @@
         return bounds.right - bounds.left;
     }
 
+    // TODO: Rename to LineBreakerRef and move everything other than LineBreaker to LineBreaker.
     /**
      * Java representation of the native Builder class.
      */
-    static class Builder {
+    private static class Builder {
         String mLocale;
         char[] mText;
         float[] mWidths;
+        LineBreaker mLineBreaker;
+        long mNativeHyphenator;
+    }
+
+    private enum BreakStrategy {
+        GREEDY, HIGH_QUALITY, BALANCED;
+
+        static BreakStrategy getStrategy(int strategy) {
+            switch (strategy) {
+                case 0:
+                    return GREEDY;
+                case 1:
+                    return HIGH_QUALITY;
+                case 2:
+                    return BALANCED;
+                default:
+                    throw new AssertionError("Unknown break strategy: " + strategy);
+            }
+        }
     }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index c6d60f8..af67a43 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -16,9 +16,6 @@
 
 package com.android.layoutlib.bridge;
 
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
 import com.android.annotations.NonNull;
 import com.android.ide.common.rendering.api.Capability;
 import com.android.ide.common.rendering.api.DrawableParams;
@@ -36,13 +33,12 @@
 import com.android.tools.layoutlib.create.MethodAdapter;
 import com.android.tools.layoutlib.create.OverrideMethod;
 import com.android.util.Pair;
-import com.ibm.icu.util.ULocale;
-import libcore.io.MemoryMappedFile_Delegate;
 
 import android.content.res.BridgeAssetManager;
 import android.graphics.Bitmap;
 import android.graphics.FontFamily_Delegate;
 import android.graphics.Typeface_Delegate;
+import android.icu.util.ULocale;
 import android.os.Looper;
 import android.os.Looper_Accessor;
 import android.view.View;
@@ -60,6 +56,11 @@
 import java.util.Map;
 import java.util.concurrent.locks.ReentrantLock;
 
+import libcore.io.MemoryMappedFile_Delegate;
+
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+
 /**
  * Main entry point of the LayoutLib Bridge.
  * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
index ea5f1ea..e589d9e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
@@ -16,9 +16,9 @@
 
 package com.android.layoutlib.bridge.android;
 
-import java.util.Locale;
+import android.icu.util.ULocale;
 
-import com.ibm.icu.util.ULocale;
+import java.util.Locale;
 
 /**
  * This class provides an alternate implementation for {@code java.util.Locale#toLanguageTag}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
index 261cc98..dbee9ea 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
@@ -16,6 +16,7 @@
 
 package com.android.layoutlib.bridge.impl;
 
+import com.android.annotations.Nullable;
 import com.android.layoutlib.bridge.util.Debug;
 import com.android.layoutlib.bridge.util.SparseWeakArray;
 
@@ -48,7 +49,7 @@
  * int -> Delegate class link.
  *
  * Native methods usually always have the int as parameters. The first thing the delegate method
- * will do is call {@link #getDelegate(int)} to get the Java object matching the int.
+ * will do is call {@link #getDelegate(long)} to get the Java object matching the int.
  *
  * Typical native init methods are returning a new int back to the Java class, so
  * {@link #addNewDelegate(Object)} does the same.
@@ -57,7 +58,7 @@
  * the Java object needs to count as a reference (even though it only holds an int), we use the
  * following mechanism:
  *
- * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(int)} adds and removes
+ * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(long)} adds and removes
  *   the delegate to/from a list. This list hold the reference and prevents the GC from reclaiming
  *   the delegate.
  *
@@ -70,12 +71,13 @@
  * @param <T> the delegate class to manage
  */
 public final class DelegateManager<T> {
+    @SuppressWarnings("FieldCanBeLocal")
     private final Class<T> mClass;
     private final SparseWeakArray<T> mDelegates = new SparseWeakArray<T>();
     /** list used to store delegates when their main object holds a reference to them.
      * This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed
      * @see #addNewDelegate(Object)
-     * @see #removeJavaReferenceFor(int)
+     * @see #removeJavaReferenceFor(long)
      */
     private final List<T> mJavaReferences = new ArrayList<T>();
     private int mDelegateCounter = 0;
@@ -94,6 +96,7 @@
      * @param native_object the native int.
      * @return the delegate or null if not found.
      */
+    @Nullable
     public T getDelegate(long native_object) {
         if (native_object > 0) {
             T delegate =  mDelegates.get(native_object);
diff --git a/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java
deleted file mode 100644
index d94c205..0000000
--- a/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.icu;
-
-import java.text.FieldPosition;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.ibm.icu.text.DateIntervalFormat;
-import com.ibm.icu.util.DateInterval;
-import com.ibm.icu.util.TimeZone;
-import com.ibm.icu.util.ULocale;
-
-public class DateIntervalFormat_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<DateIntervalFormat_Delegate> sManager =
-            new DelegateManager<DateIntervalFormat_Delegate>(DateIntervalFormat_Delegate.class);
-
-    // ---- delegate data ----
-    private DateIntervalFormat mFormat;
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/static String formatDateInterval(long address, long fromDate, long toDate) {
-        DateIntervalFormat_Delegate delegate = sManager.getDelegate((int)address);
-        if (delegate == null) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Unable for find native DateIntervalFormat", null);
-            return null;
-        }
-        DateInterval interval = new DateInterval(fromDate, toDate);
-        StringBuffer sb = new StringBuffer();
-        FieldPosition pos = new FieldPosition(0);
-        delegate.mFormat.format(interval, sb, pos);
-        return sb.toString();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createDateIntervalFormat(String skeleton, String localeName,
-            String tzName) {
-        TimeZone prevDefaultTz = TimeZone.getDefault();
-        TimeZone.setDefault(TimeZone.getTimeZone(tzName));
-        DateIntervalFormat_Delegate newDelegate = new DateIntervalFormat_Delegate();
-        newDelegate.mFormat =
-                DateIntervalFormat.getInstance(skeleton, new ULocale(localeName));
-        TimeZone.setDefault(prevDefaultTz);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void destroyDateIntervalFormat(long address) {
-        sManager.removeJavaReferenceFor((int)address);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
index b8b5fed..a6cbe56 100644
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
@@ -17,9 +17,10 @@
 package libcore.icu;
 
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.ibm.icu.text.DateTimePatternGenerator;
-import com.ibm.icu.util.Currency;
-import com.ibm.icu.util.ULocale;
+
+import android.icu.text.DateTimePatternGenerator;
+import android.icu.util.Currency;
+import android.icu.util.ULocale;
 
 import java.util.Locale;
 
@@ -252,4 +253,9 @@
     /*package*/ static String getDefaultLocale() {
         return ICU.getDefaultLocale();
     }
+
+    @LayoutlibDelegate
+    /*package*/ static String getTZDataVersion() {
+        return ICU.getTZDataVersion();
+    }
 }
diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk
index 11390c3..5eef24a 100644
--- a/tools/layoutlib/bridge/tests/Android.mk
+++ b/tools/layoutlib/bridge/tests/Android.mk
@@ -26,7 +26,6 @@
 
 LOCAL_JAVA_LIBRARIES := layoutlib \
 			kxml2-2.3.0 \
-			icu4j \
 			layoutlib_api-prebuilt \
 			tools-common-prebuilt \
 			sdk-common \
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
index c9b76be..cb72550 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
index 8b362ec..d8937f4 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
@@ -192,12 +192,12 @@
         StringBuilder sb = new StringBuilder(method.getName() + "(");
         for (int j = 0; j < parameters.length; j++) {
             Class<?> theClass = parameters[j];
-            sb.append(theClass.getName());
             int dimensions = 0;
             while (theClass.isArray()) {
                 dimensions++;
                 theClass = theClass.getComponentType();
             }
+            sb.append(theClass.getName());
             for (int i = 0; i < dimensions; i++) {
                 sb.append("[]");
             }
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
index d87c99f..509f5eb 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
@@ -40,7 +40,7 @@
 public class BridgeXmlBlockParserTest {
 
     @BeforeClass
-    public void setUp() {
+    public static void setUp() {
         ParserFactory.setLayoutlibCallback(new LayoutlibTestCallback());
     }
 
@@ -128,7 +128,7 @@
     }
 
     @AfterClass
-    public void tearDown() {
+    public static void tearDown() {
         ParserFactory.setLayoutlibCallback(null);
     }
 
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index bd467ef..91be0bd 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -17,6 +17,7 @@
 package com.android.layoutlib.bridge.intensive;
 
 import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.RenderSession;
 import com.android.ide.common.rendering.api.Result;
@@ -364,13 +365,14 @@
                 }
 
                 @Override
-                public void fidelityWarning(String tag, String message, Throwable throwable,
-                        Object data) {
+                public void fidelityWarning(@Nullable String tag, String message,
+                        Throwable throwable, Object data) {
+
                     System.out.println("FidelityWarning " + tag + ": " + message);
                     if (throwable != null) {
                         throwable.printStackTrace();
                     }
-                    failWithMsg(message);
+                    failWithMsg(message == null ? "" : message);
                 }
 
                 @Override
@@ -396,11 +398,11 @@
         if (sLogger == null) {
             sLogger = new ILogger() {
                 @Override
-                public void error(Throwable t, String msgFormat, Object... args) {
+                public void error(Throwable t, @Nullable String msgFormat, Object... args) {
                     if (t != null) {
                         t.printStackTrace();
                     }
-                    failWithMsg(msgFormat, args);
+                    failWithMsg(msgFormat == null ? "" : msgFormat, args);
                 }
 
                 @Override
diff --git a/tools/layoutlib/create/create.iml b/tools/layoutlib/create/create.iml
index b7e8eb3..9b18e73 100644
--- a/tools/layoutlib/create/create.iml
+++ b/tools/layoutlib/create/create.iml
@@ -11,8 +11,17 @@
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="asm-4.0" level="project" />
+    <orderEntry type="module-library">
+      <library name="asm-4.0">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/asm-4.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/src.zip!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
     <orderEntry type="library" scope="TEST" name="JUnit4" level="application" />
   </component>
-</module>
-
+</module>
\ No newline at end of file
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index f5e8292..245cd61 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -156,6 +156,7 @@
         "android.os.HandlerThread#run",
         "android.preference.Preference#getView",
         "android.text.format.DateFormat#is24HourFormat",
+        "android.text.Hyphenator#getSystemHyphenatorLocation",
         "android.util.Xml#newPullParser",
         "android.view.Choreographer#getRefreshRate",
         "android.view.Display#updateDisplayInfoLocked",
@@ -231,7 +232,6 @@
         "android.text.AndroidBidi",
         "android.text.StaticLayout",
         "android.view.Display",
-        "libcore.icu.DateIntervalFormat",
         "libcore.icu.ICU",
     };
 
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index fa570c8..7ca050b 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -118,6 +118,7 @@
                         "android.app.DatePickerDialog",     // b.android.com/28318
                         "android.app.TimePickerDialog",     // b.android.com/61515
                         "com.android.internal.view.menu.ActionMenu",
+                        "android.icu.**",                   // needed by LayoutLib
                     },
                     excludeClasses,
                     new String[] {